Exemple #1
0
/*
* G_EndServerFrames_UpdateChaseCam
*/
void G_EndServerFrames_UpdateChaseCam( void )
{
	int i, team;
	edict_t	*ent;

	// do it by teams, so spectators can copy the chasecam information from players
	for( team = TEAM_PLAYERS; team < GS_MAX_TEAMS; team++ )
	{
		for( i = 0; i < teamlist[team].numplayers; i++ )
		{
			ent = game.edicts + teamlist[team].playerIndices[i];
			if( trap_GetClientState( PLAYERNUM(ent) ) < CS_SPAWNED )
			{
				G_Chase_SetChaseActive( ent, false );
				continue;
			}

			G_EndFrame_UpdateChaseCam( ent );
		}
	}

	// Do spectators last
	team = TEAM_SPECTATOR;
	for( i = 0; i < teamlist[team].numplayers; i++ )
	{
		ent = game.edicts + teamlist[team].playerIndices[i];
		if( trap_GetClientState( PLAYERNUM(ent) ) < CS_SPAWNED )
		{
			G_Chase_SetChaseActive( ent, false );
			continue;
		}

		G_EndFrame_UpdateChaseCam( ent );
	}
}
Exemple #2
0
/*
=================
UI_ResetMenu
=================
*/
void UI_ResetMenu(void) {
	uiClientState_t	cstate;
	int	n1, n2, n3;
	int	l1, l2, l3;

	// zero set all our globals
	memset( &s_reset, 0, sizeof(s_reset) );

	Reset_Cache();

	n1 = UI_ProportionalStringWidth( "YES/NO" );
	n2 = UI_ProportionalStringWidth( "YES" ) + PROP_GAP_WIDTH;
	n3 = UI_ProportionalStringWidth( "/" )  + PROP_GAP_WIDTH;
	l1 = 320 - ( n1 / 2 );
	l2 = l1 + n2;
	l3 = l2 + n3;
	s_reset.slashX = l2;

	s_reset.menu.draw       = Reset_MenuDraw;
	s_reset.menu.key        = Reset_MenuKey;
	s_reset.menu.wrapAround = qtrue;

	trap_GetClientState( &cstate );

	if ( cstate.connState >= CA_CONNECTED ) {
		// float on top of running game
		s_reset.menu.fullscreen = qfalse;
	}
	else {
		// game not running
		s_reset.menu.fullscreen = qtrue;
	}

	s_reset.yes.generic.type		= MTYPE_PTEXT;      
	s_reset.yes.generic.flags		= QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; 
	s_reset.yes.generic.callback	= Reset_MenuEvent;
	s_reset.yes.generic.id			= ID_YES;
	s_reset.yes.generic.x			= l1;
	s_reset.yes.generic.y			= 264;
	s_reset.yes.string				= "YES";
	s_reset.yes.color				= color_red;
	s_reset.yes.style				= UI_LEFT;

	s_reset.no.generic.type			= MTYPE_PTEXT;      
	s_reset.no.generic.flags		= QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; 
	s_reset.no.generic.callback		= Reset_MenuEvent;
	s_reset.no.generic.id			= ID_NO;
	s_reset.no.generic.x		    = l3;
	s_reset.no.generic.y		    = 264;
	s_reset.no.string				= "NO";
	s_reset.no.color			    = color_red;
	s_reset.no.style			    = UI_LEFT;

	Menu_AddItem( &s_reset.menu,	&s_reset.yes );             
	Menu_AddItem( &s_reset.menu,	&s_reset.no );

	UI_PushMenu( &s_reset.menu );

	Menu_SetCursorToItem( &s_reset.menu, &s_reset.no );
}
Exemple #3
0
/*
* G_Chase_IsValidTarget
*/
static bool G_Chase_IsValidTarget( edict_t *ent, edict_t *target, bool teamonly ) {
	if( !ent || !target ) {
		return false;
	}

	if( !target->r.inuse || !target->r.client || trap_GetClientState( PLAYERNUM( target ) ) < CS_SPAWNED ) {
		return false;
	}

	if( target->s.team < TEAM_PLAYERS || target->s.team >= GS_MAX_TEAMS || target == ent ) {
		return false;
	}

	if( teamonly && !ent->r.client->teamstate.is_coach && G_ISGHOSTING( target ) ) {
		return false;
	}

	if( teamonly && target->s.team != ent->s.team ) {
		return false;
	}

	if( G_ISGHOSTING( target ) && !target->deadflag && target->s.team != TEAM_SPECTATOR ) {
		return false; // ghosts that are neither dead, nor speccing (probably originating from gt-specific rules)

	}
	return true;
}
Exemple #4
0
void G_ScoreboardMessage_AddChasers( int entnum, int entnum_self )
{
	char entry[MAX_TOKEN_CHARS];
	int i;
	edict_t *e;
	size_t len;

	len = strlen( scoreboardString );
	if( !len )
		return;

	// add personal spectators
	Q_strncpyz( entry, "&y ", sizeof( entry ) );
	ADD_SCOREBOARD_ENTRY( scoreboardString, len, entry );

	for( i = 0; i < teamlist[TEAM_SPECTATOR].numplayers; i++ )
	{
		e = game.edicts + teamlist[TEAM_SPECTATOR].playerIndices[i];

		if( ENTNUM( e ) == entnum_self )
			continue;

		if( e->r.client->connecting || trap_GetClientState( PLAYERNUM( e ) ) < CS_SPAWNED )
			continue;

		if( !e->r.client->resp.chase.active || e->r.client->resp.chase.target != entnum )
			continue;

		Q_snprintfz( entry, sizeof( entry ), "%i ", PLAYERNUM( e ) );
		ADD_SCOREBOARD_ENTRY( scoreboardString, len, entry );
	}
}
Exemple #5
0
/*
* G_Teams_JoinChallengersQueue
*/
void G_Teams_JoinChallengersQueue( edict_t *ent )
{
	int pos = 0;
	edict_t *e;

	if( !GS_HasChallengers() )
	{
		ent->r.client->queueTimeStamp = 0;
		return;
	}

	if( ent->s.team != TEAM_SPECTATOR )
		return;

	// enter the challengers queue
	if( !ent->r.client->queueTimeStamp )
	{                                       // enter the line
		ent->r.client->queueTimeStamp = game.realtime;
		for( e = game.edicts + 1; PLAYERNUM( e ) < gs.maxclients; e++ )
		{
			if( !e->r.inuse || !e->r.client || trap_GetClientState( PLAYERNUM(e) ) < CS_SPAWNED )
				continue;
			if( !e->r.client->queueTimeStamp || e->s.team != TEAM_SPECTATOR )
				continue;
			// if there are other players with the same timestamp, increase ours
			if( e->r.client->queueTimeStamp >= ent->r.client->queueTimeStamp )
				ent->r.client->queueTimeStamp = e->r.client->queueTimeStamp+1;
			if( e->r.client->queueTimeStamp < ent->r.client->queueTimeStamp )
				pos++;
		}

		G_PrintMsg( ent, "%sYou entered the challengers queue in position %i\n", S_COLOR_CYAN, pos+1 );
		G_UpdatePlayerMatchMsg( ent );
	}
}
/*
===============
UI_TeamOrdersMenu_f
===============
*/
void UI_TeamOrdersMenu_f(void)
{
	uiClientState_t	cs;
	char	info[MAX_INFO_STRING];
	int		team;

	// make sure it's a team game
	trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
	teamOrdersMenuInfo.gametype = atoi(Info_ValueForKey(info, "g_gametype"));
	if (teamOrdersMenuInfo.gametype < GT_TEAM)
	{
		return;
	}

	// not available to spectators
	trap_GetClientState(&cs);
	trap_GetConfigString(CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING);
	team = atoi(Info_ValueForKey(info, "t"));
	if (team == TEAM_SPECTATOR)
	{
		return;
	}

	UI_TeamOrdersMenu();
}
Exemple #7
0
/*
* ClientCommand
*/
void ClientCommand( edict_t *ent )
{
	char *cmd;
	int i;

	if( !ent->r.client || trap_GetClientState( PLAYERNUM( ent ) ) < CS_SPAWNED )
		return; // not fully in game yet

	cmd = trap_Cmd_Argv( 0 );

	if( Q_stricmp( cmd, "cvarinfo" ) ) // skip cvarinfo cmds because they are automatic responses
		G_Client_UpdateActivity( ent->r.client ); // activity detected

	for( i = 0; i < MAX_GAMECOMMANDS; i++ )
	{
		if( !g_Commands[i].name[0] )
			break;

		if( !Q_stricmp( g_Commands[i].name, cmd ) )
		{
			if( g_Commands[i].func )
				g_Commands[i].func( ent );
			else
				GT_asCallGameCommand( ent->r.client, cmd, trap_Cmd_Args(), trap_Cmd_Argc() - 1 );
			return;
		}
	}

	G_PrintMsg( ent, "Bad user command: %s\n", cmd );
}
Exemple #8
0
/*
* TVM_ClientBegin
* 
* called when a client has finished connecting, and is ready
* to be placed into the game. This will happen every level load.
*/
void TVM_ClientBegin( tvm_relay_t *relay, edict_t *ent )
{
	edict_t *spot, *other;
	int i, specs;
	char hostname[MAX_CONFIGSTRING_CHARS];

	assert( ent && ent->local && ent->r.client );

	//TVM_Printf( "Begin: %s\n", ent->r.client->pers.netname );

	ent->r.client->pers.connecting = false;

	spot = TVM_SelectSpawnPoint( ent );
	if( spot )
	{
		VectorCopy( spot->s.origin, ent->s.origin );
		VectorCopy( spot->s.origin, ent->s.old_origin );
		VectorCopy( spot->s.angles, ent->s.angles );
		VectorCopy( spot->s.origin, ent->r.client->ps.pmove.origin );
		VectorCopy( spot->s.angles, ent->r.client->ps.viewangles );
	}
	else
	{
		VectorClear( ent->s.origin );
		VectorClear( ent->s.old_origin );
		VectorClear( ent->s.angles );
		VectorClear( ent->r.client->ps.pmove.origin );
		VectorClear( ent->r.client->ps.viewangles );
	}

	ent->s.teleported = true;
	// set the delta angle
	for( i = 0; i < 3; i++ )
		ent->r.client->ps.pmove.delta_angles[i] = ANGLE2SHORT( ent->s.angles[i] ) - ent->r.client->pers.cmd_angles[i];

	specs = 0;
	for( i = 0; i < relay->local_maxclients; i++ )
	{
		other = relay->local_edicts + i;
		if( other == ent )
			continue;
		if( !other->r.inuse || !other->r.client )
			continue;
		if( trap_GetClientState( relay, PLAYERNUM( other ) ) != CS_SPAWNED )
			continue;
		specs++;
	}

	Q_strncpyz( hostname, relay->configStrings[CS_HOSTNAME], sizeof( hostname ) );
	TVM_PrintMsg( relay, ent, S_COLOR_ORANGE "Welcome to %s! There %s currently %i spectator%s on this channel.\n",
		COM_RemoveColorTokens( hostname ), (specs == 1 ? "is" : "are"), specs, (specs == 1 ? "" : "s") );

	TVM_PrintMsg( relay, ent, S_COLOR_ORANGE "For more information about chase camera modes type 'chase help' at console.\n" );

	if( ent->r.client->chase.active )
		TVM_ChaseClientEndSnapFrame( ent );
	else
		TVM_ClientEndSnapFrame( ent );
}
Exemple #9
0
/*
* G_ClientEndSnapFrame
* 
* Called for each player at the end of the server frame
* and right after spawning
*/
void G_ClientEndSnapFrame( edict_t *ent )
{
	gclient_t *client;
	int i;

	if( trap_GetClientState( PLAYERNUM( ent ) ) < CS_SPAWNED )
		return;

	client = ent->r.client;

	// set fov
	if( !client->ps.pmove.stats[PM_STAT_ZOOMTIME] )
		client->ps.fov = ent->r.client->fov;
	else
	{
		float frac = (float)client->ps.pmove.stats[PM_STAT_ZOOMTIME] / (float)ZOOMTIME;
		client->ps.fov = client->fov - ( (float)( client->fov - client->zoomfov ) * frac );
	}

	// If the end of unit layout is displayed, don't give
	// the player any normal movement attributes
	if( GS_MatchState() >= MATCH_STATE_POSTMATCH )
	{
		G_SetClientStats( ent );
	}
	else
	{
		if( G_IsDead( ent ) && !level.gametype.customDeadBodyCam )
		{
			G_Client_DeadView( ent );
		}

		G_PlayerWorldEffects( ent ); // burn from lava, etc
		G_ClientDamageFeedback( ent ); // show damage taken along the snap
		G_SetClientStats( ent );
		G_SetClientEffects( ent );
		G_SetClientSound( ent );
		G_SetClientFrame( ent );

		client->ps.plrkeys = client->resp.snap.plrkeys;
	}

	G_ReleaseClientPSEvent( client );

	// set the delta angle
	for( i = 0; i < 3; i++ )
		client->ps.pmove.delta_angles[i] = ANGLE2SHORT( client->ps.viewangles[i] ) - client->ucmd.angles[i];

	// this is pretty hackish. We exploit the fact that servers *do not* transmit
	// origin2/old_origin for ET_PLAYER/ET_CORPSE entities, and we use it for sending the player velocity
	if( !G_ISGHOSTING( ent ) )
	{
		ent->r.svflags |= SVF_TRANSMITORIGIN2;
		VectorCopy( ent->velocity, ent->s.origin2 );
	}
	else
		ent->r.svflags &= ~SVF_TRANSMITORIGIN2;
}
Exemple #10
0
/*
* G_ClearSnap
* We just run G_SnapFrame, the server just sent the snap to the clients,
* it's now time to clean up snap specific data to start the next snap from clean.
*/
void G_ClearSnap( void )
{
	edict_t	*ent;

	game.realtime = trap_Milliseconds(); // level.time etc. might not be real time

	// clear gametype's clock override
	gs.gameState.longstats[GAMELONG_CLOCKOVERRIDE] = 0;

	// clear all events in the snap
	for( ent = &game.edicts[0]; ENTNUM( ent ) < game.numentities; ent++ )
	{
		if( ISEVENTENTITY( &ent->s ) )  // events do not persist after a snapshot
		{
			G_FreeEdict( ent );
			continue;
		}

		// events only last for a single message
		ent->s.events[0] = ent->s.events[1] = 0;
		ent->s.eventParms[0] = ent->s.eventParms[1] = 0;
		ent->numEvents = 0;
		ent->eventPriority[0] = ent->eventPriority[1] = false;
		ent->s.teleported = qfalse; // remove teleported bit.

		// remove effect bits that are (most likely) added from gametypes
		ent->s.effects = ( ent->s.effects & (EF_TAKEDAMAGE|EF_CARRIER|EF_FLAG_TRAIL|EF_ROTATE_AND_BOB|EF_STRONG_WEAPON|EF_GHOST) );
	}

	// recover some info, let players respawn and finally clear the snap structures
	for( ent = &game.edicts[0]; ENTNUM( ent ) < game.numentities; ent++ )
	{
		if( !GS_MatchPaused() )
		{
			// copy origin to old origin ( this old_origin is for snaps )
			if( !( ent->r.svflags & SVF_TRANSMITORIGIN2 ) )
				VectorCopy( ent->s.origin, ent->s.old_origin );

			G_CheckClientRespawnClick( ent );
		}

		if( GS_MatchPaused() )
			ent->s.sound = entity_sound_backup[ENTNUM( ent )];

		// clear the snap temp info
		memset( &ent->snap, 0, sizeof( ent->snap ) );
		if( ent->r.client && trap_GetClientState( PLAYERNUM( ent ) ) >= CS_SPAWNED )
		{
			memset( &ent->r.client->resp.snap, 0, sizeof( ent->r.client->resp.snap ) );

			// set race stats to invisible
			RS_clearHUDStats( ent->r.client ); // racesow - clear with our function
		}
	}

	g_snapStarted = false;
}
Exemple #11
0
/*
===============
UI_TeamOrdersMenu_BuildBotList
===============
*/
static void UI_TeamOrdersMenu_BuildBotList(void)
{
	uiClientState_t	cs;
	int		numPlayers;
	int		isBot;
	int		n;
	char	playerTeam;
	char	botTeam;
	char	info[MAX_INFO_STRING];

	for (n = 0; n < 9; n++)
	{
		teamOrdersMenuInfo.bots[n] = teamOrdersMenuInfo.botNames[n];
	}

	trap_GetClientState(&cs);

	Q_strncpyz(teamOrdersMenuInfo.botNames[0], "Everyone", 16);
	teamOrdersMenuInfo.numBots = 1;

	trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
	numPlayers = atoi(Info_ValueForKey(info, "sv_maxclients"));
	teamOrdersMenuInfo.gametype = atoi(Info_ValueForKey(info, "g_gametype"));

	//Too: get the player team before the loop, so If player enter after bots in game, the menu still works !
	trap_GetConfigString(CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING);
	playerTeam = *Info_ValueForKey(info, "t");

	for (n = 0; n < numPlayers && teamOrdersMenuInfo.numBots < 9; n++)
	{
		trap_GetConfigString(CS_PLAYERS + n, info, MAX_INFO_STRING);

		//playerTeam = TEAM_SPECTATOR; // bk001204 = possible uninit use

		/*if (n == cs.clientNum)
		{
			playerTeam = *Info_ValueForKey(info, "t");
			continue;
		}*/

		isBot = atoi(Info_ValueForKey(info, "skill"));
		if (!isBot)
		{
			continue;
		}

		botTeam = *Info_ValueForKey(info, "t");
		if (botTeam != playerTeam)
		{
			continue;
		}

		Q_strncpyz(teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.numBots], Info_ValueForKey(info, "n"), 16);
		Q_CleanStr(teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.numBots]);
		teamOrdersMenuInfo.numBots++;
	}
}
Exemple #12
0
/*
* 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 )
		{
			if( onlyspecs && game.edicts[i+1].s.team != TEAM_SPECTATOR )
				continue;

			Q_snprintfz( line, sizeof( line ), "%3i %s%s\n", i, game.clients[i].netname,
				game.clients[i].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 ) );
}
Exemple #13
0
//==========================================
// AITools_Frame
// Gives think time to the debug tools found
// in this archive (those witch need it)
//==========================================
void AITools_Frame( void )
{
	edict_t *ent;
	for( ent = game.edicts + 1; PLAYERNUM( ent ) < gs.maxclients; ent++ )
	{
		if( !ent->r.inuse )
			continue;
		if( trap_GetClientState( PLAYERNUM( ent ) ) < CS_SPAWNED )
			continue;

		AITools_DropNodes( ent );
		AITools_ShowPlinks( ent );
	}
}
Exemple #14
0
/*
=================
UI_TogglePlayerIngame
=================
*/
void UI_TogglePlayerIngame(int localClientNum)
{
	uiClientState_t	cs;

	trap_GetClientState( &cs );

	if (cs.clientNums[localClientNum] == -1) {
		trap_Cmd_ExecuteText( EXEC_APPEND, va("%s\n", Com_LocalClientCvarName(localClientNum, "dropin")) );
	} else {
		trap_Cmd_ExecuteText( EXEC_APPEND, va("%s\n", Com_LocalClientCvarName(localClientNum, "dropout")) );
	}

	UI_ForceMenuOff ();
}
Exemple #15
0
/*
=================
InSelectPlayerMenu
=================
*/
void InSelectPlayerMenu( void (*playerfunc)(int), const char *banner, qboolean disableMissingPlayers ) {
	uiClientState_t	cs;

	trap_GetClientState( &cs );

	// If there is only one local client skip this menu.
	if (UI_NumLocalClients(&cs) <= 1 && disableMissingPlayers) {
		playerfunc(0);
		return;
	}

	InSelectPlayer_MenuInit( &cs, banner, disableMissingPlayers );
	s_setupplayers.playerfunc = playerfunc;
	UI_PushMenu( &s_setupplayers.menu );
}
void UI_LoadPanel_RenderHeaderText( panel_button_t* button ) {
	uiClientState_t cstate;
	char downloadName[MAX_INFO_VALUE];

	trap_GetClientState( &cstate );

	trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof( downloadName ) );

	if ( ( cstate.connState == CA_DISCONNECTED || cstate.connState == CA_CONNECTED ) && *downloadName ) {
		button->text = "DOWNLOADING...";
	} else {
		button->text = "CONNECTING...";
	}

	BG_PanelButtonsRender_Text( button );
}
void G_Gametype_GENERIC_SetUpEndMatch( void )
{
	edict_t *ent;

	level.gametype.readyAnnouncementEnabled = false;
	level.gametype.scoreAnnouncementEnabled = false;
	level.gametype.pickableItemsMask = 0; // disallow item pickup
	level.gametype.countdownEnabled = false;

	for( ent = game.edicts + 1; PLAYERNUM( ent ) < gs.maxclients; ent++ )
	{
		if( ent->r.inuse && trap_GetClientState( PLAYERNUM( ent ) ) >= CS_SPAWNED )
			G_ClientRespawn( ent, true );
	}

	G_AnnouncerSound( NULL, trap_SoundIndex( va( S_ANNOUNCER_POSTMATCH_GAMEOVER_1_to_2, ( rand()&1 )+1 ) ), GS_MAX_TEAMS, true, NULL );
}
Exemple #18
0
/*
===============
UI_TeamOrdersMenu_BuildBotList
===============
*/
static void UI_TeamOrdersMenu_BuildBotList(void) {
    uiClientState_t cs;
    int     numPlayers;
    int     isBot;
    int     n;
    char    playerTeam = '3';
    char    botTeam;
    char    info[MAX_INFO_STRING];

    for (n = 0; n < 9; n++) {
        teamOrdersMenuInfo.bots[n] = teamOrdersMenuInfo.botNames[n];
    }

    trap_GetClientState(&cs);

    Q_strncpyz(teamOrdersMenuInfo.botNames[0], "Everyone", 16);
    teamOrdersMenuInfo.numBots = 1;

    trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
    numPlayers = atoi(Info_ValueForKey(info, "sv_maxclients"));
    teamOrdersMenuInfo.gametype = atoi(Info_ValueForKey(info, "g_gametype"));

    for (n = 0; n < numPlayers && teamOrdersMenuInfo.numBots < 9; n++) {
        trap_GetConfigString(CS_PLAYERS + n, info, MAX_INFO_STRING);

        if (n == cs.clientNum) {
            playerTeam = *Info_ValueForKey(info, "t");
            continue;
        }

        isBot = atoi(Info_ValueForKey(info, "skill"));
        if (!isBot) {
            continue;
        }

        botTeam = *Info_ValueForKey(info, "t");
        if (botTeam != playerTeam) {
            continue;
        }

        Q_strncpyz(teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.numBots], Info_ValueForKey(info, "n"), 16);
        Q_CleanStr(teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.numBots]);
        teamOrdersMenuInfo.numBots++;
    }
}
/*
* G_CheckNumBots
*/
static void G_CheckNumBots( void )
{
	edict_t	*ent;
	int desiredNumBots;

	if( level.spawnedTimeStamp + 5000 > game.realtime )
		return;

	// check sanity of g_numbots
	if( g_numbots->integer < 0 )
		trap_Cvar_Set( "g_numbots", "0" );

	if( g_numbots->integer > gs.maxclients )
		trap_Cvar_Set( "g_numbots", va( "%i", gs.maxclients ) );

	if( level.gametype.numBots > gs.maxclients )
		level.gametype.numBots = gs.maxclients;

	desiredNumBots = level.gametype.numBots ? level.gametype.numBots : g_numbots->integer;

	if( desiredNumBots < game.numBots )
	{
		// kick one bot
		for( ent = game.edicts + gs.maxclients; PLAYERNUM( ent ) >= 0; ent-- )
		{
			if( !ent->r.inuse || !( ent->r.svflags & SVF_FAKECLIENT ) )
				continue;
			if( AI_GetType( ent->ai ) == AI_ISBOT )
			{
				trap_DropClient( ent, DROP_TYPE_GENERAL, NULL );
				break;
			}
		}
		return;
	}

	if( desiredNumBots > game.numBots )
	{                                     // add a bot if there is room
		for( ent = game.edicts + 1; PLAYERNUM( ent ) < gs.maxclients && game.numBots < desiredNumBots; ent++ )
		{
			if( !ent->r.inuse && trap_GetClientState( PLAYERNUM( ent ) ) == CS_FREE )
				BOT_SpawnBot( NULL );
		}
	}
}
Exemple #20
0
/*
================
Con_ToggleConsole_f
================
*/
void Con_ToggleConsole_f (void) {
	uiClientState_t	cls;

	trap_GetClientState( &cls );

	// Can't toggle the console when it's the only thing available
	if ( cls.connState == CA_DISCONNECTED && trap_Key_GetCatcher( ) == KEYCATCH_CONSOLE ) {
		return;
	}

	if ( con_autoclear.integer ) {
		MField_Clear( &g_consoleField );
	}

	g_consoleField.widthInChars = g_console_field_width;

	trap_Key_SetCatcher( trap_Key_GetCatcher( ) ^ KEYCATCH_CONSOLE );
}
Exemple #21
0
/*
* G_Chase_IsValidTarget
*/
static bool G_Chase_IsValidTarget( edict_t *ent, edict_t *target, bool teamonly )
{
	if( !ent || !target )
		return false;

	if( !target->r.inuse || !target->r.client || trap_GetClientState( PLAYERNUM( target ) ) < CS_SPAWNED )
		return false;

	if( target->s.team < TEAM_PLAYERS || target->s.team >= GS_MAX_TEAMS || target == ent )
		return false;

	if( teamonly && !ent->r.client->teamstate.is_coach && G_ISGHOSTING( target ) )
		return false;

	if( teamonly && target->s.team != ent->s.team )
		return false;

	return true;
}
/*
=================
UI_Message
hacked over from Confirm stuff
=================
*/
void UI_Message( const char **lines ) {
	uiClientState_t	cstate;
	int n1, l1;
	
	// zero set all our globals
	memset( &s_confirm, 0, sizeof(s_confirm) );

	ConfirmMenu_Cache();

	n1 = UI_ProportionalStringWidth( "OK" );
	l1 = 320 - ( n1 / 2 );
	
	s_confirm.lines = lines;
	s_confirm.style = UI_CENTER|UI_INVERSE|UI_SMALLFONT;

	s_confirm.menu.draw       = MessageMenu_Draw;
	s_confirm.menu.key        = ConfirmMenu_Key;
	s_confirm.menu.wrapAround = qtrue;
	
	trap_GetClientState( &cstate );
	if ( cstate.connState >= CA_CONNECTED ) {
		s_confirm.menu.fullscreen = qfalse;
	}
	else {
		s_confirm.menu.fullscreen = qtrue;
	}

	s_confirm.yes.generic.type		= MTYPE_PTEXT;      
	s_confirm.yes.generic.flags		= QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; 
	s_confirm.yes.generic.callback	= ConfirmMenu_Event;
	s_confirm.yes.generic.id		= ID_CONFIRM_YES;
	s_confirm.yes.generic.x			= l1;
	s_confirm.yes.generic.y			= 280;
	s_confirm.yes.string			= "OK";
	s_confirm.yes.color				= color_red;
	s_confirm.yes.style				= UI_LEFT;

	Menu_AddItem( &s_confirm.menu,	&s_confirm.yes );
	
	UI_PushMenu( &s_confirm.menu );

	Menu_SetCursorToItem( &s_confirm.menu, &s_confirm.yes );
}
Exemple #23
0
/*
* G_Client_InactivityRemove
*/
void G_Client_InactivityRemove( gclient_t *client )
{
	if( !client )
		return;

	if( trap_GetClientState( client - game.clients ) < CS_SPAWNED )
		return;

	if( client->ps.pmove.pm_type != PM_NORMAL )
		return;

	if( g_inactivity_maxtime->modified )
	{
		if( g_inactivity_maxtime->value <= 0.0f )
			trap_Cvar_ForceSet( "g_inactivity_maxtime", "0.0" );
		else if( g_inactivity_maxtime->value < 15.0f )
			trap_Cvar_ForceSet( "g_inactivity_maxtime", "15.0" );

		g_inactivity_maxtime->modified = false;
	}

	if( g_inactivity_maxtime->value == 0.0f )
		return;

	if( ( GS_MatchState() != MATCH_STATE_PLAYTIME ) || !level.gametype.removeInactivePlayers )
		return;

	// inactive for too long
	if( client->level.last_activity && client->level.last_activity + ( g_inactivity_maxtime->value * 1000 ) < level.time )
	{
		if( client->team >= TEAM_PLAYERS && client->team < GS_MAX_TEAMS )
		{
			edict_t *ent = &game.edicts[ client - game.clients + 1 ];

			// move to spectators and reset the queue time, effectively removing from the challengers queue
			G_Teams_SetTeam( ent, TEAM_SPECTATOR );
			client->queueTimeStamp = 0;

			G_PrintMsg( NULL, "%s" S_COLOR_YELLOW " has been moved to spectator after %.1f seconds of inactivity\n", client->netname, g_inactivity_maxtime->value );
		}
	}
}
Exemple #24
0
/*
* G_Laser_Think
*/
static void G_Laser_Think( edict_t *ent ) {
	edict_t *owner;

	if( ent->s.ownerNum < 1 || ent->s.ownerNum > gs.maxclients ) {
		G_FreeEdict( ent );
		return;
	}

	owner = &game.edicts[ent->s.ownerNum];

	if( G_ISGHOSTING( owner ) || owner->s.weapon != WEAP_LASERGUN ||
		trap_GetClientState( PLAYERNUM( owner ) ) < CS_SPAWNED ||
		( owner->r.client->ps.weaponState != WEAPON_STATE_REFIRESTRONG
		  && owner->r.client->ps.weaponState != WEAPON_STATE_REFIRE ) ) {
		G_HideLaser( ent );
		return;
	}

	ent->nextThink = level.time + 1;
}
/*
* G_TickOutPowerUps
*/
static void G_TickOutPowerUps( void )
{
	edict_t *ent;
	gsitem_t *item;
	int i;

	for( ent = game.edicts + 1; PLAYERNUM( ent ) < gs.maxclients; ent++ )
	{
		if( ent->r.inuse && trap_GetClientState( PLAYERNUM( ent ) ) >= CS_SPAWNED )
		{
			for( i = POWERUP_QUAD; i < POWERUP_TOTAL; i++ )
			{
				item = GS_FindItemByTag( i );
				if( item && item->quantity && ent->r.client->ps.inventory[item->tag] > 0 )
				{
					ent->r.client->ps.inventory[item->tag]--;
				}
			}
		}
	}

	// also tick out dropped powerups
	for( ent = game.edicts + gs.maxclients + BODY_QUEUE_SIZE; ENTNUM( ent ) < game.numentities; ent++ )
	{
		if( !ent->r.inuse || !ent->item )
			continue;

		if( !( ent->item->type & IT_POWERUP ) )
			continue;

		if( ent->spawnflags & DROPPED_ITEM )
		{
			ent->count--;
			if( ent->count <= 0 )
			{
				G_FreeEdict( ent );
				continue;
			}
		}
	}
}
Exemple #26
0
/*
* G_Teams_Join_Cmd
*/
void G_Teams_Join_Cmd( edict_t *ent )
{
	char *t;
	int team;

	if( !ent->r.client || trap_GetClientState( PLAYERNUM( ent ) ) < CS_SPAWNED )
		return;

	t = trap_Cmd_Argv( 1 );
	if( !t || *t == 0 )
	{
		G_Teams_JoinAnyTeam( ent, false );
		return;
	}

	team = GS_Teams_TeamFromName( t );
	if( team != -1 )
	{
		if( team == TEAM_SPECTATOR )
		{                      // special handling for spectator team
			Cmd_Spec_f( ent );
			return;
		}
		if( team == ent->s.team )
		{
			G_PrintMsg( ent, "You are already in %s team\n", GS_TeamName( team ) );
			return;
		}
		if( G_Teams_JoinTeam( ent, team ) )
		{
			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 );
			return;
		}
	}
	else
	{
		G_PrintMsg( ent, "No such team.\n" );
		return;
	}
}
Exemple #27
0
/*
* G_ClientThink
* Client frame think, and call to execute its usercommands thinking
*/
void G_ClientThink( edict_t *ent )
{
	if( !ent || !ent->r.client )
		return;

	if( trap_GetClientState( PLAYERNUM( ent ) ) < CS_SPAWNED )
		return;

	ent->r.client->ps.POVnum = ENTNUM( ent ); // set self

	// load instashield
	if( GS_Instagib() && g_instashield->integer )
	{
		if( ent->s.team >= TEAM_PLAYERS && ent->s.team < GS_MAX_TEAMS )
		{
			if( ent->r.client->ps.inventory[POWERUP_SHELL] > 0 )
			{
				ent->r.client->resp.instashieldCharge -= ( game.frametime * 0.001f ) * 60.0f;
				clamp( ent->r.client->resp.instashieldCharge, 0, INSTA_SHIELD_MAX );
				if( ent->r.client->resp.instashieldCharge == 0 )
					ent->r.client->ps.inventory[POWERUP_SHELL] = 0;
			}
			else
			{
				ent->r.client->resp.instashieldCharge += ( game.frametime * 0.001f ) * 20.0f;
				clamp( ent->r.client->resp.instashieldCharge, 0, INSTA_SHIELD_MAX );
			}
		}
	}

	// run bots thinking with the rest of clients
	if( ent->r.svflags & SVF_FAKECLIENT )
	{
		if( !ent->think && AI_GetType( ent->ai ) == AI_ISBOT )
			AI_Think( ent );
	}

	trap_ExecuteClientThinks( PLAYERNUM( ent ) );
}
Exemple #28
0
/*
* G_CheckClientRespawnClick
*/
void G_CheckClientRespawnClick( edict_t *ent )
{
	if( !ent->r.inuse || !ent->r.client || !G_IsDead( ent ) )
		return;

	if( GS_MatchState() >= MATCH_STATE_POSTMATCH )
		return;

	if( trap_GetClientState( PLAYERNUM( ent ) ) >= CS_SPAWNED )
	{
		// if the spawnsystem doesn't require to click
		if( G_SpawnQueue_GetSystem( ent->s.team ) != SPAWNSYSTEM_INSTANT )
		{
			int minDelay = g_respawn_delay_min->integer;

			// waves system must wait for at least 500 msecs (to see the death, but very short for selfkilling tactics).
			if( G_SpawnQueue_GetSystem( ent->s.team ) == SPAWNSYSTEM_WAVES )
				minDelay = ( g_respawn_delay_min->integer < 500 ) ? 500 : g_respawn_delay_min->integer;

			// hold system must wait for at least 1000 msecs (to see the death properly)
			if( G_SpawnQueue_GetSystem( ent->s.team ) == SPAWNSYSTEM_HOLD )
				minDelay = ( g_respawn_delay_min->integer < 1300 ) ? 1300 : g_respawn_delay_min->integer;
				
			if( level.time >= ent->deathTimeStamp + minDelay )
				G_SpawnQueue_AddClient( ent );
		}
		// clicked
		else if( ent->r.client->resp.snap.buttons & BUTTON_ATTACK )
		{
			if( level.time > ent->deathTimeStamp + g_respawn_delay_min->integer )
				G_SpawnQueue_AddClient( ent );
		}
		// didn't click, but too much time passed
		else if( g_respawn_delay_max->integer && ( level.time > ent->deathTimeStamp + g_respawn_delay_max->integer ) )
		{
			G_SpawnQueue_AddClient( ent );
		}
	}
}
Exemple #29
0
/*
* G_Teams_UpdateMembersList
* It's better to count the list in detail once per fame, than
* creating a quick list each time we need it.
*/
void G_Teams_UpdateMembersList( void )
{
	edict_t	*ent;
	int i, team;

	for( team = TEAM_SPECTATOR; team < GS_MAX_TEAMS; team++ )
	{
		teamlist[team].numplayers = 0;
		teamlist[team].ping = 0;
		teamlist[team].has_coach = false;

		//create a temp list with the clients inside this team
		for( i = 0, ent = game.edicts + 1; i < gs.maxclients; i++, ent++ )
		{
			if( !ent->r.client || ( trap_GetClientState( PLAYERNUM( ent ) ) < CS_CONNECTED ) )
				continue;

			if( ent->s.team == team )
			{
				teamlist[team].playerIndices[teamlist[team].numplayers++] = ENTNUM( ent );

				if( ent->r.client->teamstate.is_coach )
					teamlist[team].has_coach = true;
			}
		}

		qsort( teamlist[team].playerIndices, teamlist[team].numplayers, sizeof( teamlist[team].playerIndices[0] ), G_Teams_CompareMembers );

		if( teamlist[team].numplayers )
		{
			for( i = 0; i < teamlist[team].numplayers; i++ )
				teamlist[team].ping += game.edicts[teamlist[team].playerIndices[i]].r.client->r.ping;
			teamlist[team].ping /= teamlist[team].numplayers;
		}
	}
}
/*
* G_Match_ScoreAnnouncement
*/
static void G_Match_ScoreAnnouncement( void )
{
	int i;
	edict_t *e, *chased;
	int num_leaders, team;

	if( !level.gametype.scoreAnnouncementEnabled )
		return;

	num_leaders = 0;
	memset( leaders, 0, sizeof( leaders ) );

	if( GS_TeamBasedGametype() )
	{
		int score_max = -999999999;

		for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ )
		{
			if( !teamlist[team].numplayers )
				continue;

			if( teamlist[team].stats.score > score_max )
			{
				score_max = teamlist[team].stats.score;
				leaders[0] = team;
				num_leaders = 1;
			}
			else if( teamlist[team].stats.score == score_max )
			{
				leaders[num_leaders++] = team;
			}
		}
		leaders[num_leaders] = 0;
	}
	else
	{
		int score_max = -999999999;

		for( i = 0; i < MAX_CLIENTS && i < teamlist[TEAM_PLAYERS].numplayers; i++ )
		{
			if( game.clients[teamlist[TEAM_PLAYERS].playerIndices[i]-1].level.stats.score > score_max )
			{
				score_max = game.clients[teamlist[TEAM_PLAYERS].playerIndices[i]-1].level.stats.score;
				leaders[0] = teamlist[TEAM_PLAYERS].playerIndices[i];
				num_leaders = 1;
			}
			else if( game.clients[teamlist[TEAM_PLAYERS].playerIndices[i]-1].level.stats.score == score_max )
			{
				leaders[num_leaders++] = teamlist[TEAM_PLAYERS].playerIndices[i];
			}
		}
		leaders[num_leaders] = 0;
	}

	if( !score_announcement_init )
	{
		// copy over to last_leaders
		memcpy( last_leaders, leaders, sizeof( leaders ) );
		score_announcement_init = true;
		return;
	}

	for( e = game.edicts + 1; PLAYERNUM( e ) < gs.maxclients; e++ )
	{
		if( !e->r.client || trap_GetClientState( PLAYERNUM( e ) ) < CS_SPAWNED )
			continue;

		if( e->r.client->resp.chase.active )
			chased = &game.edicts[e->r.client->resp.chase.target];
		else
			chased = e;

		// floating spectator
		if( chased->s.team == TEAM_SPECTATOR )
		{
			if( !GS_TeamBasedGametype() )
				continue;

			if( last_leaders[1] == 0 && leaders[1] != 0 )
			{
				G_AnnouncerSound( e, trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TIED_LEAD_1_to_2, ( rand()&1 )+1 ) ),
					GS_MAX_TEAMS, true, NULL );
			}
			else if( leaders[1] == 0 && ( last_leaders[0] != leaders[0] || last_leaders[1] != 0 ) )
			{
				//G_AnnouncerSound( e, trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_1_to_4_TAKEN_LEAD_1_to_2,
				//	leaders[0]-1, ( rand()&1 )+1 ) ), GS_MAX_TEAMS, true, NULL );
			}
			continue;
		}

		// in the game or chasing someone who is
		if( G_WasLeading( chased ) && !G_IsLeading( chased ) )
		{
			if( GS_TeamBasedGametype() && !GS_InvidualGameType() )
				G_AnnouncerSound( e, trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_LOST_LEAD_1_to_2, ( rand()&1 )+1 ) ),
				GS_MAX_TEAMS, true, NULL );
			else
				G_AnnouncerSound( e, trap_SoundIndex( va( S_ANNOUNCER_SCORE_LOST_LEAD_1_to_2, ( rand()&1 )+1 ) ),
				GS_MAX_TEAMS, true, NULL );
		}
		else if( ( !G_WasLeading( chased ) || ( last_leaders[1] != 0 ) ) && G_IsLeading( chased ) && ( leaders[1] == 0 ) )
		{
			if( GS_TeamBasedGametype() && !GS_InvidualGameType() )
				G_AnnouncerSound( e, trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TAKEN_LEAD_1_to_2, ( rand()&1 )+1 ) ),
				GS_MAX_TEAMS, true, NULL );
			else
				G_AnnouncerSound( e, trap_SoundIndex( va( S_ANNOUNCER_SCORE_TAKEN_LEAD_1_to_2, ( rand()&1 )+1 ) ),
				GS_MAX_TEAMS, true, NULL );
		}
		else if( ( !G_WasLeading( chased ) || ( last_leaders[1] == 0 ) ) && G_IsLeading( chased ) && ( leaders[1] != 0 ) )
		{
			if( GS_TeamBasedGametype() && !GS_InvidualGameType() )
				G_AnnouncerSound( e, trap_SoundIndex( va( S_ANNOUNCER_SCORE_TEAM_TIED_LEAD_1_to_2, ( rand()&1 )+1 ) ),
				GS_MAX_TEAMS, true, NULL );
			else
				G_AnnouncerSound( e, trap_SoundIndex( va( S_ANNOUNCER_SCORE_TIED_LEAD_1_to_2, ( rand()&1 )+1 ) ),
				GS_MAX_TEAMS, true, NULL );
		}
	}

	// copy over to last_leaders
	memcpy( last_leaders, leaders, sizeof( leaders ) );
}