Пример #1
0
/*
================
G_InitSessionData

Called on a first-time connect
================
*/
void G_InitSessionData( gclient_t *client, char *userinfo ) {
	clientSession_t	*sess;
	const char		*value;

	sess = &client->sess;

	// initial team determination
	if ( g_gametype.integer >= GT_TEAM ) {
		if ( g_teamAutoJoin.integer && !(g_entities[ client - level.clients ].r.svFlags & SVF_BOT) ) {
			sess->sessionTeam = PickTeam( -1 );
			BroadcastTeamChange( client, -1 );
		} else {
			// always spawn as spectator in team games
			sess->sessionTeam = TEAM_SPECTATOR;	
		}
	} else {
		value = Info_ValueForKey( userinfo, "team" );
		if ( value[0] == 's' ) {
			// a willing spectator, not a waiting-in-line
			sess->sessionTeam = TEAM_SPECTATOR;
		} else {
			switch ( g_gametype.integer ) {
			default:
			case GT_FFA:
			case GT_SINGLE_PLAYER:
				if ( g_maxGameClients.integer > 0 && 
					level.numNonSpectatorClients >= g_maxGameClients.integer ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			case GT_TOURNAMENT:
				// if the game is full, go into a waiting mode
				if ( level.numNonSpectatorClients >= 2 ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			}
		}
	}

	sess->spectatorState = SPECTATOR_FREE;
	AddTournamentQueue(client);

	if (crandom() > 0)
		client->sess.weapon = WP_RAILGUN;
	else
		client->sess.weapon = WP_ROCKET_LAUNCHER;

	G_WriteClientSessionData( client );
}
Пример #2
0
/*
================
G_InitSessionData

Called on a first-time connect
================
*/
void G_InitSessionData( gclient_t *client, char *userinfo ) {
	clientSession_t	*sess;
	const char		*value;

	sess = &client->sess;

	// initial team determination
	if ( g_gametype.integer >= GT_TEAM ) {
		if ( g_teamAutoJoin.integer ) {
			sess->sessionTeam = PickTeam( -1 );
			BroadcastTeamChange( client, -1 );
		} else {
			// always spawn as spectator in team games
			sess->sessionTeam = TEAM_SPECTATOR;	
		}
	} else {
		value = Info_ValueForKey( userinfo, "team" );
		if ( value[0] == 's' ) {
			// a willing spectator, not a waiting-in-line
			sess->sessionTeam = TEAM_SPECTATOR;
		} else {
			switch ( g_gametype.integer ) {
			default:
			case GT_FFA:
			case GT_SINGLE_PLAYER:
				if ( g_maxGameClients.integer > 0 && 
					level.numNonSpectatorClients >= g_maxGameClients.integer ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			case GT_TOURNAMENT:
				// if the game is full, go into a waiting mode
				if ( level.numNonSpectatorClients >= 2 ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			}
		}
	}

	sess->spectatorState = SPECTATOR_FREE;
	sess->spectatorTime = level.time;

	G_WriteClientSessionData( client );
}
Пример #3
0
/*
================
G_InitSessionData

Called on a first-time connect
================
*/
void G_InitSessionData( gclient_t *client, char *userinfo ) 
{
	clientSession_t	*sess;
	const char		*value;

	sess = &client->sess;

	// initial team determination
	if ( level.gametypeData->teams ) 
	{
		if ( g_teamAutoJoin.integer ) 
		{
			sess->team = PickTeam( -1 );
			BroadcastTeamChange( client, -1 );
		} 
		else 
		{
			// always spawn as spectator in team games
			sess->team = TEAM_SPECTATOR;	
		}
	} 
	else 
	{
		value = Info_ValueForKey( userinfo, "team" );
		if ( value[0] == 's' ) 
		{
			// a willing spectator, not a waiting-in-line
			sess->team = TEAM_SPECTATOR;
		} 
		else 
		{
			if ( g_maxGameClients.integer > 0 && level.numNonSpectatorClients >= g_maxGameClients.integer ) 
			{
				sess->team = TEAM_SPECTATOR;
			} 
			else 
			{
				sess->team = TEAM_FREE;
			}
		}
	}

	sess->spectatorState = SPECTATOR_FREE;
	sess->spectatorTime = level.time;

	G_WriteClientSessionData( client );
}
Пример #4
0
/** LQ3A: Changed return from void to qboolean.
	This function initilises the session data and assigns a team to the client,
	if we cannot assign a team it returns qfalse and the client should be dropped from the server.
	@see ClientConnect(). */
qboolean G_InitSessionData( gclient_t *client, char *userinfo ) {
	clientSession_t	*sess;
	/* LQ3A */
//	const char	*value;
	qboolean	bCanClientSpectate;
	int			iVacantPlayerSlots;

	/* LQ3A */
	UNREFERENCED_PARAMETER(userinfo);

	sess = &client->sess;

	/* LQ3A */
	bCanClientSpectate	= LQ3A_CanClientSpectate(LQ3A_ClientToEntity(client));
	iVacantPlayerSlots	= LQ3A_GetVacantPlayerSlots();

	// initial team determination
	if (g_gametype.integer >= GT_TEAM)
	{
		/* LQ3A: Added support for g_maxGameClients in team games.
			Force auto join when the client cannot spectate. */
		if (iVacantPlayerSlots && (g_teamAutoJoin.integer || !bCanClientSpectate))
		{
			sess->sessionTeam = PickTeam( -1 );
			BroadcastTeamChange( client, -1 );
		}
		else if (bCanClientSpectate)
		{
			sess->sessionTeam = TEAM_SPECTATOR;	
		}
		else
		{
			/* No vacant player slots and we cannot spectate. */
			return qfalse;
		}

	} else {

		/* LQ3A: Place clients into spectator mode by default where possible. */
		if (bCanClientSpectate)
		{
			sess->sessionTeam = TEAM_SPECTATOR;
		}
		/* If we cannot spectate, place the client in the game when there are vacant slots. */
		else if (iVacantPlayerSlots)
		{
			sess->sessionTeam = TEAM_FREE;
		}
		else
		{
			/* No vacant player slots and we cannot spectate. */
			return qfalse;
		}
	}

	sess->spectatorState = SPECTATOR_FREE;
	sess->spectatorTime = level.time;

	/* LQ3A */
	if (sess->sessionTeam == TEAM_SPECTATOR)
	{
		LQ3A_CompleteClientMoveToSpectatorTeam(LQ3A_ClientToEntity(client));
	}

	G_WriteClientSessionData( client );

	/* LQ3A */
	return qtrue;
}
Пример #5
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
	int				value;
	int				connectionNum;
	int				clientNum;
	int				t;
	char			*botinfo;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
	char			*headmodel;
	char			userinfo[MAX_INFO_STRING];
	qboolean		modelSet;

	// have the server allocate a client slot
	value = trap_BotAllocateClient();
	if ( value == -1 ) {
		G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" );
		G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
		return;
	}

	// get connection and client numbers
	connectionNum = value & 0xFFFF;
	clientNum = value >> 16;

	// set default team
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM ) {
			if( PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "free";
		}
	}

	// get the botinfo from bots.txt
	if (Q_stricmp(name, "random") == 0) {
		if (Q_stricmp(team, "blue") == 0)
			t = TEAM_BLUE;
		else if (Q_stricmp(team, "red") == 0)
			t = TEAM_RED;
		else
			t = TEAM_FREE;

		// get info of a randomly selected bot
		botinfo = G_GetBotInfoByNumber( G_SelectRandomBotForAdd( t ) );
	}
	else {
		// get info of the bot
		botinfo = G_GetBotInfoByName( name );
	}

	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		trap_BotFreeClient(clientNum);
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%.2f", skill) );
	Info_SetValueForKey( userinfo, "teampref", team );

	if ( skill >= 1 && skill < 2 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	}
	else if ( skill >= 2 && skill < 3 ) {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	}
	else if ( skill >= 3 && skill < 4 ) {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	}

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	modelSet = ( *model );
	if ( !modelSet ) {
		model = DEFAULT_MODEL;
	}
	Info_SetValueForKey( userinfo, key, model );
	key = "team_model";
	Info_SetValueForKey( userinfo, key, model );

	key = "headmodel";
	headmodel = Info_ValueForKey( botinfo, key );
	if ( !*headmodel ) {
		if (!modelSet) {
			headmodel = DEFAULT_HEAD;
		} else {
			headmodel = model;
		}
	}
	Info_SetValueForKey( userinfo, key, headmodel );
	key = "team_headmodel";
	Info_SetValueForKey( userinfo, key, headmodel );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = va("%d", DEFAULT_CLIENT_COLOR1);
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = va("%d", DEFAULT_CLIENT_COLOR2);
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s ) {
		trap_Print( S_COLOR_RED "Error: bot has no aifile specified\n" );
		trap_BotFreeClient(clientNum);
		return;
	}
	Info_SetValueForKey( userinfo, "characterfile", s );

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue, connectionNum, 0 ) ) {
		return;
	}

	if( delay == 0 ) {
		ClientBegin( clientNum );
		return;
	}

	AddBotToSpawnQueue( clientNum, delay );
}
Пример #6
0
/*
===========
ClientUserInfoChanged

Called from ClientConnect when the player first connects and
directly by the server system when the player updates a userinfo variable.

The game can override any of the settings and call trap_SetUserinfo
if desired.
============
*/
void ClientUserinfoChanged( int clientNum ) {
	gentity_t *ent;
	int		teamTask, teamLeader, team, health;
	char	*s;
	char	model[MAX_QPATH];
	char	headModel[MAX_QPATH];
	char	oldname[MAX_STRING_CHARS];
	gclient_t	*client;
	char	c1[MAX_INFO_STRING];
	char	c2[MAX_INFO_STRING];
	char	redTeam[MAX_INFO_STRING];
	char	blueTeam[MAX_INFO_STRING];
	char	userinfo[MAX_INFO_STRING];

	ent = g_entities + clientNum;
	client = ent->client;

	trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );

	// check for malformed or illegal info strings
	if ( !Info_Validate(userinfo) ) {
		strcpy (userinfo, "\\name\\badinfo");
	}

	// check for local client
	s = Info_ValueForKey( userinfo, "ip" );
	if ( !strcmp( s, "localhost" ) ) {
		client->pers.localClient = qtrue;
	}

	// check the item prediction
	s = Info_ValueForKey( userinfo, "cg_predictItems" );
	if ( !atoi( s ) ) {
		client->pers.predictItemPickup = qfalse;
	} else {
		client->pers.predictItemPickup = qtrue;
	}

	// set name
	Q_strncpyz ( oldname, client->pers.netname, sizeof( oldname ) );
	s = Info_ValueForKey (userinfo, "name");
	ClientCleanName( s, client->pers.netname, sizeof(client->pers.netname) );

	if ( client->sess.sessionTeam == TEAM_SPECTATOR ) {
		if ( client->sess.spectatorState == SPECTATOR_SCOREBOARD ) {
			Q_strncpyz( client->pers.netname, "scoreboard", sizeof(client->pers.netname) );
		}
	}

	if ( client->pers.connected == CON_CONNECTED ) {
		if ( strcmp( oldname, client->pers.netname ) ) {
			trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " renamed to %s\n\"", oldname, 
				client->pers.netname) );
		}
	}

	// set max health
#ifdef MISSIONPACK
	if (client->ps.powerups[PW_GUARD]) {
		client->pers.maxHealth = 200;
	} else {
		health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
		client->pers.maxHealth = health;
		if ( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) {
			client->pers.maxHealth = 100;
		}
	}
#else
	health = atoi( Info_ValueForKey( userinfo, "handicap" ) );
	client->pers.maxHealth = health;
	if ( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) {
		client->pers.maxHealth = 100;
	}
#endif
	client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;

	// set model
	if( g_gametype.integer >= GT_TEAM ) {
		Q_strncpyz( model, Info_ValueForKey (userinfo, "team_model"), sizeof( model ) );
		Q_strncpyz( headModel, Info_ValueForKey (userinfo, "team_headmodel"), sizeof( headModel ) );
	} else {
		Q_strncpyz( model, Info_ValueForKey (userinfo, "model"), sizeof( model ) );
		Q_strncpyz( headModel, Info_ValueForKey (userinfo, "headmodel"), sizeof( headModel ) );
	}

	// bots set their team a few frames later
	if (g_gametype.integer >= GT_TEAM && g_entities[clientNum].r.svFlags & SVF_BOT) {
		s = Info_ValueForKey( userinfo, "team" );
		if ( !Q_stricmp( s, "red" ) || !Q_stricmp( s, "r" ) ) {
			team = TEAM_RED;
		} else if ( !Q_stricmp( s, "blue" ) || !Q_stricmp( s, "b" ) ) {
			team = TEAM_BLUE;
		} else {
			// pick the team with the least number of players
			team = PickTeam( clientNum );
		}
	}
	else {
		team = client->sess.sessionTeam;
	}

/*	NOTE: all client side now

	// team
	switch( team ) {
	case TEAM_RED:
		ForceClientSkin(client, model, "red");
//		ForceClientSkin(client, headModel, "red");
		break;
	case TEAM_BLUE:
		ForceClientSkin(client, model, "blue");
//		ForceClientSkin(client, headModel, "blue");
		break;
	}
	// don't ever use a default skin in teamplay, it would just waste memory
	// however bots will always join a team but they spawn in as spectator
	if ( g_gametype.integer >= GT_TEAM && team == TEAM_SPECTATOR) {
		ForceClientSkin(client, model, "red");
//		ForceClientSkin(client, headModel, "red");
	}
*/

#ifdef MISSIONPACK
	if (g_gametype.integer >= GT_TEAM) {
		client->pers.teamInfo = qtrue;
	} else {
		s = Info_ValueForKey( userinfo, "teamoverlay" );
		if ( ! *s || atoi( s ) != 0 ) {
			client->pers.teamInfo = qtrue;
		} else {
			client->pers.teamInfo = qfalse;
		}
	}
#else
	// teamInfo
	s = Info_ValueForKey( userinfo, "teamoverlay" );
	if ( ! *s || atoi( s ) != 0 ) {
		client->pers.teamInfo = qtrue;
	} else {
		client->pers.teamInfo = qfalse;
	}
#endif
	/*
	s = Info_ValueForKey( userinfo, "cg_pmove_fixed" );
	if ( !*s || atoi( s ) == 0 ) {
		client->pers.pmoveFixed = qfalse;
	}
	else {
		client->pers.pmoveFixed = qtrue;
	}
	*/

	// team task (0 = none, 1 = offence, 2 = defence)
	teamTask = atoi(Info_ValueForKey(userinfo, "teamtask"));
	// team Leader (1 = leader, 0 is normal player)
	teamLeader = client->sess.teamLeader;

	// colors
	strcpy(c1, Info_ValueForKey( userinfo, "color1" ));
	strcpy(c2, Info_ValueForKey( userinfo, "color2" ));

	strcpy(redTeam, Info_ValueForKey( userinfo, "g_redteam" ));
	strcpy(blueTeam, Info_ValueForKey( userinfo, "g_blueteam" ));

	// send over a subset of the userinfo keys so other clients can
	// print scoreboards, display models, and play custom sounds
	if ( ent->r.svFlags & SVF_BOT ) {
		s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d",
			client->pers.netname, team, model, headModel, c1, c2, 
			client->pers.maxHealth, client->sess.wins, client->sess.losses,
			Info_ValueForKey( userinfo, "skill" ), teamTask, teamLeader );
	} else {
		s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\g_redteam\\%s\\g_blueteam\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d",
			client->pers.netname, client->sess.sessionTeam, model, headModel, redTeam, blueTeam, c1, c2, 
			client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, teamLeader);
	}

	trap_SetConfigstring( CS_PLAYERS+clientNum, s );

	// this is not the userinfo, more like the configstring actually
	G_LogPrintf( "ClientUserinfoChanged: %i %s\n", clientNum, s );
}
Пример #7
0
/* LQ3A: Added bBroadcast parameter to allow the calling function to suppress the change. */
void SetTeam( gentity_t *ent, char *s, qboolean bBroadcast) {
	/* LQ3A */
	team_t				team, oldTeam;

	gclient_t			*client;
	int					clientNum;
	spectatorState_t	specState;
	int					specClient;
	int					teamLeader;

	//
	// see what change is requested
	//
	client = ent->client;

	clientNum = client - level.clients;
	specClient = 0;
	specState = SPECTATOR_NOT;
	if ( !Q_stricmp( s, "scoreboard" ) || !Q_stricmp( s, "score" )  ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_SCOREBOARD;
	} else if ( !Q_stricmp( s, "follow1" ) ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_FOLLOW;
		specClient = -1;
	} else if ( !Q_stricmp( s, "follow2" ) ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_FOLLOW;
		specClient = -2;
	} else if ( !Q_stricmp( s, "spectator" ) || !Q_stricmp( s, "s" ) ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_FREE;
	} else if ( g_gametype.integer >= GT_TEAM ) {
		// if running a team game, assign player to one of the teams
		specState = SPECTATOR_NOT;
		if ( !Q_stricmp( s, "red" ) || !Q_stricmp( s, "r" ) ) {
			team = TEAM_RED;
		} else if ( !Q_stricmp( s, "blue" ) || !Q_stricmp( s, "b" ) ) {
			team = TEAM_BLUE;
		} else {
			// pick the team with the least number of players
			team = PickTeam( clientNum );
		}

		if ( g_teamForceBalance.integer  ) {
			int		counts[TEAM_NUM_TEAMS];

			counts[TEAM_BLUE] = TeamCount( ent->client->ps.clientNum, TEAM_BLUE );
			counts[TEAM_RED] = TeamCount( ent->client->ps.clientNum, TEAM_RED );

			// We allow a spread of two
			if ( team == TEAM_RED && counts[TEAM_RED] - counts[TEAM_BLUE] > 1 ) {
				trap_SendServerCommand( ent->client->ps.clientNum, 
					"cp \"Red team has too many players.\n\"" );
				return; // ignore the request
			}
			if ( team == TEAM_BLUE && counts[TEAM_BLUE] - counts[TEAM_RED] > 1 ) {
				trap_SendServerCommand( ent->client->ps.clientNum, 
					"cp \"Blue team has too many players.\n\"" );
				return; // ignore the request
			}

			// It's ok, the team we are switching to has less or same number of players
		}

	} else {
		// force them to spectators if there aren't any spots free
		/* LQ3A */
		team = ((client->sess.sessionTeam == TEAM_FREE) ||
			((client->sess.sessionTeam != TEAM_FREE) && LQ3A_GetVacantPlayerSlots())) ? TEAM_FREE : TEAM_SPECTATOR;
	}

	// override decision if limiting the players
	if ( (g_gametype.integer == GT_TOURNAMENT)
		&& level.numNonSpectatorClients >= 2 ) {
		team = TEAM_SPECTATOR;
	} else if ( g_maxGameClients.integer > 0 && 
		level.numNonSpectatorClients > g_maxGameClients.integer ) {
		team = TEAM_SPECTATOR;
	}

	//
	// decide if we will allow the change
	//
	oldTeam = client->sess.sessionTeam;
	/* LQ3A */
	if ( team == oldTeam /*&& team != TEAM_SPECTATOR*/ ) {
		return;
	}

	/* LQ3A: Ensure we're allowed to spectate. */
	if ((team == TEAM_SPECTATOR) && !LQ3A_CanClientSpectate(ent))
	{
		return;
	}

	//
	// execute the team change
	//

	// if the player was dead leave the body
	if ( client->ps.stats[STAT_HEALTH] <= 0 ) {
		CopyToBodyQue(ent);
	}

	// he starts at 'base'
	client->pers.teamState.state = TEAM_BEGIN;

	/* LQ3A*/
	if (oldTeam == TEAM_SPECTATOR)
	{
		ent->r.svFlags &= ~SVF_NOCLIENT;
		client->pers.enterTime += (level.time - client->sess.spectatorTime);

		/* Restore the players score. */
		client->ps.persistant[PERS_SCORE] = client->pers.iScore;
	}
	else if (ent->client->ps.stats[STAT_HEALTH] > 0)
	{
		// Kill him (makes sure he loses flags, etc)
		ent->flags &= ~FL_GODMODE;

		/* LQ3A: Kill the player if they have too little health. */
		if ((g_spectatorFreePass.integer > 0) && (ent->client->ps.stats[STAT_HEALTH] < g_spectatorFreePass.integer))
		{
			ent->client->ps.stats[STAT_HEALTH] = ent->health = 0;
			player_die (ent, ent, ent, 100000, MOD_SUICIDE);
		}
		else
		{
			/* LQ3A: Drop items and return flags when we're allowed
				to become a spectator without commiting suicide. */

			// if client is in a nodrop area, don't drop anything (but return CTF flags!)
			if (!(trap_PointContents(ent->r.currentOrigin, -1) & CONTENTS_NODROP))
			{
				TossClientItems(ent);
			}
			else 
			{
				if (ent->client->ps.powerups[PW_NEUTRALFLAG])
				{
					Team_ReturnFlag(TEAM_FREE);
				}
				else if (ent->client->ps.powerups[PW_REDFLAG])
				{
					Team_ReturnFlag(TEAM_RED);
				}
				else if (ent->client->ps.powerups[PW_BLUEFLAG])
				{
					Team_ReturnFlag(TEAM_BLUE);
				}
			}
#ifdef MISSIONPACK
			TossClientPersistantPowerups(ent);

			if(g_gametype.integer == GT_HARVESTER)
			{
				TossClientCubes(ent);
			}
#endif
		}

	}
	// they go to the end of the line for tournements
	if ( team == TEAM_SPECTATOR ) {

		/* LQ3A */
		LQ3A_CompleteClientMoveToSpectatorTeam(ent);
	}

	client->sess.sessionTeam = team;
	client->sess.spectatorState = specState;
	client->sess.spectatorClient = specClient;

	client->sess.teamLeader = qfalse;
	if ( team == TEAM_RED || team == TEAM_BLUE ) {
		teamLeader = TeamLeader( team );
		// if there is no team leader or the team leader is a bot and this client is not a bot
		if ( teamLeader == -1 || ( !(g_entities[clientNum].r.svFlags & SVF_BOT) && (g_entities[teamLeader].r.svFlags & SVF_BOT) ) ) {
			SetLeader( team, clientNum );
		}
	}
	// make sure there is a team leader on the team the player came from
	if ( oldTeam == TEAM_RED || oldTeam == TEAM_BLUE ) {
		CheckTeamLeader( oldTeam );
	}

	/* LQ3A: Broadcast the change when instructed to do so. */
	if (bBroadcast)
	{
		BroadcastTeamChange(client, oldTeam);
	}

	// get and distribute relevent paramters
	ClientUserinfoChanged( clientNum );

	/* LQ3A */
	if (team != TEAM_SPECTATOR)
	{
		/* Spawn the client into the game. */
		ClientBegin(clientNum);
	}
	else
	{
		/* Update the cached scores. */
		CalculateRanks();
	}
}
Пример #8
0
//[TABBot]
//added bot type varible
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname, int bottype) {
//static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
//[/TABBot]
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
//	char			*headmodel;
	char			userinfo[MAX_INFO_STRING];
	int				preTeam = 0;
	//[DuelGuns][EnhancedImpliment]
	/*
	char			*firearm; // ** change gun model	
	qboolean		bot_dualguns = qfalse;
	int				gunoption=0;
	*/
	//[/DuelGuns][EnhancedImpliment]

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );

	if ( skill >= 1 && skill < 2 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	}
	else if ( skill >= 2 && skill < 3 ) {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	}
	else if ( skill >= 3 && skill < 4 ) {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	}

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "kyle/default";
	}
	Info_SetValueForKey( userinfo, key, model );

/*	key = "headmodel";
	headmodel = Info_ValueForKey( botinfo, key );
	if ( !*headmodel ) {
		headmodel = model;
	}
	Info_SetValueForKey( userinfo, key, headmodel );
	key = "team_headmodel";
	Info_SetValueForKey( userinfo, key, headmodel );
*/
	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "saber1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "single_1";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "saber2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "none";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "personality");
	if (!*s )
	{
		Info_SetValueForKey( userinfo, "personality", "botfiles/default.jkb" );
	}
	else
	{
		Info_SetValueForKey( userinfo, "personality", s );
	}

	//[DuelGuns][EnhancedImpliment]
	/*
//	if(1)//f_dualguns.integer)
//	{
		key = "dualgun";
		s = Info_ValueForKey(botinfo, key);
		if (*s)
		{
			gunoption = atoi(s);
		}
		if(gunoption>0)
			bot_dualguns = qtrue;
//	}

	firearm = Info_ValueForKey( botinfo, "firearm");
	if (!*firearm)
	{
		Info_SetValueForKey( userinfo, "firearm", botname );
	}
	else
	{
		Info_SetValueForKey( userinfo, "firearm", firearm);
	}
	*/
	//[/DuelGuns][EnhancedImpliment]

	//[RGBSabers]
	key = "rgb_saber1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "255,0,0";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "rgb_saber2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "0,255,255";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "rgb_script1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "none";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "rgb_script2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "none";
	}
	Info_SetValueForKey( userinfo, key, s );
	//[/RGBSabers]

	//[ClientPlugInDetect]
	//set it so that the bots are assumed to have the OJP client plugin
	//this should be CURRENT_OJPENHANCED_CLIENTVERSION
	Info_SetValueForKey( userinfo, "ojp_clientplugin", CURRENT_OJPENHANCED_CLIENTVERSION );
	//[/ClientPlugInDetect]

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
//		G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
//		G_Printf( S_COLOR_RED "Start server with more 'open' slots.\n" );
		trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "UNABLE_TO_ADD_BOT")));
		return;
	}

	//[DuelGuns][EnhancedImpliment]
	/*
	if(bot_dualguns)
	{
		g_entities[clientNum].client->ps.dualguns = 1;		
	}
	*/
	//[/DuelGuns][EnhancedImpliment]

	// initialize the bot settings
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM ) {
			//[AdminSys]
			if( PickTeam(clientNum, qtrue) == TEAM_RED) {
			//if( PickTeam(clientNum) == TEAM_RED) {
			//[/AdminSys]
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "red";
		}
	}
//	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
	Info_SetValueForKey( userinfo, "team", team );
	//[TABBot]
	Info_SetValueForKey( userinfo, "bottype", va( "%i", bottype) );
	//[/TABBot]

	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	bot->inuse = qtrue;

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	//[NewGameTypes][EnhancedImpliment]
	//if (g_gametype.integer >= GT_TEAM && g_gametype.integer != GT_RPG)
	if (g_gametype.integer >= GT_TEAM)
	//[/NewGameTypes][EnhancedImpliment]
	{
		if (team && Q_stricmp(team, "red") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_RED;
		}
		else if (team && Q_stricmp(team, "blue") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_BLUE;
		}
		else
		{
			//[AdminSys]
			bot->client->sess.sessionTeam = PickTeam( -1, qtrue );
			//bot->client->sess.sessionTeam = PickTeam( -1 );
			//[/AdminSys]
		}
	}

	if (g_gametype.integer == GT_SIEGE)
	{
		bot->client->sess.siegeDesiredTeam = bot->client->sess.sessionTeam;
		bot->client->sess.sessionTeam = TEAM_SPECTATOR;
	}

	preTeam = bot->client->sess.sessionTeam;

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if (bot->client->sess.sessionTeam != preTeam)
	{
		trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING);

		if (bot->client->sess.sessionTeam == TEAM_SPECTATOR)
		{
			bot->client->sess.sessionTeam = preTeam;
		}

		if (bot->client->sess.sessionTeam == TEAM_RED)
		{
			team = "Red";
		}
		else
		{
			if (g_gametype.integer == GT_SIEGE)
			{
				if (bot->client->sess.sessionTeam == TEAM_BLUE)
				{
					team = "Blue";
				}
				else
				{
					team = "s";
				}
			}
			else
			{
				team = "Blue";
			}
		}

		Info_SetValueForKey( userinfo, "team", team );

		trap_SetUserinfo( clientNum, userinfo );

		bot->client->ps.persistant[ PERS_TEAM ] = bot->client->sess.sessionTeam;

		G_ReadSessionData( bot->client );
		ClientUserinfoChanged( clientNum );
	}

	if (g_gametype.integer == GT_DUEL ||
		g_gametype.integer == GT_POWERDUEL)
	{
		int loners = 0;
		int doubles = 0;

		bot->client->sess.duelTeam = 0;
		G_PowerDuelCount(&loners, &doubles, qtrue);

		if (!doubles || loners > (doubles/2))
		{
            bot->client->sess.duelTeam = DUELTEAM_DOUBLE;
		}
		else
		{
            bot->client->sess.duelTeam = DUELTEAM_LONE;
		}

		bot->client->sess.sessionTeam = TEAM_SPECTATOR;
		SetTeam(bot, "s");
	}
	else
	{
		if( delay == 0 ) {
			ClientBegin( clientNum, qfalse );
			//UNIQUEFIX - what's the purpose of this?
			//ClientUserinfoChanged( clientNum );
			return;
		}

		AddBotToSpawnQueue( clientNum, delay );
		//UNIQUEFIX - what's the purpose of this?
		//ClientUserinfoChanged( clientNum );
	}
}
Пример #9
0
/**
Called from ClientConnect when the player first connects and
directly by the server system when the player updates a userinfo variable.

The game can override any of the settings and call trap_SetUserinfo
if desired.
*/
void ClientUserinfoChanged(int clientNum)
{
	gentity_t *ent;
	int		teamTask, teamLeader, team, health;
	char	*s;
	char	oldname[MAX_STRING_CHARS];
	gclient_t	*client;
	char	userinfo[MAX_INFO_STRING];
	char	*nameError;

	ent = g_entities + clientNum;
	client = ent->client;

	trap_GetUserinfo(clientNum, userinfo, sizeof(userinfo));

	// check for malformed or illegal info strings
	if (!Info_Validate(userinfo)) {
		strcpy (userinfo, "\\name\\badinfo");
		// don't keep those clients and userinfo
		trap_DropClient(clientNum, "Invalid userinfo");
	}

	// check for local client
	s = Info_ValueForKey(userinfo, "ip");
	if (!strcmp(s, "localhost")) {
		client->pers.localClient = qtrue;
	}

	// check the item prediction
	s = Info_ValueForKey(userinfo, "cg_predictItems");
	if (!atoi(s)) {
		client->pers.predictItemPickup = qfalse;
	} else {
		client->pers.predictItemPickup = qtrue;
	}

	// set name
	Q_strncpyz(oldname, client->pers.netname, sizeof(oldname));
	s = Info_ValueForKey(userinfo, "name");
	nameError = ClientCleanName(s, client->pers.netname, sizeof client->pers.netname);

	if (client->pers.connected == CON_CONNECTED && strcmp(oldname, s)) {
		if (client->pers.muted) {
			ClientPrint(ent, "You cannot change your name while you are muted.");
		} else if (nameError) {
			ClientPrint(ent, "%s", nameError);
		} else {
			G_LogPrintf("%s ^7renamed to %s\n", oldname, client->pers.netname);
		}

		if (nameError || client->pers.muted) {
			Q_strncpyz(client->pers.netname, oldname, sizeof client->pers.netname);
		}
	}

	if (client->sess.sessionTeam == TEAM_SPECTATOR) {
		if (client->sess.spectatorState == SPECTATOR_SCOREBOARD) {
			Q_strncpyz(client->pers.netname, "scoreboard", sizeof(client->pers.netname));
		}
	}

	// set max health
	health = atoi(Info_ValueForKey(userinfo, "handicap"));
	client->pers.maxHealth = health;
	if (client->pers.maxHealth < 1 || client->pers.maxHealth > 100) {
		client->pers.maxHealth = 100;
	}
	client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;

	// bots set their team a few frames later
	if (g_gametype.integer >= GT_TEAM && g_entities[clientNum].r.svFlags & SVF_BOT) {
		s = Info_ValueForKey(userinfo, "team");
		if (!Q_stricmp(s, "red") || !Q_stricmp(s, "r")) {
			team = TEAM_RED;
		} else if (!Q_stricmp(s, "blue") || !Q_stricmp(s, "b")) {
			team = TEAM_BLUE;
		} else {
			// pick the team with the least number of players
			team = PickTeam(clientNum);
		}
	}
	else {
		team = client->sess.sessionTeam;
	}

	// team task (0 = none, 1 = offence, 2 = defence)
	teamTask = atoi(Info_ValueForKey(userinfo, "teamtask"));
	// team Leader (1 = leader, 0 is normal player)
	teamLeader = client->sess.teamLeader;

	// send over a subset of the userinfo keys so other clients can
	// print scoreboards, display models, and play custom sounds
	if (ent->r.svFlags & SVF_BOT) {
		s = va("n\\%s\\t\\%i\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d",
			client->pers.netname, team, client->pers.maxHealth,
			client->sess.wins, client->sess.losses,
			Info_ValueForKey(userinfo, "skill"), teamTask, teamLeader);
	}
	else {
		s = va("n\\%s\\t\\%i\\s\\%d\\r\\%i\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d",
			client->pers.netname, team, client->sess.specOnly,
			client->pers.ready, client->pers.maxHealth,
			client->sess.wins, client->sess.losses, teamTask, teamLeader);
	}

	trap_SetConfigstring(CS_PLAYERS+clientNum, s);

	// this is not the userinfo, more like the configstring actually
	G_LogPrintf("ClientUserinfoChanged: %i %s\n", clientNum, s);
}
Пример #10
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
    int				clientNum;
    char			*botinfo;
    gentity_t		*bot;
    char			*key;
    char			*s;
    char			*botname;
    char			*model;
    char			*headmodel;
    char			*logo;
    char			userinfo[MAX_INFO_STRING];

    // get the botinfo from bots.txt
    botinfo = G_GetBotInfoByName( name );
    if ( !botinfo ) {
        G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
        return;
    }

    // create the bot's userinfo
    userinfo[0] = '\0';

    botname = Info_ValueForKey( botinfo, "funname" );
    if( !botname[0] ) {
        botname = Info_ValueForKey( botinfo, "name" );
    }
    // check for an alternative name
    if (altname && altname[0]) {
        botname = altname;
    }
    Info_SetValueForKey( userinfo, "name", botname );
    Info_SetValueForKey( userinfo, "rate", "25000" );
    Info_SetValueForKey( userinfo, "snaps", "20" );
    Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );

    if ( skill >= 1 && skill < 2 ) {
        Info_SetValueForKey( userinfo, "handicap", "50" );
    }
    else if ( skill >= 2 && skill < 3 ) {
        Info_SetValueForKey( userinfo, "handicap", "70" );
    }
    else if ( skill >= 3 && skill < 4 ) {
        Info_SetValueForKey( userinfo, "handicap", "90" );
    }

    key = "spraylogo";
    logo = Info_ValueForKey( botinfo, key);
    if ( !*logo ) {
        logo = "15_padlogo";
    }
    Info_SetValueForKey( userinfo, key, logo );

    key = "model";
    model = Info_ValueForKey( botinfo, key );
    if ( !*model ) {
        model = "padman/default";
    }
    else if ( g_gametype.integer < GT_TEAM ) {
        // If a team is given, but we're not in a team-gametype
        // this is caused by the ui, so we're forcing a skin.
        // This is rather nasty..

        // TODO: Check whether the resulting model exists

        if ( *team ) {
            char *color = NULL;
            if ( !Q_stricmp( team, "red" )
                    || !Q_stricmp( team, "r" )
                    || !Q_stricmp( team, "0" ) ) {
                color = "red";
            }
            else if ( !Q_stricmp( team, "blue" )
                      || !Q_stricmp( team, "b" )
                      || !Q_stricmp( team, "1" ) ) {
                color = "blue";
            }

            // user decided to add a skin and specify a team
            // use skin color (way easier to implement)
            // FIXME: Explicitly search for color after ('/' or) '_'
            if ( strstr( model, "_red" ) || strstr( model, "_blue" ) ) {
                color = NULL;
            }

            if ( color ) {
                if ( strrchr( model, '/' ) ) {
                    // model is a skin already, append colorname to skin
                    // fatpad/fatty _red
                    model = va( "%s_%s", model, color );
                }
                else {
                    // model is a "basemodel", append skin
                    // fatpad /red
                    model = va( "%s/%s", model, color );
                }
            }
        }
    }

    Info_SetValueForKey( userinfo, key, model );
    key = "team_model";
    Info_SetValueForKey( userinfo, key, model );

    key = "headmodel";
    headmodel = Info_ValueForKey( botinfo, key );
    if ( !*headmodel ) {
        headmodel = model;
    }
    Info_SetValueForKey( userinfo, key, headmodel );
    key = "team_headmodel";
    Info_SetValueForKey( userinfo, key, headmodel );

    key = "gender";
    s = Info_ValueForKey( botinfo, key );
    if ( !*s ) {
        s = "male";
    }
    Info_SetValueForKey( userinfo, "sex", s );

    key = "color1";
    s = Info_ValueForKey( botinfo, key );
    if ( !*s ) {
        s = "4";
    }
    Info_SetValueForKey( userinfo, key, s );

    key = "color2";
    s = Info_ValueForKey( botinfo, key );
    if ( !*s ) {
        s = "5";
    }
    Info_SetValueForKey( userinfo, key, s );

    s = Info_ValueForKey(botinfo, "aifile");
    if (!*s ) {
        trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" );
        return;
    }

    // have the server allocate a client slot
    clientNum = trap_BotAllocateClient();
    if ( clientNum == -1 ) {
        G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
        G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
        return;
    }

    // initialize the bot settings
    if( !team || !*team ) {
        if( g_gametype.integer >= GT_TEAM ) {
            if( PickTeam(clientNum) == TEAM_RED) {
                team = "red";
            }
            else {
                team = "blue";
            }
        }
        else {
            team = "red";
        }
    }
    Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
    Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
    Info_SetValueForKey( userinfo, "team", team );

    bot = &g_entities[ clientNum ];
    bot->r.svFlags |= SVF_BOT;
    bot->inuse = qtrue;

    // register the userinfo
    trap_SetUserinfo( clientNum, userinfo );

    // have it connect to the game as a normal client
    if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
        return;
    }

    if( delay == 0 ) {
        ClientBegin( clientNum );
        return;
    }

    AddBotToSpawnQueue( clientNum, delay );
}
Пример #11
0
Файл: g_bot.c Проект: GenaSG/ET
/*
==================
G_SpawnBot
==================
*/
void G_SpawnBot( const char *text )
{
	// bot parameters
	char			name[MAX_TOKEN_CHARS]		= "wolfBot";
	//GS  prevent bot health from counting down to 70 (i.e. don't set STAT_MAX_HEALTH = 70)
	char			skill[MAX_TOKEN_CHARS]		= "4";
	char			team[MAX_TOKEN_CHARS]		= "";
	char			pClass[MAX_TOKEN_CHARS]		= "";
	char			pWeapon[MAX_TOKEN_CHARS]	= "0";
	char			spawnPoint[MAX_TOKEN_CHARS]	= "";
	char			respawn[MAX_TOKEN_CHARS]	= "";
	char			scriptName[MAX_TOKEN_CHARS]	= "wolfBot";
	char			characterFile[MAX_TOKEN_CHARS]	= "";

	// START - Mad Doc - TDF
	char			rank[MAX_TOKEN_CHARS] = "";
	char			botSkills[MAX_TOKEN_CHARS] = "";
	// END Mad Doc - TDF

	char			pow[MAX_TOKEN_CHARS]		= "no";


	// This is the selection meny index used in SetWolfSpawnWeapons
	int		weaponSpawnNumber = -1;

	// parsing vars
	char			*token, *pStr, *old_pStr;
	char			cmd[MAX_TOKEN_CHARS], last_cmd[MAX_TOKEN_CHARS];
	char			cmd_var[MAX_TOKEN_CHARS];
	char			string[MAX_TOKEN_CHARS];
	int				j, pClassInt;
	int				characterInt, rankNum;
	int				skills[SK_NUM_SKILLS];
	qboolean		prisonerOfWar;
	int				teamNum;

	// parameters
	spawnBotCommand_t	params[] =
	{
		{"/name",		name,			qfalse,		"[name]"},
		{"/skill",		skill,			qfalse,		"[0-4]"},
		{"/team",		team,			qfalse,		"[AXIS/ALLIES]"},
		{"/class",		pClass,			qfalse,		"[SOLDIER/MEDIC/LIEUTENANT/ENGINEER/COVERTOPS/FIELDOPS]"}, // FIXME: remove LIEUTENANT from missionpack
		{"/weapon",		pWeapon,		qfalse,		"[weaponValue]"},
		{"/spawnpoint",	spawnPoint,		qtrue,		"[targetname]"},
		{"/respawn",	respawn,		qfalse,		"[ON/OFF]"},
		{"/scriptName",	scriptName,		qfalse,		"[scriptName]"},
		{"/character",	characterFile,	qfalse,		"[character]"},
		// START Mad Doc - TDF
		{"/rank",		rank,			qfalse,		"[rank]"},
		{"/skills",		botSkills,		qfalse,		"[botskills]"}, // not really to be exposed to script
		// END Mad Doc - TDF
		{"/pow",		pow,			qfalse,		"[yes/no]"},

		{NULL}
	};
	// special tables
	typedef struct {
		char	*weapon;
		int		index;
	} spawnBotWeapons_t;

	// TAT 1/16/2003 - uninit'ed data here - getting crazy data for the skills
	memset(&skills, 0, sizeof(skills));

	//
	// parse the vars
	pStr = (char *)text;
	token = COM_Parse( &pStr );
	Q_strncpyz( cmd, token, sizeof(cmd) );
	// if this is a question mark, show help info
	if (!Q_stricmp( cmd, "?" ) || !Q_stricmp( cmd, "/?" )) {
		G_Printf( "Spawns a bot into the game, with the given parameters.\n\nSPAWNBOT [/param [value]] [/param [value]] ...\n\n  where [/param [value]] may consist of:\n\n" );
		for (j=0; params[j].cmd; j++) {
			G_Printf( "  %s %s\n", params[j].cmd, params[j].help );
		}
		return;
	}
	//
	// intitializations
	for (j=0; params[j].cmd; j++) {
		params[j].count = 0;
	}
	memset( last_cmd, 0, sizeof(last_cmd) );
	pStr = (char *)text;
	//
	// parse each command
	while (cmd[0]) {
		//
		// build the string up to the next parameter change
		token = COM_Parse( &pStr );
		Q_strncpyz( cmd, token, sizeof(cmd) );
		if (!cmd[0]) break;
		// if we find an "or", then use the last command
		if (!Q_stricmp( cmd, "or" )) {
			// use the last command
			Q_strncpyz( cmd, last_cmd, sizeof(cmd) );
		}
		//
		// read the parameters
		memset( string, 0, sizeof(string) );
		token = COM_Parse( &pStr );
		Q_strncpyz( cmd_var, token, sizeof(cmd_var) );
		if (!cmd_var[0]) break;
		while (qtrue) {
			Q_strcat( string, sizeof(string), cmd_var );
			old_pStr = pStr;
			token = COM_Parse( &pStr );
			Q_strncpyz( cmd_var, token, sizeof(cmd_var) );
			if (cmd_var[0] && (cmd_var[0] == '/' || !Q_stricmp( cmd_var, "or" ))) {
				pStr = old_pStr;
				break;
			}
			if (!cmd_var[0]) break;
			Q_strcat( string, sizeof(string), " " );
		}
		//
		// see if this command exists in the parameters table
		for (j=0; params[j].cmd; j++) {
			if (!Q_stricmp( params[j].cmd, cmd )) {
				// found a match, if this field already has an entry, then randomly override it
				if (!params[j].count || (!params[j].appendParams && ((rand()%(++params[j].count)) == 0))) {
					Q_strncpyz( params[j].string, string, sizeof(string) );
				} else if (params[j].appendParams) {
					// append this token
					Q_strcat( params[j].string, sizeof(string), va(" %s", string) );
				}
				params[j].count++;
				break;
			}
		}
		if (!params[j].cmd) {
			G_Printf( "G_SpawnBot: unknown parameter: %s\nFor usage info, use \"spawnbot /?\"\n", cmd );
			return;
		}
		//
		Q_strncpyz( last_cmd, cmd, sizeof(last_cmd) );
		Q_strncpyz( cmd, cmd_var, sizeof(cmd) );
	}
	//
	if (strlen( pClass )) {
		pClassInt = 1 + G_ClassForString( pClass );
	} else {
		pClassInt = 0;
	}

	if ( !Q_stricmp( team, "red" ) || !Q_stricmp( team, "r" ) || !Q_stricmp( team, "axis" ) ) {
		teamNum = TEAM_AXIS;
	} else if ( !Q_stricmp( team, "blue" ) || !Q_stricmp( team, "b" ) || !Q_stricmp( team, "allies" ) ) {
		teamNum = TEAM_ALLIES;
	} else {
		// pick the team with the least number of players
		teamNum = PickTeam( -1 );
	}

	G_BotParseCharacterParms( characterFile, &characterInt );

	// Gordon: 27/11/02
	if( *pow && !Q_stricmp(pow, "yes") ) {
		prisonerOfWar = qtrue;
	} else {
		prisonerOfWar = qfalse;
	}

	// START Mad Doc - TDF
	// special case: if "NONE" is specified, treat this differently
	if (!Q_stricmp(pWeapon, "NONE"))
	{
		weaponSpawnNumber = -1;
	}
	// END Mad Doc - TDF

	// START	Mad Doctor I changes, 8/17/2002. 
	// If we have a weapon specified, and we have a class specified
	else if (isdigit(pWeapon[0]))
	{
		// Just convert the string to a number
		weaponSpawnNumber = atoi(pWeapon);

	} // if (isdigit(pWeapon[0]))...

	// If we have a weapon specified as a string, and we have a class specified
	else if (pClassInt > 0)
	{
		// Translate the weapon name into a proper weapon index
		// Get the index for the weapon
		weaponSpawnNumber = Bot_GetWeaponForClassAndTeam( pClassInt - 1, teamNum, pWeapon );

		// Get default weapon
		if (weaponSpawnNumber == -1)
			weaponSpawnNumber = BG_GetPlayerClassInfo( teamNum, pClassInt - 1 )->classWeapons[0];
		
	} // if (Q_stricmp(pWeapon[MAX_TOKEN_CHARS], "0")...

	// Otherwise, no weapon is selected
	else
	{
		// Just use the default
		weaponSpawnNumber = BG_GetPlayerClassInfo( teamNum, pClassInt - 1 )->classWeapons[0];

	} // else...


	// START Mad Doc - TDF
	rankNum = atoi(rank);
	if( rankNum ) {
		rankNum--; // people like to start with 1
					// Gordon: coders are people too :(
	}

	if (botSkills[0])
	{
		// parse the skills out
		int i;
		char *pString, *token;
	
		pString = botSkills;
		for (i = 0; i < SK_NUM_SKILLS; i++)
		{
			token = COM_ParseExt( &pString, qfalse );
			skills[i] = atoi(token);
		}
	}


	//	{"/botskills",	botSkills,		qfalse,		"[botskills]"}, // not really to be exposed to script

// END Mad Doc - TDF

	G_AddBot( name, atoi(skill), team, spawnPoint, pClassInt, weaponSpawnNumber, characterInt, respawn, scriptName, rankNum, skills, prisonerOfWar );

// END		Mad Doctor I changes, 8/17/2002. 
}
Пример #12
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
//	char			*headmodel;
	char			userinfo[MAX_INFO_STRING];
	int				preTeam = 0;

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );

	if ( skill >= 1 && skill < 2 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	}
	else if ( skill >= 2 && skill < 3 ) {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	}
	else if ( skill >= 3 && skill < 4 ) {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	}

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "kyle/default";
	}
	Info_SetValueForKey( userinfo, key, model );

/*	key = "headmodel";
	headmodel = Info_ValueForKey( botinfo, key );
	if ( !*headmodel ) {
		headmodel = model;
	}
	Info_SetValueForKey( userinfo, key, headmodel );
	key = "team_headmodel";
	Info_SetValueForKey( userinfo, key, headmodel );
*/
	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "saber1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "single_1";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "saber2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "none";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "personality");
	if (!*s )
	{
		Info_SetValueForKey( userinfo, "personality", "botfiles/default.jkb" );
	}
	else
	{
		Info_SetValueForKey( userinfo, "personality", s );
	}

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
//		G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
//		G_Printf( S_COLOR_RED "Start server with more 'open' slots.\n" );
		trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "UNABLE_TO_ADD_BOT")));
		return;
	}

	// initialize the bot settings
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM ) {
			if( PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "red";
		}
	}
//	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
	Info_SetValueForKey( userinfo, "team", team );

	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	bot->inuse = qtrue;

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	if (g_gametype.integer >= GT_TEAM)
	{
		if (team && Q_stricmp(team, "red") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_RED;
		}
		else if (team && Q_stricmp(team, "blue") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_BLUE;
		}
		else
		{
			bot->client->sess.sessionTeam = PickTeam( -1 );
		}
	}

	if (g_gametype.integer == GT_SIEGE)
	{
		bot->client->sess.siegeDesiredTeam = bot->client->sess.sessionTeam;
		bot->client->sess.sessionTeam = TEAM_SPECTATOR;
	}

	preTeam = bot->client->sess.sessionTeam;

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if (bot->client->sess.sessionTeam != preTeam)
	{
		trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING);

		if (bot->client->sess.sessionTeam == TEAM_SPECTATOR)
		{
			bot->client->sess.sessionTeam = preTeam;
		}

		if (bot->client->sess.sessionTeam == TEAM_RED)
		{
			team = "Red";
		}
		else
		{
			if (g_gametype.integer == GT_SIEGE)
			{
				if (bot->client->sess.sessionTeam == TEAM_BLUE)
				{
					team = "Blue";
				}
				else
				{
					team = "s";
				}
			}
			else
			{
				team = "Blue";
			}
		}

		Info_SetValueForKey( userinfo, "team", team );

		trap_SetUserinfo( clientNum, userinfo );

		bot->client->ps.persistant[ PERS_TEAM ] = bot->client->sess.sessionTeam;

		G_ReadSessionData( bot->client );
		ClientUserinfoChanged( clientNum );
	}

	if (g_gametype.integer == GT_DUEL ||
		g_gametype.integer == GT_POWERDUEL)
	{
		int loners = 0;
		int doubles = 0;

		bot->client->sess.duelTeam = 0;
		G_PowerDuelCount(&loners, &doubles, qtrue);

		if (!doubles || loners > (doubles/2))
		{
            bot->client->sess.duelTeam = DUELTEAM_DOUBLE;
		}
		else
		{
            bot->client->sess.duelTeam = DUELTEAM_LONE;
		}

		bot->client->sess.sessionTeam = TEAM_SPECTATOR;
		SetTeam(bot, "s");
	}
	else
	{
		if( delay == 0 ) {
			ClientBegin( clientNum, qfalse );
			return;
		}		
		AddBotToSpawnQueue( clientNum, delay );
	}
}
Пример #13
0
void G_InitSessionData( gclient_t *client, char *userinfo, qboolean isBot, qboolean firstTime ) {
	clientSession_t	*sess;
	const char		*value;

	sess = &client->sess;

	client->sess.siegeDesiredTeam = TEAM_FREE;

	// initial team determination
	if ( g_gametype.integer >= GT_TEAM ) {
		if ( g_teamAutoJoin.integer ) {
			sess->sessionTeam = PickTeam( -1 );
		} else {
			// always spawn as spectator in team games
			if (!isBot)
			{
				sess->sessionTeam = TEAM_SPECTATOR;	
			}
			else
			{ //Bots choose their team on creation
				value = Info_ValueForKey( userinfo, "team" );
				if (value[0] == 'r' || value[0] == 'R')
				{
					sess->sessionTeam = TEAM_RED;
				}
				else if (value[0] == 'b' || value[0] == 'B')
				{
					sess->sessionTeam = TEAM_BLUE;
				}
				else
				{
					sess->sessionTeam = PickTeam( -1 );
				}
			}
		}
	} else {
		value = Info_ValueForKey( userinfo, "team" );
		if ( value[0] == 's' ) {
			// a willing spectator, not a waiting-in-line
			sess->sessionTeam = TEAM_SPECTATOR;
		} else {
			switch ( g_gametype.integer ) {
			default:
			case GT_FFA:
			case GT_HOLOCRON:
			case GT_JEDIMASTER:
			case GT_SINGLE_PLAYER:
				if ( g_maxGameClients.integer > 0 && 
					level.numNonSpectatorClients >= g_maxGameClients.integer ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			case GT_DUEL:
				// if the game is full, go into a waiting mode
				if ( level.numNonSpectatorClients >= 2 ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			case GT_POWERDUEL:
				{
					int loners = 0;
					int doubles = 0;

					G_PowerDuelCount(&loners, &doubles, qtrue);

					if (!doubles || loners > (doubles/2))
					{
						sess->duelTeam = DUELTEAM_DOUBLE;
					}
					else
					{
						sess->duelTeam = DUELTEAM_LONE;
					}
				}
				sess->sessionTeam = TEAM_SPECTATOR;
				break;
			}
		}
	}

	if (firstTime){
		Q_strncpyz(sess->ipString, Info_ValueForKey( userinfo, "ip" ) , sizeof(sess->ipString));
	}

    if ( !getIpPortFromString( sess->ipString, &(sess->ip), &(sess->port) ) )
    {
        sess->ip = 0;
        sess->port = 0;
    }

    sess->nameChangeTime = getGlobalTime();

	// accounts system
	//if (isDBLoaded && !isBot){
	//	username = Info_ValueForKey(userinfo, "password");
	//	delimitator = strchr(username,':');
	//	if (delimitator){
	//		*delimitator = '\0'; //seperate username and password
	//		Q_strncpyz(client->sess.username,username,sizeof(client->sess.username));
	//	} else {
	//		client->sess.username[0] = '\0';
	//	}
	//} else 
	{
		client->sess.username[0] = '\0';
	}

	sess->isInkognito = qfalse;
	sess->ignoreFlags = 0;

	sess->canJoin = !sv_passwordlessSpectators.integer || PasswordMatches( Info_ValueForKey( userinfo, "password" ) );
	sess->whTrustToggle = qfalse;

	sess->spectatorState = SPECTATOR_FREE;
	sess->spectatorTime = level.time;
    sess->inactivityTime = getGlobalTime() + 1000 * g_spectatorInactivity.integer;

	sess->siegeClass[0] = 0;

	Q_strncpyz( sess->saberType, Info_ValueForKey( userinfo, "saber1" ), sizeof( sess->saberType ) );
	Q_strncpyz( sess->saber2Type, Info_ValueForKey( userinfo, "saber2" ), sizeof( sess->saber2Type ) );

	sess->shadowMuted = qfalse;

#ifdef NEWMOD_SUPPORT
	sess->cuidHash[0] = '\0';
	sess->serverKeys[0] = sess->serverKeys[1] = 0;
	sess->auth = level.nmAuthEnabled && *Info_ValueForKey( userinfo, "nm_ver" ) ? PENDING : INVALID;
#endif
}
Пример #14
0
Файл: g_bot.c Проект: GenaSG/ET
static void G_AddBot( const char *name, int skill, const char *team, const char *spawnPoint, int playerClass, int playerWeapon, int characerIndex, const char *respawn, const char *scriptName, int rank, int skills[], qboolean pow ) {
#define	MAX_BOTNAMES 1024
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
//	char			*model;
	char			userinfo[MAX_INFO_STRING];

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( "wolfbot" );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%i", skill) );

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s ) {
		trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" );
		return;
	}

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient( 0 );	// Arnout: 0 means no prefered clientslot
	if ( clientNum == -1 ) {
		G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
		G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
		return;
	}

	// initialize the bot settings
	if( !team || !*team ) {
		if( PickTeam(clientNum) == TEAM_AXIS) {
			team = "red";
		} else {
			team = "blue";
		}
	}
	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	//Info_SetValueForKey( userinfo, "skill", va( "%i", skill ) );
	Info_SetValueForKey( userinfo, "team", team );

	if( spawnPoint && spawnPoint[0] ) {
		Info_SetValueForKey( userinfo, "spawnPoint", spawnPoint );
	}

	if (scriptName && scriptName[0]) {
		Info_SetValueForKey( userinfo, "scriptName", scriptName );
	}

/*	if (playerClass > 0) {
		Info_SetValueForKey( userinfo, "pClass", va("%i", playerClass) );
	}

	if (playerWeapon) {
		Info_SetValueForKey( userinfo, "pWeapon", va("%i", playerWeapon) );
	}*/
	// END Mad Doc - TDF

	key = "wolfbot";
	if (!Q_stricmp( (char *)name, key )) {
		// read the botnames file, and pick a name that doesnt exist
		fileHandle_t f;
		int len, i, j, k;
		qboolean setname = qfalse;
		char botnames[8192], *pbotnames, *listbotnames[MAX_BOTNAMES], *token, *oldpbotnames;
		int	lengthbotnames[MAX_BOTNAMES];

		len = trap_FS_FOpenFile( "botfiles/botnames.txt", &f, FS_READ );

		if (len >= 0) {
			if (len > sizeof(botnames)) {
				G_Error( "botfiles/botnames.txt is too big (max = %i)", (int)sizeof(botnames) );
			}
			memset( botnames, 0, sizeof(botnames) );
			trap_FS_Read( botnames, len, f );
			pbotnames = botnames;
			// read them in
			i = 0;
			oldpbotnames = pbotnames;
			while ((token = COM_Parse( &pbotnames ))) {
				if (!token[0]) break;
				listbotnames[i] = strstr( oldpbotnames, token );
				lengthbotnames[i] = strlen(token);
				listbotnames[i][lengthbotnames[i]] = 0;
				oldpbotnames = pbotnames;
				if (++i == MAX_BOTNAMES) break;
			}
			//
			if (i > 2) {
				j = rand() % (i-1);	// start at a random spot inthe list
				for( k = j + 1; k != j; k++ ) {
					if( k == i ) {
						k = -1;	// gets increased on next loop
						continue;
					}
					if (ClientFromName( listbotnames[k] ) == -1) {
						// found an unused name
						Info_SetValueForKey( userinfo, "name", listbotnames[k]  );
						setname = qtrue;
						break;
					}
				}
			}
			//
			trap_FS_FCloseFile( f );
		}

		if (!setname) {
			Info_SetValueForKey( userinfo, "name", va("wolfbot_%i", clientNum+1)  );
		}
	} else {
		Info_SetValueForKey( userinfo, "name", name );
	}

	// if a character was specified, put the index of that character filename in the CS_CHARACTERS table in the userinfo
	if( characerIndex != -1 ) {
		Info_SetValueForKey( userinfo, "ch", va( "%i", characerIndex ) );
	}

	// if a rank was specified, use that
/*	if (rank != -1) {
		Info_SetValueForKey(userinfo, "rank", va("%i", rank));
	}*/

	// END Mad Doc - TDF
	
	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	if( pow ) {
		bot->r.svFlags |= SVF_POW;
	}
	bot->inuse = qtrue;
	bot->aiName = bot->client->pers.netname;

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ((s = ClientConnect( clientNum, qtrue, qtrue ))) {
		G_Printf( S_COLOR_RED "Unable to add bot: %s\n", s );
		return;
	}

	SetTeam( bot, (char *)team, qtrue, -1, -1, qfalse );

/*	if( skills ) {
		int i;
		
		for( i = 0; i < SK_NUM_SKILLS; i++ ) {
			bot->client->sess.skill[i] = skills[i];
		}
	}*/
	return;
}
Пример #15
0
/*
===========
ClientBegin

called when a client has finished connecting, and is ready
to be placed into the level.  This will happen every level load,
and on transition between teams, but doesn't happen on respawns
============
*/
void ClientBegin( int clientNum, qboolean allowTeamReset ) {
	gentity_t	*ent;
	gclient_t	*client;
	gentity_t	*tent;
	int			flags, i;
	char		userinfo[MAX_INFO_VALUE], *modelname;

	ent = g_entities + clientNum;

	if ((ent->r.svFlags & SVF_BOT) && g_gametype.integer >= GT_TEAM)
	{
		if (allowTeamReset)
		{
			const char *team = "Red";
			int preSess;

			//SetTeam(ent, "");
			ent->client->sess.sessionTeam = PickTeam(-1);
			trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING);

			if (ent->client->sess.sessionTeam == TEAM_SPECTATOR)
			{
				ent->client->sess.sessionTeam = TEAM_RED;
			}

			if (ent->client->sess.sessionTeam == TEAM_RED)
			{
				team = "Red";
			}
			else
			{
				team = "Blue";
			}

			Info_SetValueForKey( userinfo, "team", team );

			trap_SetUserinfo( clientNum, userinfo );

			ent->client->ps.persistant[ PERS_TEAM ] = ent->client->sess.sessionTeam;

			preSess = ent->client->sess.sessionTeam;
			G_ReadSessionData( ent->client );
			ent->client->sess.sessionTeam = preSess;
			G_WriteClientSessionData(ent->client);
			ClientUserinfoChanged( clientNum );
			ClientBegin(clientNum, qfalse);
			return;
		}
	}

	client = level.clients + clientNum;

	if ( ent->r.linked ) {
		trap_UnlinkEntity( ent );
	}
	G_InitGentity( ent );
	ent->touch = 0;
	ent->pain = 0;
	ent->client = client;

	client->pers.connected = CON_CONNECTED;
	client->pers.enterTime = level.time;
	client->pers.teamState.state = TEAM_BEGIN;

	// save eflags around this, because changing teams will
	// cause this to happen with a valid entity, and we
	// want to make sure the teleport bit is set right
	// so the viewpoint doesn't interpolate through the
	// world to the new position
	flags = client->ps.eFlags;

	i = 0;

	while (i < NUM_FORCE_POWERS)
	{
		if (ent->client->ps.fd.forcePowersActive & (1 << i))
		{
			WP_ForcePowerStop(ent, i);
		}
		i++;
	}

	i = TRACK_CHANNEL_1;

	while (i < NUM_TRACK_CHANNELS)
	{
		if (ent->client->ps.fd.killSoundEntIndex[i-50] && ent->client->ps.fd.killSoundEntIndex[i-50] < MAX_GENTITIES && ent->client->ps.fd.killSoundEntIndex[i-50] > 0)
		{
			G_MuteSound(ent->client->ps.fd.killSoundEntIndex[i-50], CHAN_VOICE);
		}
		i++;
	}
	i = 0;

	memset( &client->ps, 0, sizeof( client->ps ) );
	client->ps.eFlags = flags;

	client->ps.hasDetPackPlanted = qfalse;

	//first-time force power initialization
	WP_InitForcePowers( ent );

	//init saber ent
	WP_SaberInitBladeData( ent );

	// First time model setup for that player.
	trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) );
	modelname = Info_ValueForKey (userinfo, "model");
	SetupGameGhoul2Model(client, modelname);

	if (ent->client->ghoul2)
	{
		ent->bolt_Head = trap_G2API_AddBolt(ent->client->ghoul2, 0, "cranium");
		ent->bolt_Waist = trap_G2API_AddBolt(ent->client->ghoul2, 0, "thoracic");
		ent->bolt_LArm = trap_G2API_AddBolt(ent->client->ghoul2, 0, "lradius");
		ent->bolt_RArm = trap_G2API_AddBolt(ent->client->ghoul2, 0, "rradius");
		ent->bolt_LLeg = trap_G2API_AddBolt(ent->client->ghoul2, 0, "ltibia");
		ent->bolt_RLeg = trap_G2API_AddBolt(ent->client->ghoul2, 0, "rtibia");
		ent->bolt_Motion = trap_G2API_AddBolt(ent->client->ghoul2, 0, "Motion");
	}

	// locate ent at a spawn point
	ClientSpawn( ent );

	if ( client->sess.sessionTeam != TEAM_SPECTATOR ) {
		// send event
		tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN );
		tent->s.clientNum = ent->s.clientNum;

		if ( g_gametype.integer != GT_TOURNAMENT  ) {
			trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " %s\n\"", client->pers.netname, G_GetStripEdString("SVINGAME", "PLENTER")) );
		}
	}
	G_LogPrintf( "ClientBegin: %i\n", clientNum );

	// count current clients and rank for scoreboard
	CalculateRanks();

	G_ClearClientLog(clientNum);
}
Пример #16
0
void SetTeam( gentity_t *ent, char *s ) {
	int					clientNum, specClient=0;
	team_t				team, oldTeam;
	gclient_t			*client = ent->client;
	spectatorState_t	specState = SPECTATOR_NOT;

	// see what change is requested
	clientNum = ARRAY_INDEX( level.clients, client );

	if ( !Q_stricmp( s, "scoreboard" ) || !Q_stricmp( s, "score" ) ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_SCOREBOARD;
	}

	else if ( !Q_stricmp( s, "follow1" ) ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_FOLLOW;
		specClient = -1;
	}

	else if ( !Q_stricmp( s, "follow2" ) ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_FOLLOW;
		specClient = -2;
	}

	else if ( !Q_stricmp( s, "spectator" ) || !Q_stricmp( s, "s" ) ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_FREE;
	}

	// if running a team game, assign player to one of the teams
	else if ( level.gametype >= GT_TEAMBLOOD ) {
		specState = SPECTATOR_NOT;
		if ( !Q_stricmp( s, "red" ) || !Q_stricmp( s, "r" ) )
			team = TEAM_RED;
		else if ( !Q_stricmp( s, "blue" ) || !Q_stricmp( s, "b" ) )
			team = TEAM_BLUE;
		else
			team = PickTeam( clientNum ); // pick the team with the least number of players

		if ( g_teamForceBalance->integer  ) {
			int		counts[TEAM_NUM_TEAMS];

			counts[TEAM_BLUE] = TeamCount( clientNum, TEAM_BLUE );
			counts[TEAM_RED] = TeamCount( clientNum, TEAM_RED );

			// We allow a spread of two
			if ( team == TEAM_RED && counts[TEAM_RED] - counts[TEAM_BLUE] > 1 ) {
				trap->SV_GameSendServerCommand( clientNum, "cp \"Red team has too many players.\n\"" );
				return; // ignore the request
			}
			if ( team == TEAM_BLUE && counts[TEAM_BLUE] - counts[TEAM_RED] > 1 ) {
				trap->SV_GameSendServerCommand( clientNum, "cp \"Blue team has too many players.\n\"" );
				return; // ignore the request
			}

			// It's ok, the team we are switching to has less or same number of players
		}

	}
	else
		team = TEAM_FREE; // force them to spectators if there aren't any spots free

	// override decision if limiting the players
	if ( (level.gametype == GT_DUEL) && level.numNonSpectatorClients >= 2 )
		team = TEAM_SPECTATOR;
	else if ( g_maxGameClients->integer > 0 && level.numNonSpectatorClients >= g_maxGameClients->integer )
		team = TEAM_SPECTATOR;

	// decide if we will allow the change
	oldTeam = client->sess.sessionTeam;
	if ( team == oldTeam && team != TEAM_SPECTATOR )
		return;

	// if the player was dead leave the body
	if ( client->ps.stats[STAT_HEALTH] <= 0 ) {
		CopyToBodyQue( ent );
	}

	// he starts at 'base'
	client->pers.teamState.state = TEAM_BEGIN;
	if ( oldTeam != TEAM_SPECTATOR ) {
		// Kill him (makes sure he loses flags, etc)
		ent->flags &= ~FL_GODMODE;
		ent->client->ps.stats[STAT_HEALTH] = ent->health = 0;
		player_die( ent, ent, ent, 100000, MOD_SUICIDE );

	}

	// they go to the end of the line for tournaments
	if ( team == TEAM_SPECTATOR && oldTeam != team )
		AddTournamentQueue( client );

	// exploit fix: with 3 (any odd amount?) players connected, one could /callvote map x followed by /team s to force the vote
	G_ClearVote( ent );

	client->sess.sessionTeam = team;
	client->sess.spectatorState = specState;
	client->sess.spectatorClient = specClient;

	BroadcastTeamChange( client, oldTeam );
	ClientUserinfoChanged( clientNum );
	ClientBegin( clientNum );
}
Пример #17
0
/*
================
G_InitSessionData

Called on a first-time connect
================
*/
void G_InitSessionData( gclient_t *client, char *userinfo, qboolean isBot ) {
	clientSession_t	*sess;
	const char		*value;

	sess = &client->sess;

	client->sess.siegeDesiredTeam = TEAM_FREE;

	// initial team determination
	if ( level.gametype >= GT_TEAM ) {
		if ( g_teamAutoJoin.integer && !(g_entities[client-level.clients].r.svFlags & SVF_BOT) ) {
			sess->sessionTeam = PickTeam( -1 );
			BroadcastTeamChange( client, -1 );
		} else {
			// always spawn as spectator in team games
			if (!isBot)
			{
				sess->sessionTeam = TEAM_SPECTATOR;	
			}
			else
			{ //Bots choose their team on creation
				value = Info_ValueForKey( userinfo, "team" );
				if (value[0] == 'r' || value[0] == 'R')
				{
					sess->sessionTeam = TEAM_RED;
				}
				else if (value[0] == 'b' || value[0] == 'B')
				{
					sess->sessionTeam = TEAM_BLUE;
				}
				else
				{
					sess->sessionTeam = PickTeam( -1 );
				}
				BroadcastTeamChange( client, -1 );
			}
		}
	} else {
		value = Info_ValueForKey( userinfo, "team" );
		if ( value[0] == 's' ) {
			// a willing spectator, not a waiting-in-line
			sess->sessionTeam = TEAM_SPECTATOR;
		} else {
			switch ( level.gametype ) {
			default:
			case GT_FFA:
			case GT_HOLOCRON:
			case GT_JEDIMASTER:
			case GT_SINGLE_PLAYER:
				if (!isBot && (!g_maxGameClients.integer || (g_maxGameClients.integer > 0 && //loda fixme - this should fix clients showing ingame when they really arnt , when first connect?
					level.numNonSpectatorClients >= g_maxGameClients.integer))) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			case GT_DUEL:
				// if the game is full, go into a waiting mode
				if ( level.numNonSpectatorClients >= 2 ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			case GT_POWERDUEL:
				//sess->duelTeam = DUELTEAM_LONE; //default
				{
					int loners = 0;
					int doubles = 0;

					G_PowerDuelCount(&loners, &doubles, qtrue);

					if (!doubles || loners > (doubles/2))
					{
						sess->duelTeam = DUELTEAM_DOUBLE;
					}
					else
					{
						sess->duelTeam = DUELTEAM_LONE;
					}
				}
				sess->sessionTeam = TEAM_SPECTATOR;
				break;
			}
		}
	}

	sess->spectatorState = SPECTATOR_FREE;
	AddTournamentQueue(client);

	sess->siegeClass[0] = 0;

	sess->ignore = 0;//[JAPRO - Serverside - All - Ignore]

	G_WriteClientSessionData( client );
}
Пример #18
0
/** LQ3A: Changed return from void to qboolean.
	This function reads the session data from cvars and assigns a team to the client,
	if we cannot assign a team it returns qfalse and the client should be dropped from the server.
	@see ClientConnect(). */
qboolean G_ReadSessionData(gclient_t *client) {
	char	s[MAX_STRING_CHARS];
	const char	*var;

	// bk001205 - format
	int teamLeader;
	int spectatorState;
	int sessionTeam;
	/* LQ3A */
	qboolean bCanClientSpectate;

	var = va( "session%i", client - level.clients );
	trap_Cvar_VariableStringBuffer( var, s, sizeof(s) );

	sscanf( s, "%i %i %i %i %i %i %i",
		&sessionTeam,                 // bk010221 - format
		&client->sess.spectatorTime,
		&spectatorState,              // bk010221 - format
		&client->sess.spectatorClient,
		&client->sess.wins,
		&client->sess.losses,
		&teamLeader                   // bk010221 - format
		);

	/* LQ3A */
	bCanClientSpectate = LQ3A_CanClientSpectate(LQ3A_ClientToEntity(client));

	/* Place clients into the same teams they were in previously. */
	if (g_gametype.integer >= GT_TEAM)
	{
		client->sess.sessionTeam = (team_t)sessionTeam;

		/* Force spectators into the game if we can no longer spectate. */
		if ((client->sess.sessionTeam == TEAM_SPECTATOR) && !bCanClientSpectate)
		{
			client->sess.sessionTeam = PickTeam(-1);
			BroadcastTeamChange(client, -1);
		}
	}
	/* Always default as spectator. */
	else if (bCanClientSpectate)
	{
		client->sess.sessionTeam = TEAM_SPECTATOR;
	}
	/* If we cannot spectate, can we join the game? */
	else if (LQ3A_GetVacantPlayerSlots())
	{
		client->sess.sessionTeam = TEAM_FREE;
	}
	else
	{
		/* No vacant player slots and we cannot spectate. */
		return qfalse;
	}

	if (client->sess.sessionTeam == TEAM_SPECTATOR)
	{
		/* Force free floating spectator mode each level load. */
		client->sess.spectatorState		= SPECTATOR_FREE;
		client->sess.spectatorClient	= 0;
	}

	client->sess.teamLeader = (qboolean)teamLeader;

	/* LQ3A */
	return qtrue;
}
Пример #19
0
// Called on a first-time connect
void G_InitClientSessionData( gclient_t *client, char *userinfo, qboolean isBot ) {
	clientSession_t	*sess = &client->sess;
	const char		*value;

	client->sess.siegeDesiredTeam = TEAM_FREE;

	// initial team determination
	if ( level.gametype >= GT_TEAM ) {
		if ( g_teamAutoJoin.integer && !(g_entities[client-level.clients].r.svFlags & SVF_BOT) ) {
			sess->sessionTeam = PickTeam( -1 );
			client->ps.fd.forceDoInit = 1; //every time we change teams make sure our force powers are set right
		} else {
			// always spawn as spectator in team games
			if (!isBot)
			{
				sess->sessionTeam = TEAM_SPECTATOR;	
			}
			else
			{ //Bots choose their team on creation
				value = Info_ValueForKey( userinfo, "team" );
				if (value[0] == 'r' || value[0] == 'R')
				{
					sess->sessionTeam = TEAM_RED;
				}
				else if (value[0] == 'b' || value[0] == 'B')
				{
					sess->sessionTeam = TEAM_BLUE;
				}
				else
				{
					sess->sessionTeam = PickTeam( -1 );
				}
				client->ps.fd.forceDoInit = 1; //every time we change teams make sure our force powers are set right
			}
		}
	} else {
		value = Info_ValueForKey( userinfo, "team" );
		if ( value[0] == 's' ) {
			// a willing spectator, not a waiting-in-line
			sess->sessionTeam = TEAM_SPECTATOR;
		} else {
			switch ( level.gametype ) {
			default:
			case GT_FFA:
			case GT_SINGLE_PLAYER:
				if ( g_maxGameClients.integer > 0 && 
					level.numNonSpectatorClients >= g_maxGameClients.integer ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			case GT_DUEL:
				// if the game is full, go into a waiting mode
				if ( level.numNonSpectatorClients >= 2 ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			case GT_POWERDUEL:
				//sess->duelTeam = DUELTEAM_LONE; //default
				{
					int loners = 0;
					int doubles = 0;

					G_PowerDuelCount(&loners, &doubles, qtrue);

					if (!doubles || loners > (doubles/2))
					{
						sess->duelTeam = DUELTEAM_DOUBLE;
					}
					else
					{
						sess->duelTeam = DUELTEAM_LONE;
					}
				}
				sess->sessionTeam = TEAM_SPECTATOR;
				break;
			}
		}
	}

	sess->spectatorState = SPECTATOR_FREE;
	AddTournamentQueue(client);

	G_WriteClientSessionData( client );
}
Пример #20
0
/*
================
G_InitSessionData

Called on a first-time connect
================
*/
void G_InitSessionData( gclient_t *client, char *userinfo, qboolean isBot ) {
	clientSession_t	*sess;
	const char		*value;

	sess = &client->sess;

	client->sess.siegeDesiredTeam = TEAM_FREE;

	// initial team determination
	if ( g_gametype.integer >= GT_TEAM ) {
		if ( g_teamAutoJoin.integer ) {
			sess->sessionTeam = PickTeam( -1 );
			BroadcastTeamChange( client, -1 );
		} else {
			// always spawn as spectator in team games
			if (!isBot)
			{
				sess->sessionTeam = TEAM_SPECTATOR;	
			}
			else
			{ //Bots choose their team on creation
				value = Info_ValueForKey( userinfo, "team" );
				if (value[0] == 'r' || value[0] == 'R')
				{
					sess->sessionTeam = TEAM_RED;
				}
				else if (value[0] == 'b' || value[0] == 'B')
				{
					sess->sessionTeam = TEAM_BLUE;
				}
				else
				{
					sess->sessionTeam = PickTeam( -1 );
				}
				BroadcastTeamChange( client, -1 );
			}
		}
	} else {
		value = Info_ValueForKey( userinfo, "team" );
		if ( value[0] == 's' ) {
			// a willing spectator, not a waiting-in-line
			sess->sessionTeam = TEAM_SPECTATOR;
		} else {
			switch ( g_gametype.integer ) {
			default:
			case GT_FFA:
			case GT_HOLOCRON:
			case GT_JEDIMASTER:
			case GT_SINGLE_PLAYER:
				if ( g_maxGameClients.integer > 0 && 
					level.numNonSpectatorClients >= g_maxGameClients.integer ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			case GT_DUEL:
				// if the game is full, go into a waiting mode
				if ( level.numNonSpectatorClients >= 2 ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			case GT_POWERDUEL:
				//sess->duelTeam = DUELTEAM_LONE; //default
				{
					int loners = 0;
					int doubles = 0;

					G_PowerDuelCount(&loners, &doubles, qtrue);

					if (!doubles || loners > (doubles/2))
					{
						sess->duelTeam = DUELTEAM_DOUBLE;
					}
					else
					{
						sess->duelTeam = DUELTEAM_LONE;
					}
				}
				sess->sessionTeam = TEAM_SPECTATOR;
				break;
			}
		}
	}

	sess->spectatorState = SPECTATOR_FREE;
	sess->spectatorTime = level.time;

	sess->siegeClass[0] = 0;
	sess->saberType[0] = 0;
	sess->saber2Type[0] = 0;

	G_WriteClientSessionData( client );
}
Пример #21
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
	char			*headmodel;
	char			userinfo[MAX_INFO_STRING];

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
                G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );

	if ( skill >= 1 && skill < 2 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	}
	else if ( skill >= 2 && skill < 3 ) {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	}
	else if ( skill >= 3 && skill < 4 ) {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	}

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "sarge/default";
	}
	Info_SetValueForKey( userinfo, key, model );
	key = "team_model";
	Info_SetValueForKey( userinfo, key, model );

	key = "headmodel";
	headmodel = Info_ValueForKey( botinfo, key );
	if ( !*headmodel ) {
		headmodel = model;
	}
	Info_SetValueForKey( userinfo, key, headmodel );
	key = "team_headmodel";
	Info_SetValueForKey( userinfo, key, headmodel );

	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "5";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s ) {
		trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" );
		return;
	}

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
                G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
                G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
                return;
	}

	// initialize the bot settings
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM && g_ffa_gt!=1) {
			if( PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "red";
		}
	}
	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
	Info_SetValueForKey( userinfo, "team", team );

	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	bot->inuse = qtrue;

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if( delay == 0 ) {
		ClientBegin( clientNum );
		return;
	}

	AddBotToSpawnQueue( clientNum, delay );
}
Пример #22
0
/*
=================
SetTeam
=================
*/
void SetTeam( gentity_t *ent, char *s ) {
	int					team, oldTeam;
	gclient_t			*client;
	int					clientNum;
	spectatorState_t	specState;
	int					specClient;
	int					teamLeader;

	//
	// see what change is requested
	//
	client = ent->client;

	clientNum = client - level.clients;
	specClient = 0;
	specState = SPECTATOR_NOT;
	if ( !Q_stricmp( s, "scoreboard" ) || !Q_stricmp( s, "score" )  ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_SCOREBOARD;
	} else if ( !Q_stricmp( s, "follow1" ) ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_FOLLOW;
		specClient = -1;
	} else if ( !Q_stricmp( s, "follow2" ) ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_FOLLOW;
		specClient = -2;
	} else if ( !Q_stricmp( s, "spectator" ) || !Q_stricmp( s, "s" ) ) {
		team = TEAM_SPECTATOR;
		specState = SPECTATOR_FREE;
	} else if ( g_gametype.integer >= GT_TEAM ) {
		// if running a team game, assign player to one of the teams
		specState = SPECTATOR_NOT;
		if ( !Q_stricmp( s, "red" ) || !Q_stricmp( s, "r" ) ) {
			team = TEAM_RED;
		} else if ( !Q_stricmp( s, "blue" ) || !Q_stricmp( s, "b" ) ) {
			team = TEAM_BLUE;
		} else {
			// pick the team with the least number of players
			team = PickTeam( clientNum );
		}

		if ( g_teamForceBalance.integer  ) {
			int		counts[TEAM_NUM_TEAMS];

			counts[TEAM_BLUE] = TeamCount( clientNum, TEAM_BLUE );
			counts[TEAM_RED] = TeamCount( clientNum, TEAM_RED );

			// We allow a spread of two
			if ( team == TEAM_RED && counts[TEAM_RED] - counts[TEAM_BLUE] > 1 ) {
				trap_SendServerCommand( clientNum, 
					"cp \"Red team has too many players.\n\"" );
				return; // ignore the request
			}
			if ( team == TEAM_BLUE && counts[TEAM_BLUE] - counts[TEAM_RED] > 1 ) {
				trap_SendServerCommand( clientNum, 
					"cp \"Blue team has too many players.\n\"" );
				return; // ignore the request
			}

			// It's ok, the team we are switching to has less or same number of players
		}

	} else {
		// force them to spectators if there aren't any spots free
		team = TEAM_FREE;
	}

	// override decision if limiting the players
	if ( (g_gametype.integer == GT_TOURNAMENT)
		&& level.numNonSpectatorClients >= 2 ) {
		team = TEAM_SPECTATOR;
	} else if ( g_maxGameClients.integer > 0 && 
		level.numNonSpectatorClients >= g_maxGameClients.integer ) {
		team = TEAM_SPECTATOR;
	}

	//
	// decide if we will allow the change
	//
	oldTeam = client->sess.sessionTeam;
	if ( team == oldTeam && team != TEAM_SPECTATOR ) {
		return;
	}

	//
	// execute the team change
	//

	// if the player was dead leave the body
	if ( client->ps.stats[STAT_HEALTH] <= 0 ) {
		CopyToBodyQue(ent);
	}

	// he starts at 'base'
	client->pers.teamState.state = TEAM_BEGIN;
	if ( oldTeam != TEAM_SPECTATOR ) {
		// Kill him (makes sure he loses flags, etc)
		ent->flags &= ~FL_GODMODE;
		ent->client->ps.stats[STAT_HEALTH] = ent->health = 0;
		player_die (ent, ent, ent, 100000, MOD_SUICIDE);

	}

	// they go to the end of the line for tournements
	if(team == TEAM_SPECTATOR && oldTeam != team)
		AddTournamentQueue(client);

	client->sess.sessionTeam = team;
	client->sess.spectatorState = specState;
	client->sess.spectatorClient = specClient;

	client->sess.teamLeader = qfalse;
	if ( team == TEAM_RED || team == TEAM_BLUE ) {
		teamLeader = TeamLeader( team );
		// if there is no team leader or the team leader is a bot and this client is not a bot
		if ( teamLeader == -1 || ( !(g_entities[clientNum].r.svFlags & SVF_BOT) && (g_entities[teamLeader].r.svFlags & SVF_BOT) ) ) {
			SetLeader( team, clientNum );
		}
	}
	// make sure there is a team leader on the team the player came from
	if ( oldTeam == TEAM_RED || oldTeam == TEAM_BLUE ) {
		CheckTeamLeader( oldTeam );
	}

	BroadcastTeamChange( client, oldTeam );

	// get and distribute relevent paramters
	ClientUserinfoChanged( clientNum );

	ClientBegin( clientNum );
}
Пример #23
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay ) {
	int clientNum;
	char            *botinfo;
	char            *key;
	char            *s;
	char            *botname;
	char            *model;
	char userinfo[MAX_INFO_STRING];

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
		G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" );
		G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
		return;
	}

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		trap_BotFreeClient( clientNum );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if ( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%.2f", skill) );

	if ( skill == 1 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	} else if ( skill == 2 )   {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	} else if ( skill == 3 )   {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	}

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "visor/default";
	}
	Info_SetValueForKey( userinfo, key, model );

	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey( botinfo, "aifile" );
	if ( !*s ) {
		trap_Print( S_COLOR_RED "Error: bot has no aifile specified\n" );
		trap_BotFreeClient( clientNum );
		return;
	}
	Info_SetValueForKey( userinfo, "characterfile", s );

	if ( !team || !*team ) {
		if ( g_gametype.integer == GT_TEAM || g_gametype.integer == GT_CTF ) {
			if ( PickTeam( clientNum ) == TEAM_RED ) {
				team = "red";
			} else {
				team = "blue";
			}
		} else {
			team = "red";
		}
	}
	Info_SetValueForKey( userinfo, "team", team );

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if ( delay == 0 ) {
		ClientBegin( clientNum );
		return;
	}

	AddBotToSpawnQueue( clientNum, delay );
}
Пример #24
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot(const char *name, float skill, const char *team, int delay, char *altname)
{
	int clientNum;
	char *botinfo;
	gentity_t *bot;
	char *s;
	char *botname;
	char *model;
	char *headmodel;
	char userinfo[MAX_INFO_STRING];
	weapon_t tpWeapon = WP_M4;
	holdable_t tpItem = HI_LASER;

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName(name);
	if (!botinfo) {
		G_Printf(S_COLOR_RED "Error: Bot '%s' not defined\n", name);
		return;
	}
	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey(botinfo, "funname");
	if (!botname[0]) {
		botname = Info_ValueForKey(botinfo, "name");
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey(userinfo, "name", botname);
	Info_SetValueForKey(userinfo, "rate", "25000");
	Info_SetValueForKey(userinfo, "snaps", "20");
	Info_SetValueForKey(userinfo, "skill", va("%1.2f", skill));

	if (skill >= 1 && skill < 2) {
		Info_SetValueForKey(userinfo, "handicap", "50");
	} else if (skill >= 2 && skill < 3) {
		Info_SetValueForKey(userinfo, "handicap", "70");
	} else if (skill >= 3 && skill < 4) {
		Info_SetValueForKey(userinfo, "handicap", "90");
	}

	model = Info_ValueForKey(botinfo, "model");
	if (!*model) {
		// Elder: changed to our default
		model = "reactionmale/default";
	}

	Info_SetValueForKey(userinfo, "model", model);

	Info_SetValueForKey(userinfo, "team_model", model);

	headmodel = Info_ValueForKey(botinfo, "headmodel");
	if (!*headmodel) {
		headmodel = model;
	}
	Info_SetValueForKey(userinfo, "headmodel", headmodel);

	Info_SetValueForKey(userinfo, "team_headmodel", headmodel);

	s = Info_ValueForKey(botinfo, "gender");
	if (!*s) {
		s = "male";
	}
	Info_SetValueForKey(userinfo, "sex", s);

	s = Info_ValueForKey(botinfo, "color1");
	if (!*s) {
		s = "4";
	}
	Info_SetValueForKey(userinfo, "color1", s);

	s = Info_ValueForKey(botinfo, "color2");
	if (!*s) {
		s = "5";
	}
	Info_SetValueForKey(userinfo, "color2", s);

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s) {
		trap_Printf(S_COLOR_RED "Error: bot has no aifile specified\n");
		return;
	}
	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if (clientNum == -1) {
		G_Printf(S_COLOR_RED "Unable to add bot.  All player slots are in use.\n");
		G_Printf(S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n");
		return;
	}
	// initialize the bot settings
	if (!team || !*team) {
		if (g_gametype.integer >= GT_TEAM) {
			if (PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			} else {
				team = "blue";
			}
		} else {
			team = "red";
		}
	}
	Info_SetValueForKey(userinfo, "characterfile", Info_ValueForKey(botinfo, "aifile"));
	Info_SetValueForKey(userinfo, "skill", va("%5.2f", skill));
	Info_SetValueForKey(userinfo, "team", team);

	if (g_gametype.integer == GT_TEAMPLAY) {
		//Makro - load custom weapon/item from bot file
		tpWeapon = CharToWeapon(Info_ValueForKey(botinfo, "weapon"), WP_M4);
		tpItem = CharToItem(Info_ValueForKey(botinfo, "item"), HI_LASER);
	}
	Info_SetValueForKey(userinfo, "tpw", va("%i", tpWeapon - WP_NONE));
	Info_SetValueForKey(userinfo, "tpi", va("%i", tpItem - HI_NONE));

	bot = &g_entities[clientNum];
	bot->r.svFlags |= SVF_BOT;
	bot->inuse = qtrue;

	// register the userinfo
	trap_SetUserinfo(clientNum, userinfo);

	// have it connect to the game as a normal client
	if (ClientConnect(clientNum, qtrue, qtrue)) {
		return;
	}

	if (delay == 0) {
		ClientBegin(clientNum);
		//Makro - load custom weapon/item from bot file
		if (g_gametype.integer == GT_TEAMPLAY) {
			bot->client->teamplayWeapon = tpWeapon;
			bot->client->teamplayItem = tpItem;
		}
		return;
	}

	AddBotToSpawnQueue(clientNum, delay);

	//Makro - load custom weapon/item from bot file
	if (g_gametype.integer == GT_TEAMPLAY) {
		bot->client->teamplayWeapon = tpWeapon;
		bot->client->teamplayItem = tpItem;
	}
}
Пример #25
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, const char *pclass, int delay, char *altname) {
	int				clientNum;
	char			*botinfo;
	gentity_t		*bot;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
	char			userinfo[MAX_INFO_STRING];
	int				preTeam = 0;

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );

/*	if ( skill >= 1 && skill < 2 ) {
		Info_SetValueForKey( userinfo, "handicap", "50" );
	}
	else if ( skill >= 2 && skill < 3 ) {
		Info_SetValueForKey( userinfo, "handicap", "70" );
	}
	else if ( skill >= 3 && skill < 4 ) {
		Info_SetValueForKey( userinfo, "handicap", "90" );
	} */

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "munro/main/default"; //RPG-X MODEL SYSTEM
	}
	Info_SetValueForKey( userinfo, key, model );

	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s ) {
		trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" );
		return;
	}

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
		G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
		G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
		return;
	}

	// initialize the bot settings
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM ) {
			if( PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "red";
		}
	}
	Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
	Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
	Info_SetValueForKey( userinfo, "team", team );

	bot = &g_entities[ clientNum ];
	bot->r.svFlags |= SVF_BOT;
	bot->inuse = qtrue;

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	if (g_gametype.integer >= GT_TEAM)
	{
		if (team && Q_stricmp(team, "red") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_RED;
		}
		else if (team && Q_stricmp(team, "blue") == 0)
		{
			bot->client->sess.sessionTeam = TEAM_BLUE;
		}
		else
		{
			bot->client->sess.sessionTeam = PickTeam( -1 );
		}
	}

	preTeam = bot->client->sess.sessionTeam;

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if (bot->client->sess.sessionTeam != preTeam)
	{
		trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING);

		if (bot->client->sess.sessionTeam == TEAM_SPECTATOR)
		{
			bot->client->sess.sessionTeam = preTeam;
		}

		if (bot->client->sess.sessionTeam == TEAM_RED)
		{
			team = "Red";
		}
		else
		{
			team = "Blue";
		}

		Info_SetValueForKey( userinfo, "team", team );

		trap_SetUserinfo( clientNum, userinfo );

		bot->client->ps.persistant[ PERS_TEAM ] = bot->client->sess.sessionTeam;

		G_ReadSessionData( bot->client );
		ClientUserinfoChanged( clientNum );
	}

	if( delay == 0 ) {
		ClientBegin( clientNum, qfalse, qfalse, qfalse );
		return;
	}

	AddBotToSpawnQueue( clientNum, delay );
}
Пример #26
0
/*
================
G_InitSessionData

Called on a first-time connect
================
*/
void G_InitSessionData( gclient_t *client, char *userinfo, qboolean isBot ) {
	clientSession_t	*sess;
	const char		*value;
	int				clientNum;

	sess = &client->sess;
	clientNum = client - level.clients;

	// initial team determination
	if ( GT_Team(g_gametype.integer) ) {
		if ( g_teamAutoJoin.integer ) {
			sess->sessionTeam = PickTeam( -1 );
		} else {
			// always spawn as spectator in team games
			if (!isBot)
			{
				sess->sessionTeam = TEAM_SPECTATOR;
			}
			else
			{ //Bots choose their team on creation
				value = Info_ValueForKey( userinfo, "team" );
				if (value[0] == 'r' || value[0] == 'R')
				{
					sess->sessionTeam = ValidateTeam( -1, TEAM_RED ) ?
						TEAM_RED : TEAM_SPECTATOR;
				}
				else if (value[0] == 'b' || value[0] == 'B')
				{
					sess->sessionTeam = ValidateTeam( -1, TEAM_BLUE ) ?
						TEAM_BLUE : TEAM_SPECTATOR;
				}
				else
				{
					sess->sessionTeam = PickTeam( -1 );
				}
			}
		}
	} else {
		value = Info_ValueForKey( userinfo, "team" );
		if ( value[0] == 's' ) {
			// a willing spectator, not a waiting-in-line
			sess->sessionTeam = TEAM_SPECTATOR;
		} else {
			switch ( g_gametype.integer ) {
			default:
			case GT_FFA:
			case GT_HOLOCRON:
			case GT_JEDIMASTER:
			case GT_SINGLE_PLAYER:
				sess->sessionTeam = ValidateTeam( clientNum, TEAM_FREE ) ?
					TEAM_FREE : TEAM_SPECTATOR;
				break;
			case GT_TOURNAMENT:
				// if the game is full, go into a waiting mode
				if ( level.numNonSpectatorClients >= 2 ) {
					sess->sessionTeam = TEAM_SPECTATOR;
				} else {
					sess->sessionTeam = TEAM_FREE;
				}
				break;
			}
		}
	}

	if ( sess->sessionTeam == TEAM_SPECTATOR )
		sess->spectatorState = SPECTATOR_FREE;
	else if ( level.round > 0 && g_gametype.integer != GT_REDROVER )
		sess->spectatorState = SPECTATOR_FREE;
	else
		sess->spectatorState = SPECTATOR_NOT;

	sess->spectatorTime = level.time;

	G_WriteClientSessionData( client );
}
Пример #27
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
	gentity_t		*bot = NULL;
	int				clientNum, preTeam = TEAM_FREE;
	char			userinfo[MAX_INFO_STRING] = {0},
					*botinfo = NULL, *key = NULL, *s = NULL, *botname = NULL, *model = NULL;

	// have the server allocate a client slot
	clientNum = trap->BotAllocateClient();
	if ( clientNum == -1 ) {
//		trap->Print( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
//		trap->Print( S_COLOR_RED "Start server with more 'open' slots.\n" );
		trap->SendServerCommand( -1, va("print \"%s\n\"", G_GetStringEdString("MP_SVGAME", "UNABLE_TO_ADD_BOT")));
		return;
	}

	// get the botinfo from bots.txt
	botinfo = G_GetBotInfoByName( name );
	if ( !botinfo ) {
		trap->BotFreeClient( clientNum );
		trap->Print( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] )
		botname = Info_ValueForKey( botinfo, "name" );
	// check for an alternative name
	if ( altname && altname[0] )
		botname = altname;

	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "ip", "localhost" );
	Info_SetValueForKey( userinfo, "skill", va("%.2f", skill) );

		 if ( skill >= 1 && skill < 2 )		Info_SetValueForKey( userinfo, "handicap", "50" );
	else if ( skill >= 2 && skill < 3 )		Info_SetValueForKey( userinfo, "handicap", "70" );
	else if ( skill >= 3 && skill < 4 )		Info_SetValueForKey( userinfo, "handicap", "90" );
	else									Info_SetValueForKey( userinfo, "handicap", "100" );

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model )	model = DEFAULT_MODEL"/default";
	Info_SetValueForKey( userinfo, key, model );

	key = "sex";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = Info_ValueForKey( botinfo, "gender" );
	if ( !*s )	s = "male";
	Info_SetValueForKey( userinfo, key, s );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = "4";
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = "4";
	Info_SetValueForKey( userinfo, key, s );

	key = "saber1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = DEFAULT_SABER;
	Info_SetValueForKey( userinfo, key, s );

	key = "saber2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = "none";
	Info_SetValueForKey( userinfo, key, s );

	key = "forcepowers";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = DEFAULT_FORCEPOWERS;
	Info_SetValueForKey( userinfo, key, s );

	key = "cg_predictItems";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = "1";
	Info_SetValueForKey( userinfo, key, s );

	key = "char_color_red";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = "255";
	Info_SetValueForKey( userinfo, key, s );

	key = "char_color_green";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = "255";
	Info_SetValueForKey( userinfo, key, s );

	key = "char_color_blue";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = "255";
	Info_SetValueForKey( userinfo, key, s );

	key = "teamtask";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = "0";
	Info_SetValueForKey( userinfo, key, s );

	key = "personality";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s )	s = "botfiles/default.jkb";
	Info_SetValueForKey( userinfo, key, s );

	// initialize the bot settings
	if ( !team || !*team ) {
		if ( level.gametype >= GT_TEAM ) {
			if ( PickTeam( clientNum ) == TEAM_RED)
				team = "red";
			else
				team = "blue";
		}
		else
			team = "red";
	}
	Info_SetValueForKey( userinfo, "team", team );

	bot = &g_entities[ clientNum ];
//	bot->r.svFlags |= SVF_BOT;
//	bot->inuse = qtrue;

	// register the userinfo
	trap->SetUserinfo( clientNum, userinfo );

	if ( level.gametype >= GT_TEAM )
	{
		if ( team && !Q_stricmp( team, "red" ) )
			bot->client->sess.sessionTeam = TEAM_RED;
		else if ( team && !Q_stricmp( team, "blue" ) )
			bot->client->sess.sessionTeam = TEAM_BLUE;
		else
			bot->client->sess.sessionTeam = PickTeam( -1 );
	}

	if ( level.gametype == GT_SIEGE )
	{
		bot->client->sess.siegeDesiredTeam = bot->client->sess.sessionTeam;
		bot->client->sess.sessionTeam = TEAM_SPECTATOR;
	}

	preTeam = bot->client->sess.sessionTeam;

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) )
		return;

	if ( bot->client->sess.sessionTeam != preTeam )
	{
		trap->GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );

		if ( bot->client->sess.sessionTeam == TEAM_SPECTATOR )
			bot->client->sess.sessionTeam = preTeam;

		if ( bot->client->sess.sessionTeam == TEAM_RED )
			team = "Red";
		else
		{
			if ( level.gametype == GT_SIEGE )
				team = (bot->client->sess.sessionTeam == TEAM_BLUE) ? "Blue" : "s";
			else
				team = "Blue";
		}

		Info_SetValueForKey( userinfo, "team", team );

		trap->SetUserinfo( clientNum, userinfo );

		bot->client->ps.persistant[ PERS_TEAM ] = bot->client->sess.sessionTeam;

		G_ReadSessionData( bot->client );
		if ( !ClientUserinfoChanged( clientNum ) )
			return;
	}

	if (level.gametype == GT_DUEL ||
		level.gametype == GT_POWERDUEL)
	{
		int loners = 0;
		int doubles = 0;

		bot->client->sess.duelTeam = 0;
		G_PowerDuelCount(&loners, &doubles, qtrue);

		if (!doubles || loners > (doubles/2))
		{
            bot->client->sess.duelTeam = DUELTEAM_DOUBLE;
		}
		else
		{
            bot->client->sess.duelTeam = DUELTEAM_LONE;
		}

		bot->client->sess.sessionTeam = TEAM_SPECTATOR;
		SetTeam(bot, "s");
	}
	else
	{
		if( delay == 0 ) {
			ClientBegin( clientNum, qfalse );
			return;
		}

		AddBotToSpawnQueue( clientNum, delay );
	}
}
Пример #28
0
/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
	int				clientNum;
	int				teamNum;
	int				botinfoNum;
	char			*botinfo;
	char			*key;
	char			*s;
	char			*botname;
	char			*model;
	char			*headmodel;
	char			userinfo[MAX_INFO_STRING];

	// have the server allocate a client slot
	clientNum = trap_BotAllocateClient();
	if ( clientNum == -1 ) {
		G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" );
		G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
		return;
	}

	// set default team
	if( !team || !*team ) {
		if( g_gametype.integer >= GT_TEAM ) {
			if( PickTeam(clientNum) == TEAM_RED) {
				team = "red";
			}
			else {
				team = "blue";
			}
		}
		else {
			team = "free";
		}
	}

	// get the botinfo from bots.txt
	if ( Q_stricmp( name, "random" ) == 0 ) {
		if ( Q_stricmp( team, "red" ) == 0 || Q_stricmp( team, "r" ) == 0 ) {
			teamNum = TEAM_RED;
		}
		else if ( Q_stricmp( team, "blue" ) == 0 || Q_stricmp( team, "b" ) == 0 ) {
			teamNum = TEAM_BLUE;
		}
		else if ( !Q_stricmp( team, "spectator" ) || !Q_stricmp( team, "s" ) ) {
			teamNum = TEAM_SPECTATOR;
		}
		else {
			teamNum = TEAM_FREE;
		}

		botinfoNum = G_SelectRandomBotInfo( teamNum );

		if ( botinfoNum < 0 ) {
			G_Printf( S_COLOR_RED "Error: Cannot add random bot, no bot info available.\n" );
			trap_BotFreeClient( clientNum );
			return;
		}

		botinfo = G_GetBotInfoByNumber( botinfoNum );
	}
	else {
		botinfo = G_GetBotInfoByName( name );
	}

	if ( !botinfo ) {
		G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
		trap_BotFreeClient( clientNum );
		return;
	}

	// create the bot's userinfo
	userinfo[0] = '\0';

	botname = Info_ValueForKey( botinfo, "funname" );
	if( !botname[0] ) {
		botname = Info_ValueForKey( botinfo, "name" );
	}
	// check for an alternative name
	if (altname && altname[0]) {
		botname = altname;
	}
	Info_SetValueForKey( userinfo, "name", botname );
	Info_SetValueForKey( userinfo, "rate", "25000" );
	Info_SetValueForKey( userinfo, "snaps", "20" );
	Info_SetValueForKey( userinfo, "skill", va("%.2f", skill) );
	Info_SetValueForKey( userinfo, "teampref", team );

	key = "model";
	model = Info_ValueForKey( botinfo, key );
	if ( !*model ) {
		model = "visor/default";
	}
	Info_SetValueForKey( userinfo, key, model );
	key = "team_model";
	Info_SetValueForKey( userinfo, key, model );

	key = "headmodel";
	headmodel = Info_ValueForKey( botinfo, key );
	if ( !*headmodel ) {
		headmodel = model;
	}
	Info_SetValueForKey( userinfo, key, headmodel );
	key = "team_headmodel";
	Info_SetValueForKey( userinfo, key, headmodel );

	key = "gender";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "male";
	}
	Info_SetValueForKey( userinfo, "sex", s );

	key = "color1";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "4";
	}
	Info_SetValueForKey( userinfo, key, s );

	key = "color2";
	s = Info_ValueForKey( botinfo, key );
	if ( !*s ) {
		s = "5";
	}
	Info_SetValueForKey( userinfo, key, s );

	s = Info_ValueForKey(botinfo, "aifile");
	if (!*s ) {
		trap_Print( S_COLOR_RED "Error: bot has no aifile specified\n" );
		trap_BotFreeClient( clientNum );
		return;
	}
	Info_SetValueForKey( userinfo, "characterfile", s );

	// don't send tinfo to bots, they don't parse it
	Info_SetValueForKey( userinfo, "teamoverlay", "0" );

	// register the userinfo
	trap_SetUserinfo( clientNum, userinfo );

	// have it connect to the game as a normal client
	if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
		return;
	}

	if( delay == 0 ) {
		ClientBegin( clientNum );
		return;
	}

	AddBotToSpawnQueue( clientNum, delay );
}
Пример #29
0
//[ExpSys]
//added firsttime input so we'll know if we need to reset our skill point totals or not.
void G_InitSessionData( gclient_t *client, char *userinfo, qboolean isBot, qboolean firstTime) {
//void G_InitSessionData( gclient_t *client, char *userinfo, qboolean isBot ) {
//[/ExpSys]
    clientSession_t	*sess;
    const char		*value;

    sess = &client->sess;

    client->sess.siegeDesiredTeam = TEAM_FREE;

    // initial team determination
    //[CoOp]
    //CoOp counts as a multi-team game.
    if ( g_gametype.integer >= GT_SINGLE_PLAYER) {
        //if ( g_gametype.integer >= GT_TEAM ) {
        //[/CoOp]
        if ( g_teamAutoJoin.integer )
        {
            //[AdminSys]
            sess->sessionTeam = PickTeam( -1, isBot );
            //sess->sessionTeam = PickTeam( -1 );
            //[/AdminSys]
            BroadcastTeamChange( client, -1 );
        }
        else
        {
            // always spawn as spectator in team games
            if (!isBot)
            {
                sess->sessionTeam = TEAM_SPECTATOR;
            }
            else
            {   //Bots choose their team on creation
                value = Info_ValueForKey( userinfo, "team" );
                if (value[0] == 'r' || value[0] == 'R')
                {
                    sess->sessionTeam = TEAM_RED;
                }
                else if (value[0] == 'b' || value[0] == 'B')
                {
                    sess->sessionTeam = TEAM_BLUE;
                }
                else
                {
                    //[AdminSys]
                    sess->sessionTeam = PickTeam( -1, isBot );
                    //sess->sessionTeam = PickTeam( -1 );
                    //[/AdminSys]
                }
                BroadcastTeamChange( client, -1 );
            }
        }
    } else {
        value = Info_ValueForKey( userinfo, "team" );
        if ( value[0] == 's' ) {
            // a willing spectator, not a waiting-in-line
            sess->sessionTeam = TEAM_SPECTATOR;
        } else {
            switch ( g_gametype.integer ) {
            default:
            case GT_FFA:
            case GT_HOLOCRON:
            case GT_JEDIMASTER:
                //[CoOp]
                //CoOp counts as a multi-team game.
                //case GT_SINGLE_PLAYER:
                //[/CoOp]
                if ( g_maxGameClients.integer > 0 &&
                        level.numNonSpectatorClients >= g_maxGameClients.integer ) {
                    sess->sessionTeam = TEAM_SPECTATOR;
                } else {
                    sess->sessionTeam = TEAM_FREE;
                }
                break;
            case GT_DUEL:
                // if the game is full, go into a waiting mode
                if ( level.numNonSpectatorClients >= 2 ) {
                    sess->sessionTeam = TEAM_SPECTATOR;
                } else {
                    sess->sessionTeam = TEAM_FREE;
                }
                break;
            case GT_POWERDUEL:
                //sess->duelTeam = DUELTEAM_LONE; //default
            {
                int loners = 0;
                int doubles = 0;

                G_PowerDuelCount(&loners, &doubles, qtrue);

                if (!doubles || loners > (doubles/2))
                {
                    sess->duelTeam = DUELTEAM_DOUBLE;
                }
                else
                {
                    sess->duelTeam = DUELTEAM_LONE;
                }
            }
            sess->sessionTeam = TEAM_SPECTATOR;
            break;
            }
        }
    }

    sess->spectatorState = SPECTATOR_FREE;
    sess->spectatorTime = level.time;

    sess->siegeClass[0] = 0;
    sess->saberType[0] = 0;
    sess->saber2Type[0] = 0;

    //[ExpSys]
    //[OpenRP - Skillpoint System]
    if(firstTime)
    {   //only reset skillpoints for new players.
        sess->IP[0] = 0;
        sess->skillPoints = 1;
        sess->adminLevel = 11;
        sess->radioOn = qtrue;
    }
    //[/OpenRP - Skillpoint System]
    else
    {   //remember the data from the last time.
        char	s[MAX_STRING_CHARS];
        const char	*var;
        int tempInt;
        char tempChar[64];

        var = va( "session%i", client - level.clients );
        trap_Cvar_VariableStringBuffer( var, s, sizeof(s) );
        //[ExpSys]
        sscanf( s, "%i %i %i %i %i %i %i %i %i %i %i %i %s %s %s %i %i %i %i %i %i %i %s %i",
                //sscanf( s, "%i %i %i %i %i %i %i %i %i %i %i %i %s %s %s",
                //[ExpSys]
                &tempInt,                 // bk010221 - format
                &tempInt,
                &tempInt,              // bk010221 - format
                &tempInt,
                &tempInt,
                &tempInt,
                &tempInt,                   // bk010221 - format
                &tempInt,
                &tempInt,
                &tempInt,
                &tempInt,
                &tempInt,
                &tempChar,
                &tempChar,
                &tempChar,
                &client->sess.skillPoints,
                //[OpenRP - account and character, other systems & IP]
                &client->sess.accountID,
                &client->sess.loggedinAccount,
                &client->sess.characterChosen,
                &client->sess.characterID,
                &client->sess.warnings,
                &client->sess.modelScale,
                &client->sess.IP,
                &client->sess.ojpClientPlugIn
                //[/OpenRP - account and character, other systems & IP]
              );
    }
    //[/ExpSys]

    G_WriteClientSessionData( client );
}