示例#1
0
文件: g_cmds.c 项目: j0ki/racesow
qboolean CheckFlood( edict_t *ent, qboolean teamonly )
{
	int i;
	gclient_t *client = ent->r.client;

	assert( ent && client );

	if( g_floodprotection_messages->modified )
	{
		if( g_floodprotection_messages->integer < 0 )
			trap_Cvar_Set( "g_floodprotection_messages", "0" );
		if( g_floodprotection_messages->integer > MAX_FLOOD_MESSAGES )
			trap_Cvar_Set( "g_floodprotection_messages", va( "%i", MAX_FLOOD_MESSAGES ) );
		g_floodprotection_messages->modified = qfalse;
	}

	if( g_floodprotection_team->modified )
	{
		if( g_floodprotection_team->integer < 0 )
			trap_Cvar_Set( "g_floodprotection_team", "0" );
		if( g_floodprotection_team->integer > MAX_FLOOD_MESSAGES )
			trap_Cvar_Set( "g_floodprotection_team", va( "%i", MAX_FLOOD_MESSAGES ) );
		g_floodprotection_team->modified = qfalse;
	}

	if( g_floodprotection_seconds->modified )
	{
		if( g_floodprotection_seconds->value <= 0 )
			trap_Cvar_Set( "g_floodprotection_seconds", "4" );
		g_floodprotection_seconds->modified = qfalse;
	}

	if( g_floodprotection_penalty->modified )
	{
		if( g_floodprotection_penalty->value < 0 )
			trap_Cvar_Set( "g_floodprotection_penalty", "10" );
		g_floodprotection_penalty->modified = qfalse;
	}

	// old protection still active
	if( !teamonly || g_floodprotection_team->integer )
	{
		if( game.realtime < client->level.flood_locktill )
		{
			G_PrintMsg( ent, "You can't talk for %d more seconds\n",
				(int)( ( client->level.flood_locktill - game.realtime ) / 1000.0f ) + 1 );
			return qtrue;
		}
	}


	if( teamonly )
	{
		if( g_floodprotection_team->integer && g_floodprotection_penalty->value > 0 )
		{
			i = client->level.flood_team_whenhead - g_floodprotection_team->integer + 1;
			if( i < 0 )
				i = MAX_FLOOD_MESSAGES + i;

			if( client->level.flood_team_when[i] && client->level.flood_team_when[i] <= game.realtime &&
				( game.realtime < client->level.flood_team_when[i] + g_floodprotection_seconds->integer * 1000 ) )
			{
				client->level.flood_locktill = game.realtime + g_floodprotection_penalty->value * 1000;
				G_PrintMsg( ent, "Flood protection: You can't talk for %d seconds.\n", g_floodprotection_penalty->integer );
				return qtrue;
			}
		}

		client->level.flood_team_whenhead = ( client->level.flood_team_whenhead + 1 ) % MAX_FLOOD_MESSAGES;
		client->level.flood_team_when[client->level.flood_team_whenhead] = game.realtime;
	}
	else
	{
		if( g_floodprotection_messages->integer && g_floodprotection_penalty->value > 0 )
		{
			i = client->level.flood_whenhead - g_floodprotection_messages->integer + 1;
			if( i < 0 )
				i = MAX_FLOOD_MESSAGES + i;

			if( client->level.flood_when[i] && client->level.flood_when[i] <= game.realtime &&
				( game.realtime < client->level.flood_when[i] + g_floodprotection_seconds->integer * 1000 ) )
			{
				client->level.flood_locktill = game.realtime + g_floodprotection_penalty->value * 1000;
				G_PrintMsg( ent, "Flood protection: You can't talk for %d seconds.\n", g_floodprotection_penalty->integer );
				return qtrue;
			}
		}

		client->level.flood_whenhead = ( client->level.flood_whenhead + 1 ) % MAX_FLOOD_MESSAGES;
		client->level.flood_when[client->level.flood_whenhead] = game.realtime;
	}

	return qfalse;
}
示例#2
0
/*
* Cmd_ChaseCam_f
*/
void Cmd_ChaseCam_f( edict_t *ent )
{
	bool team_only;
	const char *arg1;

	if( ent->s.team != TEAM_SPECTATOR && !ent->r.client->teamstate.is_coach )
	{
		// racesow - changed from G_Teams_JoinTeam( ent, TEAM_SPECTATOR ) as this makes
		// a second G_ChasePlayer call with followmode 0, thereby overriding the chasecam mode set here
		ent->r.client->team = TEAM_SPECTATOR;
		G_ClientRespawn( ent, true );
		// !racesow
		if( !CheckFlood( ent, false )) { // prevent 'joined spectators' spam
			G_PrintMsg( NULL, "%s%s joined the %s%s team.\n", ent->r.client->netname,
				S_COLOR_WHITE, GS_TeamName( ent->s.team ), S_COLOR_WHITE );
		}
	}

	// & 1 = scorelead
	// & 2 = powerups
	// & 4 = objectives
	// & 8 = fragger

	if( ent->r.client->teamstate.is_coach && GS_TeamBasedGametype() )
		team_only = true;
	else 
		team_only = false;

	arg1 = trap_Cmd_Argv( 1 );

	if( trap_Cmd_Argc() < 2 )
	{
		G_ChasePlayer( ent, NULL, team_only, 0 );
	}
	else if( !Q_stricmp( arg1, "auto" ) )
	{
		G_PrintMsg( ent, "Chasecam mode is 'auto'. It will follow the score leader when no powerup nor flag is carried.\n" );
		G_ChasePlayer( ent, NULL, team_only, 7 );
	}
	else if( !Q_stricmp( arg1, "carriers" ) )
	{
		G_PrintMsg( ent, "Chasecam mode is 'carriers'. It will switch to flag or powerup carriers when any of these items is picked up.\n" );
		G_ChasePlayer( ent, NULL, team_only, 6 );
	}
	else if( !Q_stricmp( arg1, "powerups" ) )
	{
		G_PrintMsg( ent, "Chasecam mode is 'powerups'. It will switch to powerup carriers when any of these items is picked up.\n" );
		G_ChasePlayer( ent, NULL, team_only, 2 );
	}
	else if( !Q_stricmp( arg1, "objectives" ) )
	{
		G_PrintMsg( ent, "Chasecam mode is 'objectives'. It will switch to objectives carriers when any of these items is picked up.\n" );
		G_ChasePlayer( ent, NULL, team_only, 4 );
	}
	else if( !Q_stricmp( arg1, "score" ) )
	{
		G_PrintMsg( ent, "Chasecam mode is 'score'. It will always follow the player with the best score.\n" );
		G_ChasePlayer( ent, NULL, team_only, 1 );
	}
	else if( !Q_stricmp( arg1, "fragger" ) )
	{
		G_PrintMsg( ent, "Chasecam mode is 'fragger'. The last fragging player will be followed.\n" );
		G_ChasePlayer( ent, NULL, team_only, 8 );
	}
	else if( !Q_stricmp( arg1, "help" ) )
	{
		G_PrintMsg( ent, "Chasecam modes:\n" );
		G_PrintMsg( ent, "- 'auto': Chase the score leader unless there's an objective carrier or a powerup carrier.\n" );
		G_PrintMsg( ent, "- 'carriers': User has pov control unless there's an objective carrier or a powerup carrier.\n" );
		G_PrintMsg( ent, "- 'objectives': User has pov control unless there's an objective carrier.\n" );
		G_PrintMsg( ent, "- 'powerups': User has pov control unless there's a flag carrier.\n" );
		G_PrintMsg( ent, "- 'score': Always follow the score leader. User has no pov control.\n" );
		G_PrintMsg( ent, "- 'none': Disable chasecam.\n" );
		return;
	}
	else
	{
		G_ChasePlayer( ent, arg1, team_only, 0 );
	}

	G_Teams_LeaveChallengersQueue( ent );
}
示例#3
0
文件: g_cmds.c 项目: j0ki/racesow
/*
* Cmd_Position_f
*/
static void Cmd_Position_f( edict_t *ent )
{
	char *action;

	if( !sv_cheats->integer && GS_MatchState() > MATCH_STATE_WARMUP &&
		ent->r.client->ps.pmove.pm_type != PM_SPECTATOR )
	{
		G_PrintMsg( ent, "Position command is only available in warmup and in spectator mode.\n" );
		return;
	}

	// flood protect
	if( ent->r.client->teamstate.position_lastcmd + 500 > game.realtime )
		return;
	ent->r.client->teamstate.position_lastcmd = game.realtime;

	action = trap_Cmd_Argv( 1 );

	if( !Q_stricmp( action, "save" ) )
	{
		ent->r.client->teamstate.position_saved = qtrue;
		VectorCopy( ent->s.origin, ent->r.client->teamstate.position_origin );
		VectorCopy( ent->s.angles, ent->r.client->teamstate.position_angles );
		G_PrintMsg( ent, "Position saved.\n" );
	}
	else if( !Q_stricmp( action, "load" ) )
	{
		if( !ent->r.client->teamstate.position_saved )
		{
			G_PrintMsg( ent, "No position saved.\n" );
		}
		else
		{
			if( ent->r.client->resp.chase.active )
				G_SpectatorMode( ent );

			if( G_Teleport( ent, ent->r.client->teamstate.position_origin, ent->r.client->teamstate.position_angles ) )
				G_PrintMsg( ent, "Position loaded.\n" );
			else
				G_PrintMsg( ent, "Position not available.\n" );
		}
	}
	else if( !Q_stricmp( action, "set" ) && trap_Cmd_Argc() == 7 )
	{
		vec3_t origin, angles;
		int i, argnumber = 2;

		for( i = 0; i < 3; i++ )
			origin[i] = atof( trap_Cmd_Argv( argnumber++ ) );
		for( i = 0; i < 2; i++ )
			angles[i] = atof( trap_Cmd_Argv( argnumber++ ) );
		angles[2] = 0;

		if( ent->r.client->resp.chase.active )
			G_SpectatorMode( ent );

		if( G_Teleport( ent, origin, angles ) )
			G_PrintMsg( ent, "Position not available.\n" );
		else
			G_PrintMsg( ent, "Position set.\n" );
	}
	else
	{
		char msg[MAX_STRING_CHARS];

		msg[0] = 0;
		Q_strncatz( msg, "Usage:\nposition save - Save current position\n", sizeof( msg ) );
		Q_strncatz( msg, "position load - Teleport to saved position\n", sizeof( msg ) );
		Q_strncatz( msg, "position set <x> <y> <z> <pitch> <yaw> - Teleport to specified position\n", sizeof( msg ) );
		Q_strncatz( msg, va( "Current position: %.4f %.4f %.4f %.4f %.4f\n", ent->s.origin[0], ent->s.origin[1],
			ent->s.origin[2], ent->s.angles[0], ent->s.angles[1] ), sizeof( msg ) );
		G_PrintMsg( ent, msg );
	}
}
示例#4
0
/*
* G_MoveClientToTV
*
* Sends cmd to connect to a non-full TV server with round robin balancing
*/
void G_MoveClientToTV( edict_t *ent )
{
	int i;
	gclient_t *client, *best;
	static int last_tv = 0;
	bool isIPv6;
	char ip[MAX_INFO_VALUE];
	int port;
	const char *p;

	if( !ent->r.client ) {
		return;
	}
	if( ent->r.svflags & SVF_FAKECLIENT ) {
		return;
	}
	if( ent->r.client->isTV ) {
		return;
	}

	best = NULL;
	for( i = 0; i < gs.maxclients; i++ ) {
		client = &game.clients[(last_tv + 1 + i) % gs.maxclients];
		if( !client->isTV || client->connecting ) {
			// not a TV or not ready yet
			continue;
		}
		if( client->tv.numclients == client->tv.maxclients ) {
			// full
			continue;
		}
		if( !client->tv.channel ) {
			// invalid userinfo/channel number
			continue;
		}
		best = client;
		break;
	}

	if( !best ) {
		G_PrintMsg( ent, "Could not find a free TV server\n" );
		return;
	}

	Q_strncpyz( ip, best->ip, sizeof( ip ) );

	// check IP type
	p = strstr( ip, "::" );
	isIPv6 = p != NULL;

	// strip port number from address string
	p = strrchr( ip, ':' );
	if( p != NULL ) {
		ip[p - ip] = '\0';
	}

	port = isIPv6 ? best->tv.port6 : best->tv.port;

	last_tv = best - game.clients;
	trap_GameCmd( ent, va( "memo tv_moveto \"%s\" %s:%hu#%i", COM_RemoveColorTokens( best->netname ), ip, port, best->tv.channel ) );
}
示例#5
0
/*
* G_ChasePlayer
*/
void G_ChasePlayer( edict_t *ent, const char *name, bool teamonly, int followmode )
{
	int i;
	edict_t *e;
	gclient_t *client;
	int targetNum = -1;
	int oldTarget;
	bool can_follow = true;
	char colorlessname[MAX_NAME_BYTES];

	client = ent->r.client;

	oldTarget = client->resp.chase.target;

	if( teamonly && !client->teamstate.is_coach )
		can_follow = false;

	if( !can_follow && followmode )
	{
		G_PrintMsg( ent, "Chasecam follow mode unavailable\n" );
		followmode = false;
	}

	if( ent->r.client->resp.chase.followmode && !followmode )
		G_PrintMsg( ent, "Disabling chasecam follow mode\n" );

	// always disable chasing as a start
	memset( &client->resp.chase, 0, sizeof( chasecam_t ) );

	// locate the requested target
	if( name && name[0] )
	{
		// find it by player names
		for( e = game.edicts + 1; PLAYERNUM( e ) < gs.maxclients; e++ )
		{
			if( !G_Chase_IsValidTarget( ent, e, teamonly ) )
				continue;

			Q_strncpyz( colorlessname, COM_RemoveColorTokens( e->r.client->netname ), sizeof(colorlessname) );

			if( !Q_stricmp( COM_RemoveColorTokens( name ), colorlessname ) )
			{
				targetNum = PLAYERNUM( e );
				break;
			}
		}

		// didn't find it by name, try by numbers
		if( targetNum == -1 )
		{
			i = atoi( name );
			if( i >= 0 && i < gs.maxclients )
			{
				e = game.edicts + 1 + i;
				if( G_Chase_IsValidTarget( ent, e, teamonly ) )
					targetNum = PLAYERNUM( e );
			}
		}

		if( targetNum == -1 )
			G_PrintMsg( ent, "Requested chasecam target is not available\n" );
	}

	// try to reuse old target if we didn't find a valid one
	if( targetNum == -1 && oldTarget > 0 && oldTarget < gs.maxclients )
	{
		e = game.edicts + 1 + oldTarget;
		if( G_Chase_IsValidTarget( ent, e, teamonly ) )
			targetNum = PLAYERNUM( e );
	}

	// if we still don't have a target, just pick the first valid one
	if( targetNum == -1 )
	{
		for( e = game.edicts + 1; PLAYERNUM( e ) < gs.maxclients; e++ )
		{
			if( !G_Chase_IsValidTarget( ent, e, teamonly ) )
				continue;

			targetNum = PLAYERNUM( e );
			break;
		}
	}

	// make the client a ghost
	G_GhostClient( ent );
	if( targetNum != -1 )
	{
		// we found a target, set up the chasecam
		client->resp.chase.target = targetNum + 1;
		client->resp.chase.teamonly = teamonly;
		client->resp.chase.followmode = followmode;
		G_Chase_SetChaseActive( ent, true );
	}
	else
	{
		// stay as observer
		if( !teamonly )
			ent->movetype = MOVETYPE_NOCLIP;
		client->level.showscores = false;
		G_Chase_SetChaseActive( ent, false );
		G_CenterPrintMsg( ent, "No one to chase" );
	}
}
示例#6
0
/*
* G_Match_CheckReadys
*/
void G_Match_CheckReadys( void )
{
	edict_t *e;
	bool allready;
	int readys, notreadys, teamsready;
	int team, i;

	if( GS_MatchState() != MATCH_STATE_WARMUP && GS_MatchState() != MATCH_STATE_COUNTDOWN )
		return;

	if( GS_MatchState() == MATCH_STATE_COUNTDOWN && level.forceStart )
		return; // never stop countdown if we have run out of warmup_timelimit

	teamsready = 0;
	for( team = TEAM_PLAYERS; team < GS_MAX_TEAMS; team++ )
	{
		readys = notreadys = 0;
		for( i = 0; i < teamlist[team].numplayers; i++ )
		{
			e = game.edicts + teamlist[team].playerIndices[i];

			if( !e->r.inuse )
				continue;
			if( e->s.team == TEAM_SPECTATOR )  //ignore spectators
				continue;

			if( level.ready[PLAYERNUM( e )] )
				readys++;
			else
				notreadys++;
		}
		if( !notreadys && readys )
			teamsready++;
	}

	// everyone has commited
	if( GS_TeamBasedGametype() )
	{
		if( teamsready == GS_MAX_TEAMS - TEAM_ALPHA )
			allready = true;
		else
			allready = false;
	}
	else
	{       //ffa
		if( teamsready && teamlist[TEAM_PLAYERS].numplayers > 1 )
			allready = true;
		else
			allready = false;
	}

	if( allready == true && GS_MatchState() != MATCH_STATE_COUNTDOWN )
	{
		G_PrintMsg( NULL, "All players are ready. Match starting!\n" );
		G_Match_LaunchState( MATCH_STATE_COUNTDOWN );
	}
	else if( allready == false && GS_MatchState() == MATCH_STATE_COUNTDOWN )
	{
		G_PrintMsg( NULL, "Countdown aborted.\n" );
		G_CenterPrintMsg( NULL, "COUNTDOWN ABORTED" );
		G_Match_Autorecord_Cancel();
		G_Match_LaunchState( MATCH_STATE_WARMUP );
	}
}
示例#7
0
/*
* ClientConnect
* Called when a player begins connecting to the server.
* The game can refuse entrance to a client by returning false.
* If the client is allowed, the connection process will continue
* and eventually get to ClientBegin()
* Changing levels will NOT cause this to be called again, but
* loadgames will.
*/
bool ClientConnect( edict_t *ent, char *userinfo, bool fakeClient, bool tvClient )
{
	char *value;

	assert( ent );
	assert( userinfo && Info_Validate( userinfo ) );
	assert( Info_ValueForKey( userinfo, "ip" ) && Info_ValueForKey( userinfo, "socket" ) );

	// verify that server gave us valid data
	if( !Info_Validate( userinfo ) )
	{
		Info_SetValueForKey( userinfo, "rejtype", va( "%i", DROP_TYPE_GENERAL ) );
		Info_SetValueForKey( userinfo, "rejflag", va( "%i", 0 ) );
		Info_SetValueForKey( userinfo, "rejmsg", "Invalid userinfo" );
		return false;
	}

	if( !Info_ValueForKey( userinfo, "ip" ) )
	{
		Info_SetValueForKey( userinfo, "rejtype", va( "%i", DROP_TYPE_GENERAL ) );
		Info_SetValueForKey( userinfo, "rejflag", va( "%i", 0 ) );
		Info_SetValueForKey( userinfo, "rejmsg", "Error: Server didn't provide client IP" );
		return false;
	}

	if( !Info_ValueForKey( userinfo, "ip" ) )
	{
		Info_SetValueForKey( userinfo, "rejtype", va( "%i", DROP_TYPE_GENERAL ) );
		Info_SetValueForKey( userinfo, "rejflag", va( "%i", 0 ) );
		Info_SetValueForKey( userinfo, "rejmsg", "Error: Server didn't provide client socket" );
		return false;
	}

	// check to see if they are on the banned IP list
	value = Info_ValueForKey( userinfo, "ip" );
	if( SV_FilterPacket( value ) )
	{
		Info_SetValueForKey( userinfo, "rejtype", va( "%i", DROP_TYPE_GENERAL ) );
		Info_SetValueForKey( userinfo, "rejflag", va( "%i", 0 ) );
		Info_SetValueForKey( userinfo, "rejmsg", "You're banned from this server" );
		return false;
	}

	// check for a password
	value = Info_ValueForKey( userinfo, "password" );
	if( !fakeClient && ( *password->string && ( !value || strcmp( password->string, value ) ) ) )
	{
		Info_SetValueForKey( userinfo, "rejtype", va( "%i", DROP_TYPE_PASSWORD ) );
		Info_SetValueForKey( userinfo, "rejflag", va( "%i", 0 ) );
		if( value && value[0] )
		{
			Info_SetValueForKey( userinfo, "rejmsg", "Incorrect password" );
		}
		else
		{
			Info_SetValueForKey( userinfo, "rejmsg", "Password required" );
		}
		return false;
	}

	// they can connect

	G_InitEdict( ent );
	ent->s.modelindex = 0;
	ent->r.solid = SOLID_NOT;
	ent->r.client = game.clients + PLAYERNUM( ent );
	ent->r.svflags = ( SVF_NOCLIENT | ( fakeClient ? SVF_FAKECLIENT : 0 ) );
	memset( ent->r.client, 0, sizeof( gclient_t ) );
	ent->r.client->ps.playerNum = PLAYERNUM( ent );
	ent->r.client->connecting = true;
	ent->r.client->isTV = tvClient == true;
	ent->r.client->team = TEAM_SPECTATOR;
	G_Client_UpdateActivity( ent->r.client ); // activity detected

	ClientUserinfoChanged( ent, userinfo );

	if( !fakeClient ) {
		char message[MAX_STRING_CHARS];

		Q_snprintfz( message, sizeof( message ), "%s%s connected", ent->r.client->netname, S_COLOR_WHITE );

		G_PrintMsg( NULL, "%s\n", message );

		G_Printf( "%s%s connected from %s\n", ent->r.client->netname, S_COLOR_WHITE, ent->r.client->ip );
	}

	// let the gametype scripts know this client just connected
	G_Gametype_ScoreEvent( ent->r.client, "connect", NULL );

	G_CallVotes_ResetClient( PLAYERNUM( ent ) );

	return true;
}
示例#8
0
文件: g_cmds.cpp 项目: DenMSC/qfusion
/*
* Cmd_PlayersExt_f
*/
static void Cmd_PlayersExt_f( edict_t *ent, bool onlyspecs )
{
	int i;
	int count = 0;
	int start = 0;
	char line[64];
	char msg[1024];

	if( trap_Cmd_Argc() > 1 )
		start = atoi( trap_Cmd_Argv( 1 ) );
	clamp( start, 0, gs.maxclients - 1 );

	// print information
	msg[0] = 0;

	for( i = start; i < gs.maxclients; i++ )
	{
		if( trap_GetClientState( i ) >= CS_SPAWNED )
		{
			edict_t *clientEnt = &game.edicts[i+1];
			gclient_t *cl;
			const char *login;

			if( onlyspecs && clientEnt->s.team != TEAM_SPECTATOR )
				continue;

			cl = clientEnt->r.client;

			login = NULL;
			if( cl->mm_session > 0 ) {
				login = Info_ValueForKey( cl->userinfo, "cl_mm_login" );
			}
			if( !login ) {
				login = "";
			}

			Q_snprintfz( line, sizeof( line ), "%3i %s" S_COLOR_WHITE "%s%s%s%s\n", i, cl->netname,
				login[0] ? "(" S_COLOR_YELLOW : "", login, login[0] ? S_COLOR_WHITE ")" : "",
				cl->isoperator ? " op" : "" );

			if( strlen( line ) + strlen( msg ) > sizeof( msg ) - 100 )
			{
				// can't print all of them in one packet
				Q_strncatz( msg, "...\n", sizeof( msg ) );
				break;
			}

			if( count == 0 )
			{
				Q_strncatz( msg, "num name\n", sizeof( msg ) );
				Q_strncatz( msg, "--- ------------------------------\n", sizeof( msg ) );
			}

			Q_strncatz( msg, line, sizeof( msg ) );
			count++;
		}
	}

	if( count )
		Q_strncatz( msg, "--- ------------------------------\n", sizeof( msg ) );
	Q_strncatz( msg, va( "%3i %s\n", count, trap_Cmd_Argv( 0 ) ), sizeof( msg ) );
	G_PrintMsg( ent, "%s", msg );

	if( i < gs.maxclients )
		G_PrintMsg( ent, "Type '%s %i' for more %s\n", trap_Cmd_Argv( 0 ), i, trap_Cmd_Argv( 0 ) );
}
示例#9
0
文件: g_awards.cpp 项目: cfr/qfusion
void G_AwardPlayerKilled( edict_t *self, edict_t *inflictor, edict_t *attacker, int mod )
{
	trace_t trace;
	score_stats_t *stats;
	loggedFrag_t *lfrag;

	if( self->r.svflags & SVF_CORPSE )
		return;

	if( !attacker->r.client )
		return;

	if( !self->r.client )
		return;

	if( attacker == self )
		return;

	if( attacker->s.team == self->s.team && attacker->s.team > TEAM_PLAYERS )
		return;

	if( mod == MOD_ROCKET_W || mod == MOD_ROCKET_S )
	{
		// direct hit
		attacker->r.client->resp.awardInfo.directrocket_count++;
		if( attacker->r.client->resp.awardInfo.directrocket_count == DIRECTROCKET_FOR_AWARD )
		{
			attacker->r.client->resp.awardInfo.directrocket_count = 0;
			attacker->r.client->resp.awardInfo.directrocket_award++;
			G_PlayerAward( attacker, S_COLOR_BLUE "Direct Rocket Hit!" );
		}
		// Midair
		if( self->groundentity == NULL && !self->waterlevel )
		{
			// check for height to the ground
			G_Trace( &trace, self->s.origin, self->r.mins, self->r.maxs, tv( self->s.origin[0], self->s.origin[1], self->s.origin[2] - 64 ), self, MASK_SOLID );
			if( trace.fraction == 1.0f )
			{
				attacker->r.client->resp.awardInfo.rl_midair_award++;
				G_PlayerAward( attacker, S_COLOR_BLUE "Air Rocket!" );
			}
		}
	}
	if( mod == MOD_GRENADE_W || mod == MOD_GRENADE_S )
	{
		// direct hit
		attacker->r.client->resp.awardInfo.directgrenade_count++;
		if( attacker->r.client->resp.awardInfo.directgrenade_count == DIRECTGRENADE_FOR_AWARD )
		{
			attacker->r.client->resp.awardInfo.directgrenade_count = 0;
			attacker->r.client->resp.awardInfo.directgrenade_award++;
			G_PlayerAward( attacker, S_COLOR_BLUE "Direct Grenade Hit!" );
		}

		// Midair
		if( self->groundentity == NULL && !self->waterlevel )
		{
			// check for height to the ground
			G_Trace( &trace, self->s.origin, self->r.mins, self->r.maxs, tv( self->s.origin[0], self->s.origin[1], self->s.origin[2] - 64 ), self, MASK_SOLID );
			if( trace.fraction == 1.0f )
			{
				attacker->r.client->resp.awardInfo.gl_midair_award++;
				G_PlayerAward( attacker, S_COLOR_BLUE "Air Grenade!" );
			}
		}
	}

	// Multikill
	if( game.serverTime - attacker->r.client->resp.awardInfo.multifrag_timer < MULTIKILL_INTERVAL )
		attacker->r.client->resp.awardInfo.multifrag_count++;
	else
		attacker->r.client->resp.awardInfo.multifrag_count = 1;

	attacker->r.client->resp.awardInfo.multifrag_timer = game.serverTime;

	if( attacker->r.client->resp.awardInfo.multifrag_count > 1 )
	{
		char s[MAX_CONFIGSTRING_CHARS];

		s[0] = 0;

		switch( attacker->r.client->resp.awardInfo.multifrag_count )
		{
		case 0:
		case 1:
			break;
		case 2:
			Q_strncpyz( s, S_COLOR_GREEN "Double Frag!", sizeof( s ) );
			break;
		case 3:
			Q_strncpyz( s, S_COLOR_GREEN "Triple Frag!", sizeof( s ) );
			break;
		case 4:
			Q_strncpyz( s, S_COLOR_GREEN "Quadruple Frag!", sizeof( s ) );
			break;
		default:
			Q_snprintfz( s, sizeof( s ), S_COLOR_GREEN "Extermination! %i in a row!", attacker->r.client->resp.awardInfo.multifrag_count );
			break;
		}

		G_PlayerAward( attacker, s );
	}

	// Sprees
	attacker->r.client->resp.awardInfo.frag_count++;

	if( attacker->r.client->resp.awardInfo.frag_count &&
		( attacker->r.client->resp.awardInfo.frag_count % 5 == 0 ) )
	{
		char s[MAX_CONFIGSTRING_CHARS];

		s[0] = 0;

		switch( (int)( attacker->r.client->resp.awardInfo.frag_count / 5 ) )
		{
		case 1:
			Q_strncpyz( s, S_COLOR_YELLOW "On Fire!", sizeof( s ) );
			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is On Fire!\n", attacker->r.client->netname );
			break;
		case 2:
			Q_strncpyz( s, S_COLOR_YELLOW "Raging!", sizeof( s ) );
			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is Raging!\n", attacker->r.client->netname );
			break;
		case 3:
			Q_strncpyz( s, S_COLOR_YELLOW "Fraglord!", sizeof( s ) );
			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is the Fraglord!\n", attacker->r.client->netname );
			break;
		case 4:
			Q_strncpyz( s, S_COLOR_YELLOW "Extermination!", sizeof( s ) );
			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is Exterminating!\n", attacker->r.client->netname );
			break;
		default:
			Q_strncpyz( s, S_COLOR_YELLOW "God Mode!", sizeof( s ) );
			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is in God Mode!\n", attacker->r.client->netname );
			break;
		}

		G_PlayerAward( attacker, s );
	}

	if( teamlist[attacker->s.team].stats.frags == 1 )
	{
		int i;

		for( i = TEAM_PLAYERS; i < GS_MAX_TEAMS; i++ ) {
			if( i == attacker->s.team )
				continue;
			if( teamlist[i].stats.frags )
				break;
		}

		if( i != GS_MAX_TEAMS )
			G_PlayerAward( attacker, S_COLOR_YELLOW "First Frag!" );
	}

	// ch : weapon specific frags
	if ( G_ModToAmmo( mod ) != AMMO_NONE )
		attacker->r.client->level.stats.accuracy_frags[G_ModToAmmo( mod )-AMMO_GUNBLADE]++;

	if( GS_MatchState() == MATCH_STATE_PLAYTIME /* && !strcmp( "duel", gs.gametypeName ) */)
	{
		// ch : frag log
		stats = &attacker->r.client->level.stats;
		if( !stats->fragAllocator )
			stats->fragAllocator = LinearAllocator( sizeof( loggedFrag_t ), 0, _G_LevelMalloc, _G_LevelFree );

		lfrag = ( loggedFrag_t * )LA_Alloc( stats->fragAllocator );
		lfrag->mm_attacker = attacker->r.client->mm_session;
		lfrag->mm_victim = self->r.client->mm_session;
		lfrag->weapon = G_ModToAmmo( mod ) - AMMO_GUNBLADE;
		lfrag->time = ( game.serverTime - GS_MatchStartTime() ) / 1000;
	}
}
示例#10
0
void G_AwardPlayerKilled( edict_t *self, edict_t *inflictor, edict_t *attacker, int mod )
{
	trace_t trace;

	if( self->r.svflags & SVF_CORPSE )
		return;

	if( !attacker->r.client )
		return;

	if( !self->r.client )
		return;

	if( attacker == self )
		return;

	if( attacker->s.team == self->s.team && attacker->s.team > TEAM_PLAYERS )
		return;

	if( mod == MOD_ROCKET_W || mod == MOD_ROCKET_S )
	{
		// direct hit
		attacker->r.client->resp.awardInfo.directrocket_count++;
		if( attacker->r.client->resp.awardInfo.directrocket_count == DIRECTROCKET_FOR_AWARD )
		{
			attacker->r.client->resp.awardInfo.directrocket_count = 0;
			attacker->r.client->resp.awardInfo.directrocket_award++;
			G_PlayerAward( attacker, S_COLOR_BLUE "Direct Rocket Hit!" );
		}
		// Midair
		if( self->groundentity == NULL && !self->waterlevel )
		{
			// check for height to the ground
			G_Trace( &trace, self->s.origin, self->r.mins, self->r.maxs, tv( self->s.origin[0], self->s.origin[1], self->s.origin[2] - 64 ), self, MASK_SOLID );
			if( trace.fraction == 1.0f )
			{
				attacker->r.client->resp.awardInfo.rl_midair_award++;
				G_PlayerAward( attacker, S_COLOR_BLUE "Air Rocket!" );
			}
		}
	}
	if( mod == MOD_GRENADE_W || mod == MOD_GRENADE_S )
	{
		// direct hit
		attacker->r.client->resp.awardInfo.directgrenade_count++;
		if( attacker->r.client->resp.awardInfo.directgrenade_count == DIRECTGRENADE_FOR_AWARD )
		{
			attacker->r.client->resp.awardInfo.directgrenade_count = 0;
			attacker->r.client->resp.awardInfo.directgrenade_award++;
			G_PlayerAward( attacker, S_COLOR_BLUE "Direct Grenade Hit!" );
		}

		// Midair
		if( self->groundentity == NULL && !self->waterlevel )
		{
			// check for height to the ground
			G_Trace( &trace, self->s.origin, self->r.mins, self->r.maxs, tv( self->s.origin[0], self->s.origin[1], self->s.origin[2] - 64 ), self, MASK_SOLID );
			if( trace.fraction == 1.0f )
			{
				attacker->r.client->resp.awardInfo.gl_midair_award++;
				G_PlayerAward( attacker, S_COLOR_BLUE "Air Grenade!" );
			}
		}
	}

	// Multikill
	if( game.serverTime - attacker->r.client->resp.awardInfo.multifrag_timer < MULTIKILL_INTERVAL )
		attacker->r.client->resp.awardInfo.multifrag_count++;
	else
		attacker->r.client->resp.awardInfo.multifrag_count = 1;

	attacker->r.client->resp.awardInfo.multifrag_timer = game.serverTime;

	if( attacker->r.client->resp.awardInfo.multifrag_count > 1 )
	{
		char s[MAX_CONFIGSTRING_CHARS];

		s[0] = 0;

		switch( attacker->r.client->resp.awardInfo.multifrag_count )
		{
		case 0:
		case 1:
			break;
		case 2:
			Q_strncpyz( s, S_COLOR_GREEN "Double Frag!", sizeof( s ) );
			break;
		case 3:
			Q_strncpyz( s, S_COLOR_GREEN "Triple Frag!", sizeof( s ) );
			break;
		case 4:
			Q_strncpyz( s, S_COLOR_GREEN "Quadruple Frag!", sizeof( s ) );
			break;
		default:
			Q_snprintfz( s, sizeof( s ), S_COLOR_GREEN "Extermination! %i in a row!", attacker->r.client->resp.awardInfo.multifrag_count );
			break;
		}

		G_PlayerAward( attacker, s );
	}

	// Sprees
	attacker->r.client->resp.awardInfo.frag_count++;

	if( attacker->r.client->resp.awardInfo.frag_count &&
		( attacker->r.client->resp.awardInfo.frag_count % 5 == 0 ) )
	{
		char s[MAX_CONFIGSTRING_CHARS];

		s[0] = 0;

		switch( (int)( attacker->r.client->resp.awardInfo.frag_count / 5 ) )
		{
		case 1:
			Q_strncpyz( s, S_COLOR_YELLOW "On Fire!", sizeof( s ) );
			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is On Fire!\n", attacker->r.client->netname );
			break;
		case 2:
			Q_strncpyz( s, S_COLOR_YELLOW "Raging!", sizeof( s ) );
			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is Raging!\n", attacker->r.client->netname );
			break;
		case 3:
			Q_strncpyz( s, S_COLOR_YELLOW "Fraglord!", sizeof( s ) );
			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is the Fraglord!\n", attacker->r.client->netname );
			break;
		case 4:
			Q_strncpyz( s, S_COLOR_YELLOW "Extermination!", sizeof( s ) );
			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is Exterminating!\n", attacker->r.client->netname );
			break;
		default:
			Q_strncpyz( s, S_COLOR_YELLOW "God Mode!", sizeof( s ) );
			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " is in God Mode!\n", attacker->r.client->netname );
			break;
		}

		G_PlayerAward( attacker, s );
	}
}
示例#11
0
/*
* G_Timeout_Update
* 
* Updates the timeout struct and informs clients about the status of the pause
*/
static void G_Timeout_Update( unsigned int msec )
{
	static int timeout_printtime = 0;
	static int timeout_last_endtime = 0;
	static int countdown_set = 1;

	if( !GS_MatchPaused() )
		return;

	game.frametime = 0;

	if( timeout_last_endtime != level.timeout.endtime ) // force print when endtime is changed
	{
		timeout_printtime = 0;
		timeout_last_endtime = level.timeout.endtime;
	}

	level.timeout.time += msec;
	if( level.timeout.endtime && level.timeout.time >= level.timeout.endtime )
	{
		level.timeout.time = 0;
		level.timeout.caller = -1;
		GS_GamestatSetFlag( GAMESTAT_FLAG_PAUSED, false );

		timeout_printtime = 0;
		timeout_last_endtime = -1;

		G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_TIMEOUT_MATCH_RESUMED_1_to_2, ( rand()&1 )+1 ) ),
			GS_MAX_TEAMS, true, NULL );
		G_CenterPrintMsg( NULL, "Match resumed" );
		G_PrintMsg( NULL, "Match resumed\n" );
	}
	else if( timeout_printtime == 0 || level.timeout.time - timeout_printtime >= 1000 )
	{
		if( level.timeout.endtime )
		{
			int seconds_left = (int)( ( level.timeout.endtime - level.timeout.time ) / 1000.0 + 0.5 );

			if( seconds_left == ( TIMEIN_TIME * 2 ) / 1000 )
			{
				G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_READY_1_to_2, ( rand()&1 )+1 ) ),
					GS_MAX_TEAMS, false, NULL );
				countdown_set = ( rand()&1 )+1;
			}
			else if( seconds_left >= 1 && seconds_left <= 3 )
			{
				G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_COUNTDOWN_COUNT_1_to_3_SET_1_to_2, seconds_left,
					countdown_set ) ), GS_MAX_TEAMS, false, NULL );
			}

			if( seconds_left > 1 )
				G_CenterPrintFormatMsg( NULL, "Match will resume in %s seconds", va( "%i", seconds_left ), NULL );
			else
				G_CenterPrintMsg( NULL, "Match will resume in 1 second" );
		}
		else
		{
			G_CenterPrintMsg( NULL, "Match paused" );
		}

		timeout_printtime = level.timeout.time;
	}
}
示例#12
0
文件: g_chase.c 项目: Racenet/racesow
/*
* Cmd_ChaseCam_f
*/
void Cmd_ChaseCam_f( edict_t *ent )
{
	qboolean team_only;

	if( ent->s.team != TEAM_SPECTATOR && !ent->r.client->teamstate.is_coach )
	{
		G_Teams_JoinTeam( ent, TEAM_SPECTATOR );
		G_PrintMsg( NULL, "%s%s joined the %s%s team.\n", ent->r.client->netname,
			S_COLOR_WHITE, GS_TeamName( ent->s.team ), S_COLOR_WHITE );
	}

	// & 1 = scorelead
	// & 2 = powerups
	// & 4 = flags

	if( ent->r.client->teamstate.is_coach && GS_TeamBasedGametype() )
		team_only = qtrue;
	else 
		team_only = qfalse;

	if( trap_Cmd_Argc() < 2 )
	{
		G_ChasePlayer( ent, NULL, team_only, 0 );
	}
	else if( !Q_stricmp( trap_Cmd_Argv( 1 ), "auto" ) )
	{
		G_PrintMsg( ent, "Chasecam mode is 'auto'. It will follow the score leader when no powerup nor flag is carried.\n" );
		G_ChasePlayer( ent, NULL, team_only, 7 );
	}
	else if( !Q_stricmp( trap_Cmd_Argv( 1 ), "carriers" ) )
	{
		G_PrintMsg( ent, "Chasecam mode is 'carriers'. It will switch to flag or powerup carriers when any of these items is picked up.\n" );
		G_ChasePlayer( ent, NULL, team_only, 6 );
	}
	else if( !Q_stricmp( trap_Cmd_Argv( 1 ), "powerups" ) )
	{
		G_PrintMsg( ent, "Chasecam mode is 'powerups'. It will switch to powerup carriers when any of these items is picked up.\n" );
		G_ChasePlayer( ent, NULL, team_only, 2 );
	}
	else if( !Q_stricmp( trap_Cmd_Argv( 1 ), "objectives" ) )
	{
		G_PrintMsg( ent, "Chasecam mode is 'objectives'. It will switch to objectives carriers when any of these items is picked up.\n" );
		G_ChasePlayer( ent, NULL, team_only, 4 );
	}
	else if( !Q_stricmp( trap_Cmd_Argv( 1 ), "score" ) )
	{
		G_PrintMsg( ent, "Chasecam mode is 'score'. It will always follow the highest fragger.\n" );
		G_ChasePlayer( ent, NULL, team_only, 1 );
	}
	else if( !Q_stricmp( trap_Cmd_Argv( 1 ), "help" ) )
	{
		G_PrintMsg( ent, "Chasecam modes:\n" );
		G_PrintMsg( ent, "- 'auto': Chase the score leader unless there's an objective carrier or a powerup carrier.\n" );
		G_PrintMsg( ent, "- 'carriers': User has pov control unless there's an objective carrier or a powerup carrier.\n" );
		G_PrintMsg( ent, "- 'objectives': User has pov control unless there's an objective carrier.\n" );
		G_PrintMsg( ent, "- 'powerups': User has pov control unless there's a flag carrier.\n" );
		G_PrintMsg( ent, "- 'score': Always follow the score leader. User has no pov control.\n" );
		G_PrintMsg( ent, "- 'none': Disable chasecam.\n" );
		return;
	}
	else
	{
		G_ChasePlayer( ent, trap_Cmd_Argv( 1 ), team_only, 0 );
	}

	G_Teams_LeaveChallengersQueue( ent );
}
示例#13
0
void G_DeathAwards( edict_t *ent )
{
	int frag_count = ent->r.client->resp.awardInfo.frag_count;
	if( frag_count >= 5 )
		G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " made a spree of " S_COLOR_WHITE "%d" S_COLOR_YELLOW "!\n", ent->r.client->netname, frag_count );
}
示例#14
0
/*
* G_Match_CheckStateAbort
*/
static void G_Match_CheckStateAbort( void )
{
	bool any = false;
	bool enough;

	if( GS_MatchState() <= MATCH_STATE_NONE || GS_MatchState() >= MATCH_STATE_POSTMATCH
		|| level.gametype.mathAbortDisabled )
	{
		GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, false );
		return;
	}

	if( GS_TeamBasedGametype() )
	{
		int team, emptyteams = 0;

		for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ )
		{
			if( !teamlist[team].numplayers )
				emptyteams++;
			else
				any = true;
		}

		enough = ( emptyteams == 0 );
	}
	else
	{
		enough = ( teamlist[TEAM_PLAYERS].numplayers > 1 );
		any = ( teamlist[TEAM_PLAYERS].numplayers > 0 );
	}

	// if waiting, turn on match states when enough players joined
	if( GS_MatchWaiting() && enough )
	{
		GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, false );
		G_UpdatePlayersMatchMsgs();
	}
	// turn off active match states if not enough players left
	else if( GS_MatchState() == MATCH_STATE_WARMUP && !enough && GS_MatchDuration() )
	{
		GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, true );
		G_UpdatePlayersMatchMsgs();
	}
	else if( GS_MatchState() == MATCH_STATE_COUNTDOWN && !enough )
	{
		if( any ) {
			G_PrintMsg( NULL, "Not enough players left. Countdown aborted.\n" );
			G_CenterPrintMsg( NULL, "COUNTDOWN ABORTED" );
		}
		G_Match_Autorecord_Cancel();
		G_Match_LaunchState( MATCH_STATE_WARMUP );
		GS_GamestatSetFlag( GAMESTAT_FLAG_WAITING, true );
		G_UpdatePlayersMatchMsgs();
	}
	// match running, but not enough players left
	else if( GS_MatchState() == MATCH_STATE_PLAYTIME && !enough )
	{
		if( any ) {
			G_PrintMsg( NULL, "Not enough players left. Match aborted.\n" );
			G_CenterPrintMsg( NULL, "MATCH ABORTED" );
		}
		G_EndMatch();
	}
}
示例#15
0
文件: g_cmds.c 项目: j0ki/racesow
/*
* Cmd_Give_f
* 
* Give items to a client
*/
static void Cmd_Give_f( edict_t *ent )
{
	char *name;
	gsitem_t	*it;
	int i;
	qboolean give_all;

	if( !sv_cheats->integer )
	{
		G_PrintMsg( ent, "Cheats are not enabled on this server.\n" );
		return;
	}

	name = trap_Cmd_Args();

	if( !Q_stricmp( name, "all" ) )
		give_all = qtrue;
	else
		give_all = qfalse;

	if( give_all || !Q_stricmp( trap_Cmd_Argv( 1 ), "health" ) )
	{
		if( trap_Cmd_Argc() == 3 )
			ent->health = atoi( trap_Cmd_Argv( 2 ) );
		else
			ent->health = ent->max_health;
		if( !give_all )
			return;
	}

	if( give_all || !Q_stricmp( name, "weapons" ) )
	{
		for( i = 0; i < GS_MAX_ITEM_TAGS; i++ )
		{
			it = GS_FindItemByTag( i );
			if( !it )
				continue;

			if( !( it->flags & ITFLAG_PICKABLE ) )
				continue;

			if( !( it->type & IT_WEAPON ) )
				continue;

			ent->r.client->ps.inventory[i] += 1;
		}
		if( !give_all )
			return;
	}

	if( give_all || !Q_stricmp( name, "ammo" ) )
	{
		for( i = 0; i < GS_MAX_ITEM_TAGS; i++ )
		{
			it = GS_FindItemByTag( i );
			if( !it )
				continue;

			if( !( it->flags & ITFLAG_PICKABLE ) )
				continue;

			if( !( it->type & IT_AMMO ) )
				continue;

			Add_Ammo( ent->r.client, it, 1000, qtrue );
		}
		if( !give_all )
			return;
	}

	if( give_all || !Q_stricmp( name, "armor" ) )
	{
		ent->r.client->resp.armor = GS_Armor_MaxCountForTag( ARMOR_RA );
		if( !give_all )
			return;
	}

	if( give_all )
	{
		for( i = 0; i < GS_MAX_ITEM_TAGS; i++ )
		{
			it = GS_FindItemByTag( i );
			if( !it )
				continue;

			if( !( it->flags & ITFLAG_PICKABLE ) )
				continue;

			if( it->type & ( IT_ARMOR|IT_WEAPON|IT_AMMO ) )
				continue;

			ent->r.client->ps.inventory[i] = 1;
		}
		return;
	}

	it = GS_FindItemByName( name );
	if( !it )
	{
		name = trap_Cmd_Argv( 1 );
		it = GS_FindItemByName( name );
		if( !it )
		{
			G_PrintMsg( ent, "unknown item\n" );
			return;
		}
	}

	if( !( it->flags & ITFLAG_PICKABLE ) )
	{
		G_PrintMsg( ent, "non-pickup (givable) item\n" );
		return;
	}

	if( it->type & IT_AMMO )
	{
		if( trap_Cmd_Argc() == 3 )
			ent->r.client->ps.inventory[it->tag] = atoi( trap_Cmd_Argv( 2 ) );
		else
			ent->r.client->ps.inventory[it->tag] += it->quantity;
	}
	else
	{
		if( it->tag && ( it->tag > 0 ) && ( it->tag < GS_MAX_ITEM_TAGS ) )
		{
			if( GS_FindItemByTag( it->tag ) != NULL )
				ent->r.client->ps.inventory[it->tag]++;
		}
		else
			G_PrintMsg( ent, "non-pickup (givable) item\n" );
	}
}
示例#16
0
/*
* ClientUserinfoChanged
* called whenever the player updates a userinfo variable.
* 
* The game can override any of the settings in place
* (forcing skins or names, etc) before copying it off.
*/
void ClientUserinfoChanged( edict_t *ent, char *userinfo )
{
	char *s;
	char oldname[MAX_INFO_VALUE];
	gclient_t *cl;

	int rgbcolor, i;

	assert( ent && ent->r.client );
	assert( userinfo && Info_Validate( userinfo ) );

	// check for malformed or illegal info strings
	if( !Info_Validate( userinfo ) )
	{
		trap_DropClient( ent, DROP_TYPE_GENERAL, "Error: Invalid userinfo" );
		return;
	}

	cl = ent->r.client;

	// ip
	s = Info_ValueForKey( userinfo, "ip" );
	if( !s )
	{
		trap_DropClient( ent, DROP_TYPE_GENERAL, "Error: Server didn't provide client IP" );
		return;
	}

	Q_strncpyz( cl->ip, s, sizeof( cl->ip ) );

	// socket
	s = Info_ValueForKey( userinfo, "socket" );
	if( !s )
	{
		trap_DropClient( ent, DROP_TYPE_GENERAL, "Error: Server didn't provide client socket" );
		return;
	}

	Q_strncpyz( cl->socket, s, sizeof( cl->socket ) );

	// color
	s = Info_ValueForKey( userinfo, "color" );
	if( s )
		rgbcolor = COM_ReadColorRGBString( s );
	else
		rgbcolor = -1;

	if( rgbcolor != -1 )
	{
		rgbcolor = COM_ValidatePlayerColor( rgbcolor );
		Vector4Set( cl->color, COLOR_R( rgbcolor ), COLOR_G( rgbcolor ), COLOR_B( rgbcolor ), 255 );
	}
	else
	{
		Vector4Set( cl->color, 255, 255, 255, 255 );
	}

	// set name, it's validated and possibly changed first
	Q_strncpyz( oldname, cl->netname, sizeof( oldname ) );
	G_SetName( ent, Info_ValueForKey( userinfo, "name" ) );
	if( oldname[0] && Q_stricmp( oldname, cl->netname ) && !cl->isTV && !CheckFlood( ent, false ) )
		G_PrintMsg( NULL, "%s%s is now known as %s%s\n", oldname, S_COLOR_WHITE, cl->netname, S_COLOR_WHITE );
	if( !Info_SetValueForKey( userinfo, "name", cl->netname ) )
	{
		trap_DropClient( ent, DROP_TYPE_GENERAL, "Error: Couldn't set userinfo (name)" );
		return;
	}

	// clan tag
	G_SetClan( ent, Info_ValueForKey( userinfo, "clan" ) );

	// handedness
	s = Info_ValueForKey( userinfo, "hand" );
	if( !s )
		cl->hand = 2;
	else
		cl->hand = bound( atoi( s ), 0, 2 );

	// handicap
	s = Info_ValueForKey( userinfo, "handicap" );
	if( s )
	{
		i = atoi( s );

		if( i > 90 || i < 0 )
		{
			G_PrintMsg( ent, "Handicap must be defined in the [0-90] range.\n" );
			cl->handicap = 0;
		}
		else
		{
			cl->handicap = i;
		}
	}

	s = Info_ValueForKey( userinfo, "cg_movementStyle" );
	if( s )
	{
		i = bound( atoi( s ), 0, GS_MAXBUNNIES - 1 );
		if( trap_GetClientState( PLAYERNUM(ent) ) < CS_SPAWNED )
		{
			if( i != cl->movestyle )
				cl->movestyle = cl->movestyle_latched = i;
		}
		else if( cl->movestyle_latched != cl->movestyle )
		{
			G_PrintMsg( ent, "A movement style change is already in progress. Please wait.\n" );
		}
		else if( i != cl->movestyle_latched )
		{
			cl->movestyle_latched = i;
			if( cl->movestyle_latched != cl->movestyle )
			{
				edict_t *switcher;

				switcher = G_Spawn();
				switcher->think = think_MoveTypeSwitcher;
				switcher->nextThink = level.time + 10000;
				switcher->s.ownerNum = ENTNUM( ent );
				G_PrintMsg( ent, "Movement style will change in 10 seconds.\n" );
			}
		}
	}

	// update the movement features depending on the movestyle
	if( !G_ISGHOSTING( ent ) && g_allow_bunny->integer )
	{
		if( cl->movestyle == GS_CLASSICBUNNY )
			cl->ps.pmove.stats[PM_STAT_FEATURES] &= ~PMFEAT_FWDBUNNY;
		else
			cl->ps.pmove.stats[PM_STAT_FEATURES] |= PMFEAT_FWDBUNNY;
	}

	s = Info_ValueForKey( userinfo, "cg_noAutohop" );
	if( s && s[0] )
	{
		if( atoi( s ) != 0 )
			cl->ps.pmove.stats[PM_STAT_FEATURES] &= ~PMFEAT_CONTINOUSJUMP;
		else
			cl->ps.pmove.stats[PM_STAT_FEATURES] |= PMFEAT_CONTINOUSJUMP;
	}

#ifdef UCMDTIMENUDGE
	s = Info_ValueForKey( userinfo, "cl_ucmdTimeNudge" );
	if( !s )
	{
		cl->ucmdTimeNudge = 0;
	}
	else
	{
		cl->ucmdTimeNudge = atoi( s );
		clamp( cl->ucmdTimeNudge, -MAX_UCMD_TIMENUDGE, MAX_UCMD_TIMENUDGE );
	}
#endif

	// mm session
	// TODO: remove the key after storing it to gclient_t !
	s = Info_ValueForKey( userinfo, "cl_mm_session" );
	cl->mm_session = ( s == NULL ) ? 0 : atoi( s );

	s = Info_ValueForKey( userinfo, "mmflags" );
	cl->mmflags = ( s == NULL ) ? 0 : strtoul( s, NULL, 10 );

	// tv
	if( cl->isTV )
	{
		s = Info_ValueForKey( userinfo, "tv_port" );
		cl->tv.port = s ? atoi( s ) : 0;

		s = Info_ValueForKey( userinfo, "tv_port6" );
		cl->tv.port6 = s ? atoi( s ) : 0;

		s = Info_ValueForKey( userinfo, "max_cl" );
		cl->tv.maxclients = s ? atoi( s ) : 0;

		s = Info_ValueForKey( userinfo, "num_cl" );
		cl->tv.numclients = s ? atoi( s ) : 0;

		s = Info_ValueForKey( userinfo, "chan" );
		cl->tv.channel = s ? atoi( s ) : 0;
	}

	if( !G_ISGHOSTING( ent ) && trap_GetClientState( PLAYERNUM( ent ) ) >= CS_SPAWNED )
		G_Client_AssignTeamSkin( ent, userinfo );

	// save off the userinfo in case we want to check something later
	Q_strncpyz( cl->userinfo, userinfo, sizeof( cl->userinfo ) );

	G_UpdatePlayerInfoString( PLAYERNUM( ent ) );
	G_UpdateMMPlayerInfoString( PLAYERNUM( ent ) );

	G_Gametype_ScoreEvent( cl, "userinfochanged", oldname );
}
示例#17
0
文件: g_cmds.c 项目: j0ki/racesow
/*
* G_vsay_f
*/
static void G_vsay_f( edict_t *ent, qboolean team )
{
	edict_t	*event = NULL;
	g_vsays_t *vsay;
	char *text = NULL;
	char *msg = trap_Cmd_Argv( 1 );

	if( ent->r.client && ent->r.client->muted & 2 )
		return;

	if( ( !GS_TeamBasedGametype() || GS_InvidualGameType() ) && ent->s.team != TEAM_SPECTATOR )
		team = qfalse;

	if( !( ent->r.svflags & SVF_FAKECLIENT ) )
	{                                      // ignore flood checks on bots
		if( ent->r.client->level.last_vsay > game.realtime - 500 )
			return; // ignore silently vsays in that come in rapid succession
		ent->r.client->level.last_vsay = game.realtime;

		if( CheckFlood( ent, qfalse ) )
			return;
	}

	for( vsay = g_vsays; vsay->name; vsay++ )
	{
		if( !Q_stricmp( msg, vsay->name ) )
		{
			event = G_SpawnEvent( EV_VSAY, vsay->id, NULL );
			text = vsay->message;
			break;
		}
	}

	if( event && text )
	{
		char saystring[256];

		event->r.svflags |= SVF_BROADCAST; // force sending even when not in PVS
		event->s.ownerNum = ent->s.number;
		if( team )
		{
			event->s.team = ent->s.team;
			event->r.svflags |= SVF_ONLYTEAM; // send only to clients with the same ->s.team value
		}

		if( trap_Cmd_Argc() > 2 )
		{
			int i;

			saystring[0] = 0;
			for( i = 2; i < trap_Cmd_Argc(); i++ )
			{
				Q_strncatz( saystring, trap_Cmd_Argv( i ), sizeof( saystring ) );
				Q_strncatz( saystring, " ", sizeof( saystring ) );
			}
			text = saystring;
		}

		if( team )
			G_Say_Team( ent, va( "(v) %s", text ), qfalse );
		else
			G_ChatMsg( NULL, ent, qfalse, "(v) %s", text );
		return;
	}

	// unknown token, print help
	{
		char string[MAX_STRING_CHARS];

		// print information
		string[0] = 0;
		if( msg && strlen( msg ) > 0 )
			Q_strncatz( string, va( "%sUnknown vsay token%s \"%s\"\n", S_COLOR_YELLOW, S_COLOR_WHITE, msg ), sizeof( string ) );
		Q_strncatz( string, va( "%svsays:%s\n", S_COLOR_YELLOW, S_COLOR_WHITE ), sizeof( string ) );
		for( vsay = g_vsays; vsay->name; vsay++ )
		{
			if( strlen( vsay->name ) + strlen( string ) < sizeof( string ) - 6 )
			{
				Q_strncatz( string, va( "%s ", vsay->name ), sizeof( string ) );
			}
		}
		Q_strncatz( string, "\n", sizeof( string ) );
		G_PrintMsg( ent, string );
	}
}
示例#18
0
/*
* G_Teams_JoinAnyTeam - find us a team since we are too lazy to do ourselves
*/
bool G_Teams_JoinAnyTeam( edict_t *ent, bool silent )
{
	int best_numplayers = gs.maxclients + 1, best_score = 999999;
	int i, team = -1;
	bool wasinqueue = ( ent->r.client->queueTimeStamp != 0 );

	G_Teams_UpdateMembersList(); // make sure we have up-to-date data

	//depending on the gametype, of course
	if( !GS_TeamBasedGametype() )
	{
		if( ent->s.team == TEAM_PLAYERS )
		{
			if( !silent )
			{
				G_PrintMsg( ent, "You are already in %s team\n", GS_TeamName( TEAM_PLAYERS ) );
			}
			return false;
		}
		if( G_Teams_JoinTeam( ent, TEAM_PLAYERS ) )
		{
			if( !silent )
			{
				G_PrintMsg( NULL, "%s%s joined the %s team.\n",
					ent->r.client->netname, S_COLOR_WHITE, GS_TeamName( ent->s.team ) );
			}
		}
		return true;

	}
	else
	{       //team based

		//find the available team with smaller player count or worse score
		for( i = TEAM_ALPHA; i < GS_MAX_TEAMS; i++ )
		{
			if( G_GameTypes_DenyJoinTeam( ent, i ) )
			{
				continue;
			}

			if( team == -1 || teamlist[i].numplayers < best_numplayers
					|| ( teamlist[i].numplayers == best_numplayers && teamlist[i].stats.score < best_score ) )
			{
				best_numplayers = teamlist[i].numplayers;
				best_score = teamlist[i].stats.score;
				team = i;
			}
		}

		if( team == ent->s.team )
		{                   // he is at the right team
			if( !silent )
			{
				G_PrintMsg( ent, "%sCouldn't find a better team than team %s.\n",
					S_COLOR_WHITE, GS_TeamName( ent->s.team ) );
			}
			return false;
		}

		if( team != -1 )
		{
			if( G_Teams_JoinTeam( ent, team ) )
			{
				if( !silent )
				{
					G_PrintMsg( NULL, "%s%s joined the %s team.\n",
						ent->r.client->netname, S_COLOR_WHITE, GS_TeamName( ent->s.team ) );
				}
				return true;
			}
		}
		if( GS_MatchState() <= MATCH_STATE_PLAYTIME && !silent )
			G_Teams_JoinChallengersQueue( ent );
	}

	// don't print message if we joined the queue
	if( !silent && ( !GS_HasChallengers() || wasinqueue || !ent->r.client->queueTimeStamp ) )
		G_PrintMsg( ent, "You can't join the game now\n" );

	return false;
}