Пример #1
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 );
}
Пример #2
0
/*
* TVM_Cmd_PlayersExt_f
*/
static void TVM_Cmd_PlayersExt_f( edict_t *ent, bool onlyspecs ) {
	int i;
	int count = 0;
	int start = 0;
	char line[64];
	char msg[1024];
	edict_t *e;
	tvm_relay_t *relay = ent->relay;

	if( trap_Cmd_Argc() > 1 ) {
		start = atoi( trap_Cmd_Argv( 1 ) );
	}
	clamp( start, 0, relay->maxclients - 1 );

	// print information
	msg[0] = 0;

	for( i = start + 1; PLAYERNUM( ( relay->edicts + i ) ) < relay->maxclients; i++ ) {
		e = relay->edicts + i;
		if( e->r.inuse && !e->local && e->r.client ) {
			char *userinfo;

			userinfo = relay->configStrings[CS_PLAYERINFOS + PLAYERNUM( e )];
			Q_snprintfz( line, sizeof( line ), "%3i %s\n", i, Info_ValueForKey( userinfo, "name" ) );

			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 ) );
	TVM_PrintMsg( relay, ent, "%s", msg );

	if( i < relay->maxclients ) {
		TVM_PrintMsg( relay, ent, "Type '%s %i' for more %s\n", trap_Cmd_Argv( 0 ), i, trap_Cmd_Argv( 0 ) );
	}
}
Пример #3
0
/*
* TVM_Cmd_ChaseCam
*/
void TVM_Cmd_ChaseCam( edict_t *ent )
{
	const char *arg1;

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

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

	arg1 = trap_Cmd_Argv( 1 );
	if( trap_Cmd_Argc() < 2 )
	{
		TVM_ChasePlayer( ent, NULL, 0 );
	}
	else if( !Q_stricmp( arg1, "auto" ) )
	{
		TVM_PrintMsg( ent->relay, ent, "Chasecam mode is 'auto'. It will follow the score leader when no powerup nor flag is carried.\n" );
		TVM_ChasePlayer( ent, NULL, 7 );
	}
	else if( !Q_stricmp( arg1, "carriers" ) )
	{
		TVM_PrintMsg( ent->relay, ent, "Chasecam mode is 'carriers'. It will switch to flag or powerup carriers when any of these items is picked up.\n" );
		TVM_ChasePlayer( ent, NULL, 6 );
	}
	else if( !Q_stricmp( arg1, "powerups" ) )
	{
		TVM_PrintMsg( ent->relay, ent, "Chasecam mode is 'powerups'. It will switch to powerup carriers when any of these items is picked up.\n" );
		TVM_ChasePlayer( ent, NULL, 2 );
	}
	else if( !Q_stricmp( arg1, "objectives" ) )
	{
		TVM_PrintMsg( ent->relay, ent, "Chasecam mode is 'objectives'. It will switch to flag carriers when any of these items is picked up.\n" );
		TVM_ChasePlayer( ent, NULL, 4 );
	}
	else if( !Q_stricmp( arg1, "score" ) )
	{
		TVM_PrintMsg( ent->relay, ent, "Chasecam mode is 'score'. It will always follow the highest fragger.\n" );
		TVM_ChasePlayer( ent, NULL, 1 );
	}
	else if( !Q_stricmp( arg1, "fragger" ) )
	{
		TVM_PrintMsg( ent->relay, ent, "Chasecam mode is 'fragger'. The last fragging player will be followed.\n" );
		TVM_ChasePlayer( ent, NULL, 8 );
	}
	else if( !Q_stricmp( arg1, "help" ) )
	{
		TVM_PrintMsg( ent->relay, ent, "Chasecam modes:\n" );
		TVM_PrintMsg( ent->relay, ent, "- 'auto': Chase the score leader unless there's an objective carrier or a powerup carrier.\n" );
		TVM_PrintMsg( ent->relay, ent, "- 'carriers': User has pov control unless there's an objective carrier or a powerup carrier.\n" );
		TVM_PrintMsg( ent->relay, ent, "- 'objectives': User has pov control unless there's a objective carrier.\n" );
		TVM_PrintMsg( ent->relay, ent, "- 'powerups': User has pov control unless there's a powerup carrier.\n" );
		TVM_PrintMsg( ent->relay, ent, "- 'score': Always follow the score leader. User has no pov control.\n" );
		TVM_PrintMsg( ent->relay, ent, "- 'none': Disable chasecam.\n" );
	}
	else
	{
		TVM_ChasePlayer( ent, trap_Cmd_Argv( 1 ), 0 );
	}
}
Пример #4
0
void TVM_ChasePlayer( edict_t *ent, char *name, 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->chase.target;
	if( oldTarget < 0 )
		oldTarget = 0;

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

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

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

	// locate the requested target
	if( name && name[0] )
	{
		// find it by player names
		for( e = ent->relay->edicts + 1; PLAYERNUM( e ) < ent->relay->maxclients; e++ )
		{
			if( !TVM_Chase_IsValidTarget( ent, e ) )
				continue;

			Q_strncpyz( colorlessname, COM_RemoveColorTokens( e->r.client->pers.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 < ent->relay->maxclients )
			{
				e = ent->relay->edicts + 1 + i;
				if( TVM_Chase_IsValidTarget( ent, e ) )
					targetNum = PLAYERNUM( e );
			}
		}

		if( targetNum == -1 )
			TVM_PrintMsg( ent->relay, 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 <= ent->relay->maxclients )
	{
		e = ent->relay->edicts + 1 + oldTarget;
		if( TVM_Chase_IsValidTarget( ent, e ) )
			targetNum = PLAYERNUM( e );
	}

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

			targetNum = PLAYERNUM( e );
			break;
		}
	}

	// make the client a ghost
	TVM_GhostClient( ent );
	if( targetNum != -1 )
	{
		// we found a target, set up the chasecam
		client->chase.target = targetNum + 1;
		client->chase.followmode = followmode;
		TVM_Chase_SetChaseActive( ent, true );
	}
	else
	{
		// stay as observer
		ent->movetype = MOVETYPE_NOCLIP;
		TVM_SpectatorMode( ent );
		TVM_CenterPrintMsg( ent->relay, ent, "No one to chase" );
	}
}