Example #1
0
/**
 * @brief Gets player for given team.
 * @param[in] team The team the player data should be searched for
 * @return The inuse player for the given team or @c NULL when no player found.
 * @todo What if there are multiple players for a team (multiplayer coop match)
 */
player_t* G_GetPlayerForTeam (int team)
{
    player_t *p;

    /* search corresponding player (even ai players) */
    p = NULL;
    while ((p = G_PlayerGetNextActiveHuman(p)))
        if (p->pers.team == team)
            /* found player */
            return p;

    p = NULL;
    while ((p = G_PlayerGetNextActiveAI(p)))
        if (p->pers.team == team)
            /* found player */
            return p;

    return NULL;
}
Example #2
0
/**
 * @brief Sets the teamnum var for this match
 * @param[in] player Pointer to connected player
 * @todo Check whether there are enough free spawnpoints in all cases
 */
static void G_GetTeam (player_t * player)
{
	player_t *p;
	int playersInGame = 0;

	/* player has already a team */
	if (player->pers.team > 0) {
		Com_DPrintf(DEBUG_GAME, "Player %s is already on team %i\n", player->pers.netname, player->pers.team);
		return;
	}

	/* number of currently connected players (no ai players) */
	p = NULL;
	while ((p = G_PlayerGetNextActiveHuman(p)))
		playersInGame++;

	/* randomly assign a teamnumber in deathmatch games */
	if (playersInGame <= 1 && sv_maxclients->integer > 1 && !sv_teamplay->integer) {
		int spawnCheck[MAX_TEAMS];
		int spawnSpots = 0;
		int randomSpot;
		int i;
		/* skip civilian teams */
		for (i = TEAM_PHALANX; i < MAX_TEAMS; i++) {
			spawnCheck[i] = 0;
			/* check whether there are spawnpoints for this team */
			if (level.num_spawnpoints[i])
				spawnCheck[spawnSpots++] = i;
		}
		/* we need at least 2 different team spawnpoints for multiplayer in a death match game */
		if (spawnSpots < 2)
			gi.Error("G_GetTeam: Not enough spawn spots in map!");

		/* assign random valid team number */
		i = spawnSpots;
		randomSpot = rand() % spawnSpots;
		for (;;) {
			const int team = spawnCheck[randomSpot];
			if (i == 0)
				gi.Error("G_GetTeam: Could not assign a team!");
			if (G_SetTeamForPlayer(player, team)) {
				gi.DPrintf("%s has been randomly assigned to team %i\n",
						player->pers.netname, G_ClientGetTeamNum(player));
				break;
			}
			i--;
			randomSpot = (randomSpot + 1) % spawnSpots;
		}
		return;
	}

	/* find a team */
	if (sv_maxclients->integer == 1)
		G_SetTeamForPlayer(player, TEAM_PHALANX);
	else if (sv_teamplay->integer) {
		/* set the team specified in the userinfo */
		const int i = G_ClientGetTeamNumPref(player);
		gi.DPrintf("Get a team for teamplay for %s\n", player->pers.netname);
		/* civilians are at team zero */
		if (i > TEAM_CIVILIAN && sv_maxteams->integer >= i) {
			G_SetTeamForPlayer(player, i);
			gi.BroadcastPrintf(PRINT_CONSOLE, "serverconsole: %s has chosen team %i\n", player->pers.netname, i);
		} else {
			gi.DPrintf("Team %i is not valid - choose a team between 1 and %i\n", i, sv_maxteams->integer);
			G_SetTeamForPlayer(player, TEAM_DEFAULT);
		}
	} else {
		int i;
		/* search team */
		gi.DPrintf("Getting a multiplayer team for %s\n", player->pers.netname);
		for (i = TEAM_CIVILIAN + 1; i < MAX_TEAMS; i++) {
			if (level.num_spawnpoints[i]) {
				bool teamAvailable = true;

				p = NULL;
				/* check if team is in use (only human controlled players) */
				while ((p = G_PlayerGetNextActiveAI(p))) {
					if (p->pers.team == i) {
						Com_DPrintf(DEBUG_GAME, "Team %i is already in use\n", i);
						/* team already in use */
						teamAvailable = false;
						break;
					}
				}
				if (teamAvailable)
					break;
			}
		}

		/* set the team */
		if (i < MAX_TEAMS) {
			/* remove ai player */
			p = NULL;
			while ((p = G_PlayerGetNextActiveHuman(p))) {
				if (p->pers.team == i) {
					gi.BroadcastPrintf(PRINT_CONSOLE, "Removing ai player...");
					p->inuse = false;
					break;
				}
			}
			Com_DPrintf(DEBUG_GAME, "Assigning %s to team %i\n", player->pers.netname, i);
			G_SetTeamForPlayer(player, i);
		} else {
			gi.DPrintf("No free team - disconnecting '%s'\n", player->pers.netname);
			G_ClientDisconnect(player);
		}
	}
}
Example #3
0
/**
 * @sa G_PlayerSoldiersCount
 */
void G_ClientEndRound (Player& player)
{
	Player* p;

	const int lastTeamIndex = (G_GetActiveTeam() + level.teamOfs) % MAX_TEAMS;

	if (!G_IsAIPlayer(&player)) {
		/* inactive players can't end their inactive turn :) */
		if (level.activeTeam != player.getTeam())
			return;

		/* check for "team oszillation" */
		if (level.framenum < level.nextEndRound)
			return;

		level.nextEndRound = level.framenum + 20;
	}

	/* only use this for teamplay matches like coopX or fight2on2 and above
	 * also skip this for ai players, this is only called when all ai actors
	 * have finished their 'thinking' */
	if (!G_IsAIPlayer(&player) && sv_teamplay->integer) {
		/* check if all team members are ready */
		if (!player.roundDone) {
			player.roundDone = true;
			G_EventEndRoundAnnounce(player);
			G_EventEnd();
		}
		p = nullptr;
		while ((p = G_PlayerGetNextActiveHuman(p)))
			if (p->getTeam() == level.activeTeam && !p->roundDone && G_PlayerSoldiersCount(*p) > 0)
				return;
		p = nullptr;
		while ((p = G_PlayerGetNextActiveAI(p)))
			if (p->getTeam() == level.activeTeam && !p->roundDone && G_PlayerSoldiersCount(*p) > 0)
				return;
	} else {
		player.roundDone = true;
	}

	/* clear any remaining reaction fire */
	G_ReactionFireOnEndTurn();

	if (!G_IsAIPlayer(&player)) {
		if (g_lastseen->integer > 0) {
			Edict* ent = nullptr;
			while ((ent = G_EdictsGetNextActor(ent))) {
				if (G_IsAI(ent) && G_IsVisibleForTeam(ent, level.activeTeam)) {
					player.lastSeen = level.actualRound;
					break;
				}
			}
			if (level.actualRound - player.lastSeen > g_lastseen->integer) {
				Com_Printf("round end triggered by g_lastseen (player %i (team %i) last seen in round %i of %i rounds)\n",
						player.getNum(), level.activeTeam, player.lastSeen, level.actualRound);
				G_MatchEndTrigger(-1, 0);
			}
		}
	}

	/* let all the invisible players perish now */
	G_CheckVisTeamAll(level.activeTeam, VIS_APPEAR, nullptr);

	G_GetNextActiveTeam();

	AI_CheckRespawn(TEAM_ALIEN);

	/* no other team left? */
	if (!G_MatchIsRunning())
		return;

	if (lastTeamIndex > (level.activeTeam + level.teamOfs) % MAX_TEAMS)
		level.actualRound++;

	/* communicate next player in row to clients */
	G_EventEndRound();

	/* store the round start time to be able to abort the round after a give time */
	level.roundstartTime = level.time;

	/* Wounded team members bleed */
	G_BleedWounds(level.activeTeam);

	/* Update the state of stuned team-members. The actual statistics are sent below! */
	G_UpdateStunState(level.activeTeam);

	/* Give the actors of the now active team their TUs. */
	G_GiveTimeUnits(level.activeTeam);

	/* apply morale behaviour, reset reaction fire */
	G_ReactionFireReset(level.activeTeam);
	if (mor_panic->integer)
		G_MoraleBehaviour(level.activeTeam);

	G_UpdateCarriedWeight(level.activeTeam);

	/* start ai - there is only one player for ai teams, and the last pointer must only
	 * be updated for ai players */
	p = G_GetPlayerForTeam(level.activeTeam);
	if (p == nullptr)
		gi.Error("Could not find player for team %i", level.activeTeam);

	/* finish off events */
	G_EventEnd();

	/* reset ready flag for every player on the current team (even ai players) */
	p = nullptr;
	while ((p = G_PlayerGetNextActiveHuman(p))) {
		if (p->getTeam() == level.activeTeam) {
			p->roundDone = false;
		}
	}

	p = nullptr;
	while ((p = G_PlayerGetNextActiveAI(p))) {
		if (p->getTeam() == level.activeTeam) {
			p->roundDone = false;
		}
	}
}