Exemple #1
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 ) {
		G_Teams_JoinTeam( ent, TEAM_SPECTATOR );
		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 );
}
Exemple #2
0
/*
* G_SpawnQueue_AddClient
*/
void G_SpawnQueue_AddClient( edict_t *ent )
{
	g_teamspawnqueue_t *queue;
	int i;

	if( !ent || !ent->r.client )
		return;

	if( ENTNUM( ent ) <= 0 || ENTNUM( ent ) > gs.maxclients )
		return;

	if( ent->r.client->team < TEAM_SPECTATOR|| ent->r.client->team >= GS_MAX_TEAMS )
		return;

	queue = &g_spawnQueues[ent->r.client->team];

	for( i = queue->start; i < queue->head; i++ )
	{
		if( queue->list[i % MAX_CLIENTS] == ENTNUM( ent ) )
			return;
	}

	G_SpawnQueue_RemoveClient( ent );
	queue->list[queue->head % MAX_CLIENTS] = ENTNUM( ent );
	queue->head++;

	if( queue->spectate_team )
		G_ChasePlayer( ent, NULL, true, 0 );
}
Exemple #3
0
/*
* G_SpawnQueue_ReleaseTeamQueue
*/
void G_SpawnQueue_ReleaseTeamQueue( int team )
{
	g_teamspawnqueue_t *queue;
	edict_t *ent;
	int count;
	bool ghost;

	if( team < TEAM_SPECTATOR || team >= GS_MAX_TEAMS )
		return;

	queue = &g_spawnQueues[team];

	if( queue->start >= queue->head )
		return;

	// try to spawn them
	for( count = 0; ( queue->start < queue->head ) && ( count < gs.maxclients ); queue->start++, count++ )
	{
		if( queue->list[queue->start % MAX_CLIENTS] <= 0 || queue->list[queue->start % MAX_CLIENTS] > gs.maxclients )
			continue;

		ent = &game.edicts[queue->list[queue->start % MAX_CLIENTS]];

		ghost = false;

		if( team == TEAM_SPECTATOR || ent->r.client->teamstate.is_coach )
			ghost = true;

		G_ClientRespawn( ent, ghost );

		// when spawning inside spectator team bring up the chase camera
		if( team == TEAM_SPECTATOR && !ent->r.client->resp.chase.active )
			G_ChasePlayer( ent, NULL, false, 0 );
	}
}
Exemple #4
0
void G_Teams_Coach( edict_t *ent )
{
	if( GS_TeamBasedGametype() && !GS_InvidualGameType() && ent->s.team != TEAM_SPECTATOR )
	{
		if( !teamlist[ent->s.team].has_coach )
		{
			if( GS_MatchState() > MATCH_STATE_WARMUP && !GS_MatchPaused() )
			{
				G_PrintMsg( ent, "Can't set coach mode with the match in progress\n" );
			}
			else
			{
				// move to coach mode
				ent->r.client->teamstate.is_coach = true;
				G_GhostClient( ent );
				ent->health = ent->max_health;
				ent->deadflag = DEAD_NO;

				G_ChasePlayer( ent, NULL, true, 0 );

				//clear up his scores
				G_Match_Ready( ent ); // set ready and check readys
				memset( &ent->r.client->level.stats, 0, sizeof( ent->r.client->level.stats ) );

				teamlist[ent->s.team].has_coach = true;
				G_PrintMsg( NULL, "%s%s is now team %s coach \n", ent->r.client->netname,
					S_COLOR_WHITE, GS_TeamName( ent->s.team ) );
			}
		}
		else if( ent->r.client->teamstate.is_coach )
		{                            // if you are this team coach, resign
			ent->r.client->teamstate.is_coach = false;
			G_PrintMsg( NULL, "%s%s is no longer team %s coach \n", ent->r.client->netname,
				S_COLOR_WHITE, GS_TeamName( ent->s.team ) );

			G_Teams_SetTeam( ent, ent->s.team );
		}
		else
			G_PrintMsg( ent, "Your team already has a coach.\n" );
	}
	else
		G_PrintMsg( ent, "Coaching only valid while on a team in Team based Gametypes.\n" );
}
Exemple #5
0
/*
* ChaseStep
*/
void G_ChaseStep( edict_t *ent, int step )
{
	int i, j;
	int start;
	edict_t *newtarget = NULL;

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

	i = start = ent->r.client->resp.chase.target;

	if( step == 0 )
	{
		if( G_Chase_IsValidTarget( ent, game.edicts + i, ent->r.client->resp.chase.teamonly ) )
			newtarget = game.edicts + i;
		else
			step = 1;
	}

	if( !newtarget )
	{
		for( j = 0; j < gs.maxclients; j++ )
		{
			i += step;
			if( i < 1 )
				i = gs.maxclients;
			else if( i > gs.maxclients )
				i = 1;
			if( i == start )
				break;
			if( G_Chase_IsValidTarget( ent, game.edicts + i, ent->r.client->resp.chase.teamonly ) )
			{	
				newtarget = game.edicts + i;
				break;
			}
		}
	}

	if( newtarget )
	{
		G_ChasePlayer( ent, va( "%i", PLAYERNUM( newtarget ) ), ent->r.client->resp.chase.teamonly, ent->r.client->resp.chase.followmode );
	}
}
Exemple #6
0
/*
* ChaseStep
*/
void G_ChaseStep( edict_t *ent, int step )
{
	int i, j, team;
	bool player_found;
	int actual;
	int start;
	edict_t *newtarget = NULL;

	assert( step == -1 || step == 0 || step == 1 );

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

	start = ent->r.client->resp.chase.target;
	i = -1;
	player_found = false; // needed to prevent an infinite loop if there are no players
	// find the team of the previously chased player and his index in the sorted teamlist
	for( team = TEAM_PLAYERS; team < GS_MAX_TEAMS; team++ )
	{
		for( j = 0; j < teamlist[team].numplayers; j++ )
		{
			player_found = true;
			if( teamlist[team].playerIndices[j] == start )
			{
				i = j;
				break;
			}
		}
		if( j != teamlist[team].numplayers )
			break;
	}

	if( step == 0 )
	{
		// keep chasing the current player if possible
		if( i >= 0 && G_Chase_IsValidTarget( ent, game.edicts + start, ent->r.client->resp.chase.teamonly ) )
			newtarget = game.edicts + start;
		else
			step = 1;
	}

	if( !newtarget && player_found )
	{
		// reset the team if the previously chased player was not found
		if( team == GS_MAX_TEAMS )
			team = TEAM_PLAYERS;
		for( j = 0; j < gs.maxclients; j++ )
		{
			// at this point step is -1 or 1
			i += step;
			// change to the previous team if we skipped before the start of this one
			// the loop assures empty teams before this team are skipped as well
			while( i < 0 )
			{
				team--;
				if( team < TEAM_PLAYERS )
					team = GS_MAX_TEAMS - 1;
				i = teamlist[team].numplayers - 1;
			}
			// similarly, change to the next team if we skipped past the end of this one
			while( i >= teamlist[team].numplayers )
			{
				team++;
				if( team == GS_MAX_TEAMS )
					team = TEAM_PLAYERS;
				i = 0;
			}
			actual = teamlist[team].playerIndices[i];
			if( actual == start )
				break; // back at the original player, no need to waste time
			if( G_Chase_IsValidTarget( ent, game.edicts + actual, ent->r.client->resp.chase.teamonly ) )
			{
				newtarget = game.edicts + actual;
				break;
			}
			// make another step if this player is not valid
		}
	}

	if( newtarget )
		G_ChasePlayer( ent, va( "%i", PLAYERNUM( newtarget ) ), ent->r.client->resp.chase.teamonly, ent->r.client->resp.chase.followmode );
}
Exemple #7
0
/*
* G_EndFrame_UpdateChaseCam
*/
static void G_EndFrame_UpdateChaseCam( edict_t *ent )
{
	edict_t *targ;
	int followpov;

	// not in chasecam
	if( !ent->r.client->resp.chase.active )
		return;

	if( ( followpov = G_Chase_FindFollowPOV( ent ) ) != -1 )
		ent->r.client->resp.chase.target = followpov;

	// is our chase target gone?
	targ = &game.edicts[ent->r.client->resp.chase.target];

	if( !G_Chase_IsValidTarget( ent, targ, ent->r.client->resp.chase.teamonly ) )
	{
		if( game.realtime < ent->r.client->resp.chase.timeout ) // wait for timeout
			return;

		ent->r.client->resp.chase.timeout = game.realtime + 1500; // update timeout

		G_ChasePlayer( ent, NULL, ent->r.client->resp.chase.teamonly, ent->r.client->resp.chase.followmode );
		targ = &game.edicts[ent->r.client->resp.chase.target];
		if( !G_Chase_IsValidTarget( ent, targ, ent->r.client->resp.chase.teamonly ) )
			return;
	}

	ent->r.client->resp.chase.timeout = game.realtime + 1500; // update timeout

	if( targ == ent )
		return;

	// free our psev buffer when in chasecam
	G_ClearPlayerStateEvents( ent->r.client );

	// copy target playerState to me
	ent->r.client->ps = targ->r.client->ps;

	// fix some stats we don't want copied from the target
	ent->r.client->ps.stats[STAT_REALTEAM] = ent->s.team;
	ent->r.client->ps.stats[STAT_LAYOUTS] &= ~STAT_LAYOUT_SCOREBOARD;
	ent->r.client->ps.stats[STAT_LAYOUTS] &= ~STAT_LAYOUT_CHALLENGER;
	ent->r.client->ps.stats[STAT_LAYOUTS] &= ~STAT_LAYOUT_READY;
	ent->r.client->ps.stats[STAT_LAYOUTS] &= ~STAT_LAYOUT_SPECTEAMONLY;
	ent->r.client->ps.stats[STAT_LAYOUTS] &= ~STAT_LAYOUT_INSTANTRESPAWN;

	if( ent->r.client->resp.chase.teamonly )
	{
		ent->r.client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_SPECTEAMONLY;
		if( !ent->r.client->teamstate.is_coach )
			ent->r.client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_SPECDEAD; // show deadcam effect
	}

	if( ent->r.client->level.showscores || GS_MatchState() >= MATCH_STATE_POSTMATCH )
		ent->r.client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_SCOREBOARD; // show the scoreboard

	if( GS_HasChallengers() && ent->r.client->queueTimeStamp )
		ent->r.client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_CHALLENGER;

	if( GS_MatchState() <= MATCH_STATE_WARMUP && level.ready[PLAYERNUM( ent )] )
		ent->r.client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_READY;

	// chasecam uses PM_CHASECAM
	ent->r.client->ps.pmove.pm_type = PM_CHASECAM;
	ent->r.client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;

	VectorCopy( targ->s.origin, ent->s.origin );
	VectorCopy( targ->s.angles, ent->s.angles );
	GClip_LinkEntity( ent );
}
Exemple #8
0
/*
* 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 );
}
Exemple #9
0
/*
* G_SpawnQueue_Think
*/
void G_SpawnQueue_Think( void )
{
	int team, maxCount, count, spawnSystem;
	g_teamspawnqueue_t *queue;
	edict_t *ent;
	bool ghost;

	for( team = TEAM_SPECTATOR; team < GS_MAX_TEAMS; team++ )
	{
		queue = &g_spawnQueues[team];

		// if the system is limited, set limits
		maxCount = MAX_CLIENTS;

		spawnSystem = queue->system;
		clamp( spawnSystem, SPAWNSYSTEM_INSTANT, SPAWNSYSTEM_HOLD );

		switch( spawnSystem )
		{
		case SPAWNSYSTEM_INSTANT:
		default:
			break;

		case SPAWNSYSTEM_WAVES:
			if( queue->nextWaveTime > level.time )
			{
				maxCount = 0;
			}
			else
			{
				maxCount = ( queue->wave_maxcount < 1 ) ? gs.maxclients : queue->wave_maxcount; // max count per reinforcement wave
				queue->nextWaveTime = level.time + ( queue->wave_time * 1000 );
			}
			break;

		case SPAWNSYSTEM_HOLD:
			maxCount = 0; // players wait to be spawned elsewhere
			break;
		}

		if( maxCount <= 0 )
			continue;

		if( queue->start >= queue->head )
			continue;

		// try to spawn them
		for( count = 0; ( queue->start < queue->head ) && ( count < maxCount ); queue->start++, count++ )
		{
			if( queue->list[queue->start % MAX_CLIENTS] <= 0 || queue->list[queue->start % MAX_CLIENTS] > gs.maxclients )
				continue;

			ent = &game.edicts[queue->list[queue->start % MAX_CLIENTS]];

			ghost = false;

			if( team == TEAM_SPECTATOR || ent->r.client->teamstate.is_coach )
				ghost = true;

			G_ClientRespawn( ent, ghost );

			// when spawning inside spectator team bring up the chase camera
			if( team == TEAM_SPECTATOR && !ent->r.client->resp.chase.active )
				G_ChasePlayer( ent, NULL, false, 0 );
		}
	}
}