Example #1
0
static void G_Players_f (const player_t *player)
{
    int count = 0;
    char smallBuf[64];
    char largeBuf[1280];
    player_t *p;

    /* print information */
    largeBuf[0] = 0;

    p = NULL;
    while ((p = G_PlayerGetNextActiveHuman(p))) {
        Com_sprintf(smallBuf, sizeof(smallBuf), "(%i) Team %i %s status: %s\n", p->num,
                    p->pers.team, p->pers.netname, (p->roundDone ? "waiting" : "playing"));

        /* can't print all of them in one packet */
        if (strlen(smallBuf) + strlen(largeBuf) > sizeof(largeBuf) - 100) {
            Q_strcat(largeBuf, "...\n", sizeof(largeBuf));
            break;
        }
        Q_strcat(largeBuf, smallBuf, sizeof(largeBuf));
        count++;
    }

    G_ClientPrintf(player, PRINT_CONSOLE, "%s\n%i players\n", largeBuf, count);
}
Example #2
0
/**
 * @brief Chose a team that should start the match
 * @param[in] player In singleplayer mode the team of this player will get the first turn
 * @sa SVCmd_StartGame_f
 */
static void G_GetStartingTeam (const player_t* player)
{
	int teamCount;
	int playerCount;
	int knownTeams[MAX_TEAMS];
	player_t *p;

	/* return with no action if activeTeam already assigned or if are in single-player mode */
	if (G_MatchIsRunning())
		return;

	if (sv_maxclients->integer == 1) {
		level.activeTeam = player->pers.team;
		level.teamOfs = MAX_TEAMS - level.activeTeam;
		return;
	}

	/* count number of currently connected unique teams and players (human controlled players only) */
	p = NULL;
	teamCount = 0;
	playerCount = 0;
	while ((p = G_PlayerGetNextActiveHuman(p))) {
		int j;
		playerCount++;
		for (j = 0; j < teamCount; j++) {
			if (p->pers.team == knownTeams[j])
				break;
		}
		if (j == teamCount)
			knownTeams[teamCount++] = p->pers.team;
	}

	if (teamCount) {
		const int teamIndex = (int) (frand() * (teamCount - 1) + 0.5);
		G_PrintStats("Starting new game: %s with %i teams", level.mapname, teamCount);
		level.activeTeam = knownTeams[teamIndex];
		level.teamOfs = MAX_TEAMS - level.activeTeam;
		p = NULL;
		while ((p = G_PlayerGetNextActiveHuman(p)))
			if (p->pers.team != level.activeTeam)
				p->roundDone = true;
	}
}
Example #3
0
/**
 * @brief Check whether a forced turn end should be executed
 */
void G_CheckForceEndRound (void)
{
	/* check for roundlimits in multiplayer only */
	if (!sv_roundtimelimit->integer || G_IsSinglePlayer())
		return;

	if (!G_MatchIsRunning())
		return;

	if (level.time != ceil(level.time))
		return;

	const int diff = level.roundstartTime + sv_roundtimelimit->integer - level.time;
	switch (diff) {
	case 240:
		gi.BroadcastPrintf(PRINT_HUD, _("4 minutes left until forced turn end."));
		return;
	case 180:
		gi.BroadcastPrintf(PRINT_HUD, _("3 minutes left until forced turn end."));
		return;
	case 120:
		gi.BroadcastPrintf(PRINT_HUD, _("2 minutes left until forced turn end."));
		return;
	case 60:
		gi.BroadcastPrintf(PRINT_HUD, _("1 minute left until forced turn end."));
		return;
	case 30:
		gi.BroadcastPrintf(PRINT_HUD, _("30 seconds left until forced turn end."));
		return;
	case 15:
		gi.BroadcastPrintf(PRINT_HUD, _("15 seconds left until forced turn end."));
		return;
	}

	/* active team still has time left */
	if (level.time < level.roundstartTime + sv_roundtimelimit->integer)
		return;

	gi.BroadcastPrintf(PRINT_HUD, _("Current active team hit the max round time."));

	/* store this in a local variable, as the global variable is changed in G_ClientEndRound */
	const int activeTeam = level.activeTeam;
	/* set all team members to ready (only human players) */
	Player* p = nullptr;
	while ((p = G_PlayerGetNextActiveHuman(p))) {
		if (p->getTeam() == activeTeam) {
			G_ClientEndRound(*p);
			level.nextEndRound = level.framenum;
		}
	}

	level.roundstartTime = level.time;
}
Example #4
0
/**
 * @brief Converts player mask to vis mask
 * @param[in] playerMask The player bit mask (contains the player numbers) that
 * is converted to a vis mask
 * @return Returns a vis mask for all the teams of the connected players that
 * are marked in the given @c playerMask.
 */
teammask_t G_PMToVis (playermask_t playerMask)
{
	player_t *p;
	teammask_t teamMask = 0;

	/* don't handle the ai players, here */
	p = NULL;
	while ((p = G_PlayerGetNextActiveHuman(p))) {
		if (playerMask & G_PlayerToPM(p))
			teamMask |= G_TeamToVisMask(p->pers.team);
	}

	return teamMask;
}
Example #5
0
/**
 * @brief Converts vis mask to player mask
 * @param[in] vis_mask The visibility bit mask (contains the team numbers) that
 * is converted to a player mask
 * @return Returns a playermask for all the teams of the connected players that
 * are marked in the given @c vis_mask.
 */
unsigned int G_VisToPM (vismask_t vis_mask)
{
	player_t *p;
	unsigned int playerMask;

	playerMask = 0;

	/* don't handle the ai players, here */
	p = NULL;
	while ((p = G_PlayerGetNextActiveHuman(p))) {
		if (vis_mask & G_TeamToVisMask(p->pers.team))
			playerMask |= G_PlayerToPM(p);
	}

	return playerMask;
}
Example #6
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 #7
0
static void G_Say_f (player_t *player, bool arg0, bool team)
{
    char text[256];
    player_t *p;

    if (gi.Cmd_Argc() < 2 && !arg0)
        return;

    if (G_CheckFlood(player))
        return;

    if (!team)
        Com_sprintf(text, sizeof(text), "%s: ", player->pers.netname);
    else
        Com_sprintf(text, sizeof(text), "^B%s (team): ", player->pers.netname);

    if (arg0) {
        Q_strcat(text, gi.Cmd_Argv(0), sizeof(text));
        Q_strcat(text, " ", sizeof(text));
        Q_strcat(text, gi.Cmd_Args(), sizeof(text));
    } else {
        const char *p = gi.Cmd_Args();
        const char *token = Com_Parse(&p);

        Q_strcat(text, token, sizeof(text));
    }

    Q_strcat(text, "\n", sizeof(text));

    if (sv_dedicated->integer)
        gi.DPrintf("%s", text);

    p = NULL;
    while ((p = G_PlayerGetNextActiveHuman(p))) {
        if (team && p->pers.team != player->pers.team)
            continue;
        G_ClientPrintf(p, PRINT_CHAT, "%s", text);
    }
}
Example #8
0
static void G_Say_f (Player& player, bool arg0, bool team)
{
	if (gi.Cmd_Argc() < 2 && !arg0)
		return;

	if (G_CheckFlood(player))
		return;

	char text[256];
	if (arg0) {
		Com_sprintf(text, sizeof(text), "%s %s", gi.Cmd_Argv(0), gi.Cmd_Args());
	} else {
		Com_sprintf(text, sizeof(text), "%s", gi.Cmd_Args());
	}

	/* strip quotes */
	char* s = text;
	if (s[0] == '"' && s[strlen(s) - 1] == '"') {
		s[strlen(s) - 1] = '\0';
		s++;
	}

	if (sv_dedicated->integer) {
		if (!team)
			gi.DPrintf("%s: %s\n", player.pers.netname, s);
		else
			gi.DPrintf("^B%s (team): %s\n", player.pers.netname, s);
	}

	Player* p = nullptr;
	while ((p = G_PlayerGetNextActiveHuman(p))) {
		if (team && p->getTeam() != player.getTeam())
			continue;
		if (!team)
			G_ClientPrintf(*p, PRINT_CHAT, "%s: %s\n", player.pers.netname, s);
		else
			G_ClientPrintf(*p, PRINT_CHAT, "^B%s (team): %s\n", player.pers.netname, s);
	}
}
Example #9
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 #10
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;
		}
	}
}