Ejemplo n.º 1
0
/*
 * G_BeginIntermission
 */
static void G_BeginIntermission(const char *map) {
	int i;
	g_edict_t *ent, *client;

	if (g_level.intermission_time)
		return; // already activated

	g_level.intermission_time = g_level.time;

	// respawn any dead clients
	for (i = 0; i < sv_max_clients->integer; i++) {

		client = g_game.edicts + 1 + i;

		if (!client->in_use)
			continue;

		if (client->health <= 0)
			G_ClientRespawn(client, false);
	}

	// find an intermission spot
	ent = G_Find(NULL, FOFS(class_name), "info_player_intermission");
	if (!ent) { // map does not have an intermission point
		ent = G_Find(NULL, FOFS(class_name), "info_player_start");
		if (!ent)
			ent = G_Find(NULL, FOFS(class_name), "info_player_deathmatch");
	}

	VectorCopy(ent->s.origin, g_level.intermission_origin);
	VectorCopy(ent->s.angles, g_level.intermission_angle);

	// move all clients to the intermission point
	for (i = 0; i < sv_max_clients->integer; i++) {

		client = g_game.edicts + 1 + i;

		if (!client->in_use)
			continue;

		G_ClientToIntermission(client);
	}

	// play a dramatic sound effect
	gi.PositionedSound(g_level.intermission_origin, g_game.edicts,
			gi.SoundIndex("weapons/bfg/hit"), ATTN_NORM);

	// stay on same level if not provided
	g_level.changemap = map && *map ? map : g_level.name;
}
Ejemplo n.º 2
0
/*
 * G_CheckRules
 */
static void G_CheckRules(void) {
	int i, seconds;
	g_client_t *cl;

	if (g_level.intermission_time)
		return;

	// match mode, no match, or countdown underway
	g_level.warmup = g_level.match && (!g_level.match_time
			|| g_level.match_time > g_level.time);

	// arena mode, no round, or countdown underway
	g_level.warmup |= g_level.rounds && (!g_level.round_time
			|| g_level.round_time > g_level.time);

	if (g_level.start_match && g_level.time >= g_level.match_time) { // players have readied, begin match
		g_level.start_match = false;
		g_level.warmup = false;

		for (i = 0; i < sv_max_clients->integer; i++) {
			if (!g_game.edicts[i + 1].in_use)
				continue;
			G_ClientRespawn(&g_game.edicts[i + 1], false);
		}

		gi.Sound(&g_game.edicts[0], gi.SoundIndex("world/teleport"), ATTN_NONE);
		gi.BroadcastPrint(PRINT_HIGH, "Match has started\n");
	}

	if (g_level.start_round && g_level.time >= g_level.round_time) { // pre-game expired, begin round
		g_level.start_round = false;
		g_level.warmup = false;

		for (i = 0; i < sv_max_clients->integer; i++) {
			if (!g_game.edicts[i + 1].in_use)
				continue;
			G_ClientRespawn(&g_game.edicts[i + 1], false);
		}

		gi.Sound(&g_game.edicts[0], gi.SoundIndex("world/teleport"), ATTN_NONE);
		gi.BroadcastPrint(PRINT_HIGH, "Round has started\n");
	}

	seconds = g_level.time;

	if (g_level.rounds) {
		if (g_level.round_time > g_level.time) // round about to start, show pre-game countdown
			seconds = g_level.round_time - g_level.time;
		else if (g_level.round_time)
			seconds = g_level.time - g_level.round_time; // round started, count up
		else
			seconds = -1;
	} else if (g_level.match) {
		if (g_level.match_time > g_level.time) // match about to start, show pre-game countdown
			seconds = g_level.match_time - g_level.time;
		else if (g_level.match_time) {
			if (g_level.time_limit) // count down to time_limit
				seconds = g_level.match_time + g_level.time_limit * 60
						- g_level.time;
			else
				seconds = g_level.time - g_level.match_time; // count up
		} else
			seconds = -1;
	}

	if (g_level.time_limit) { // check time_limit
		float t = g_level.time;

		if (g_level.match) // for matches
			t = g_level.time - g_level.match_time;
		else if (g_level.rounds) // and for rounds
			t = g_level.time - g_level.round_time;

		if (t >= g_level.time_limit * 60) {
			gi.BroadcastPrint(PRINT_HIGH, "Timelimit hit\n");
			G_EndLevel();
			return;
		}
		seconds = g_level.time_limit * 60 - t; // count down
	}

	if (g_level.frame_num % gi.frame_rate == 0) // send time updates once per second
		gi.ConfigString(CS_TIME,
				(g_level.warmup ? "Warmup" : G_FormatTime(seconds)));

	if (!g_level.ctf && g_level.frag_limit) { // check frag_limit

		if (g_level.teams) { // check team scores
			if (g_team_good.score >= g_level.frag_limit ||
					g_team_evil.score >= g_level.frag_limit) {
				gi.BroadcastPrint(PRINT_HIGH, "Fraglimit hit\n");
				G_EndLevel();
				return;
			}
		} else { // or individual scores
			for (i = 0; i < sv_max_clients->integer; i++) {
				cl = g_game.clients + i;
				if (!g_game.edicts[i + 1].in_use)
					continue;

				if (cl->persistent.score >= g_level.frag_limit) {
					gi.BroadcastPrint(PRINT_HIGH, "Fraglimit hit\n");
					G_EndLevel();
					return;
				}
			}
		}
	}

	if (g_level.ctf && g_level.capture_limit) { // check capture limit

		if (g_team_good.captures >= g_level.capture_limit || g_team_evil.captures
				>= g_level.capture_limit) {
			gi.BroadcastPrint(PRINT_HIGH, "Capturelimit hit\n");
			G_EndLevel();
			return;
		}
	}

	if (g_gameplay->modified) { // change gameplay, fix items, respawn clients
		g_gameplay->modified = false;

		g_level.gameplay = G_GameplayByName(g_gameplay->string);
		gi.ConfigString(CS_GAMEPLAY, va("%d", g_level.gameplay));

		G_RestartGame(false); // reset all clients

		gi.BroadcastPrint(PRINT_HIGH, "Gameplay has changed to %s\n",
				G_GameplayName(g_level.gameplay));
	}

	if (g_gravity->modified) { // send gravity config string
		g_gravity->modified = false;

		g_level.gravity = g_gravity->integer;
		gi.ConfigString(CS_GRAVITY, va("%d", g_level.gravity));
	}

	if (g_teams->modified) { // reset teams, scores
		g_teams->modified = false;

		g_level.teams = g_teams->integer;
		gi.ConfigString(CS_TEAMS, va("%d", g_level.teams));

		gi.BroadcastPrint(PRINT_HIGH, "Teams have been %s\n",
				g_level.teams ? "enabled" : "disabled");

		G_RestartGame(true);
	}

	if (g_ctf->modified) { // reset teams, scores
		g_ctf->modified = false;

		g_level.ctf = g_ctf->integer;
		gi.ConfigString(CS_CTF, va("%d", g_level.ctf));

		gi.BroadcastPrint(PRINT_HIGH, "CTF has been %s\n",
				g_level.ctf ? "enabled" : "disabled");

		G_RestartGame(true);
	}

	if (g_match->modified) { // reset scores
		g_match->modified = false;

		g_level.match = g_match->integer;
		gi.ConfigString(CS_MATCH, va("%d", g_level.match));

		g_level.warmup = g_level.match; // toggle warmup

		gi.BroadcastPrint(PRINT_HIGH, "Match has been %s\n",
				g_level.match ? "enabled" : "disabled");

		G_RestartGame(false);
	}

	if (g_rounds->modified) { // reset scores
		g_rounds->modified = false;

		g_level.rounds = g_rounds->integer;
		gi.ConfigString(CS_ROUNDS, va("%d", g_level.rounds));

		g_level.warmup = g_level.rounds; // toggle warmup

		gi.BroadcastPrint(PRINT_HIGH, "Rounds have been %s\n",
				g_level.rounds ? "enabled" : "disabled");

		G_RestartGame(false);
	}

	if (g_cheats->modified) { // notify when cheats changes
		g_cheats->modified = false;

		gi.BroadcastPrint(PRINT_HIGH, "Cheats have been %s\n",
				g_cheats->integer ? "enabled" : "disabled");
	}

	if (g_frag_limit->modified) {
		g_frag_limit->modified = false;
		g_level.frag_limit = g_frag_limit->integer;

		gi.BroadcastPrint(PRINT_HIGH, "Fraglimit has been changed to %d\n",
				g_level.frag_limit);
	}

	if (g_round_limit->modified) {
		g_round_limit->modified = false;
		g_level.round_limit = g_round_limit->integer;

		gi.BroadcastPrint(PRINT_HIGH, "Roundlimit has been changed to %d\n",
				g_level.round_limit);
	}

	if (g_capture_limit->modified) {
		g_capture_limit->modified = false;
		g_level.capture_limit = g_capture_limit->integer;

		gi.BroadcastPrint(PRINT_HIGH, "Capturelimit has been changed to %d\n",
				g_level.capture_limit);
	}

	if (g_time_limit->modified) {
		g_time_limit->modified = false;
		g_level.time_limit = g_time_limit->value;

		gi.BroadcastPrint(PRINT_HIGH, "Timelimit has been changed to %d\n",
				(int) g_level.time_limit);
	}
}
Ejemplo n.º 3
0
/*
 * G_RestartGame
 *
 * For normal games, this just means reset scores and respawn.
 * For match games, this means cancel the match and force everyone
 * to ready again.  Teams are only reset when teamz is true.
 */
static void G_RestartGame(boolean_t teamz) {
	int i;
	g_edict_t *ent;
	g_client_t *cl;

	if (g_level.match_time)
		g_level.match_num++;

	if (g_level.round_time)
		g_level.round_num++;

	for (i = 0; i < sv_max_clients->integer; i++) { // reset clients

		if (!g_game.edicts[i + 1].in_use)
			continue;

		ent = &g_game.edicts[i + 1];
		cl = ent->client;

		cl->persistent.ready = false; // back to warmup
		cl->persistent.score = 0;
		cl->persistent.captures = 0;

		if (teamz) // reset teams
			cl->persistent.team = NULL;

		// determine spectator or team affiliations

		if (g_level.match) {
			if (cl->persistent.match_num == g_level.match_num)
				cl->persistent.spectator = false;
			else
				cl->persistent.spectator = true;
		}

		else if (g_level.rounds) {
			if (cl->persistent.round_num == g_level.round_num)
				cl->persistent.spectator = false;
			else
				cl->persistent.spectator = true;
		}

		if (g_level.teams || g_level.ctf) {

			if (!cl->persistent.team) {
				if (g_auto_join->value)
					G_AddClientToTeam(ent, G_SmallestTeam()->name);
				else
					cl->persistent.spectator = true;
			}
		}

		G_ClientRespawn(ent, false);
	}

	G_ResetItems();

	g_level.match_time = g_level.round_time = 0;
	g_team_good.score = g_team_evil.score = 0;
	g_team_good.captures = g_team_evil.captures = 0;

	gi.BroadcastPrint(PRINT_HIGH, "Game restarted\n");
	gi.Sound(&g_game.edicts[0], gi.SoundIndex("world/teleport"), ATTN_NONE);
}