Esempio n. 1
0
/*
 * @brief
 */
static void G_BeginIntermission(const char *map) {
	int32_t 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->locals.health <= 0)
			G_ClientRespawn(client, false);
	}

	// find an intermission spot
	ent = G_Find(NULL, EOFS(class_name), "info_player_intermission");
	if (!ent) { // map does not have an intermission point
		ent = G_Find(NULL, EOFS(class_name), "info_player_start");
		if (!ent)
			ent = G_Find(NULL, EOFS(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"), ATTEN_NORM);

	// stay on same level if not provided
	g_level.changemap = map && *map ? map : g_level.name;
}
Esempio n. 2
0
/**
 * @brief Support function to allow chaingun maps to work nicely
 */
static void G_weapon_chaingun(g_entity_t *ent) {

	// see if we already have one ready, this is just to keep this BS self-contained
	g_entity_t *cg = NULL;
	
	while ((cg = G_Find(cg, EOFS(class_name), "weapon_chaingun"))) {
		if (cg->locals.Think) {
			return; // think will destroy us later
		}
	}

	ent->locals.Think = G_weapon_chaingun_Think;
	ent->locals.next_think = g_level.time + 1; // do it after spawnentities
	ent->locals.move_type = MOVE_TYPE_THINK;
}
Esempio n. 3
0
/**
 * @brief Actually does the magic
 */
static void G_weapon_chaingun_Think(g_entity_t *ent) {

	g_entity_t *cg = NULL;
	
	while ((cg = G_Find(cg, EOFS(class_name), "weapon_chaingun"))) {

		// spawn a lightning gun where we are
		g_entity_t *lg = G_AllocEntity_(g_media.items.weapons[WEAPON_LIGHTNING]->class_name);
		VectorCopy(cg->s.origin, lg->s.origin);
		VectorCopy(cg->s.angles, lg->s.angles);
		lg->locals.spawn_flags = cg->locals.spawn_flags;

		G_SpawnItem(lg, g_media.items.weapons[WEAPON_LIGHTNING]);

		// replace nearby bullets with bolts
		g_entity_t *ammo = NULL;

		while ((ammo = G_FindRadius(ammo, lg->s.origin, 128.0))) {
			if (ammo->locals.item && ammo->locals.item == g_media.items.ammo[AMMO_BULLETS]) {

				// hello bolts
				g_entity_t *bolts = G_AllocEntity_(g_media.items.ammo[AMMO_BOLTS]->class_name);
				VectorCopy(ammo->s.origin, bolts->s.origin);
				VectorCopy(ammo->s.angles, bolts->s.angles);
				bolts->locals.spawn_flags = ammo->locals.spawn_flags;

				G_SpawnItem(bolts, g_media.items.ammo[AMMO_BOLTS]);

				// byebye bullets
				G_FreeEntity(ammo);
			}
		}

		// byebye chaingun
		G_FreeEntity(cg);
	}
}
Esempio n. 4
0
/**
 * @brief Set up the list of spawn points.
 */
static void G_InitSpawnPoints(void) {

	// first, set up all of the deathmatch points
	GSList *dm_spawns = NULL;
	g_entity_t *spot = NULL;
	
	while ((spot = G_Find(spot, EOFS(class_name), "info_player_deathmatch")) != NULL) {
		dm_spawns = g_slist_prepend(dm_spawns, spot);
	}

	spot = NULL;

	// for legacy maps
	if (!g_slist_length(dm_spawns)) {

		while ((spot = G_Find(spot, EOFS(class_name), "info_player_start")) != NULL) {
			dm_spawns = g_slist_prepend(dm_spawns, spot);
		}
	}
	
	// find the team points, if we have any explicit ones in the map.
	// start by finding the flags
	for (int32_t t = 0; t < MAX_TEAMS; t++) {
		g_teamlist[t].flag_entity = G_Find(NULL, EOFS(class_name), g_teamlist[t].flag);
	}

	GSList *team_spawns[MAX_TEAMS];

	memset(team_spawns, 0, sizeof(team_spawns));

	spot = NULL;

	while ((spot = G_Find(spot, EOFS(class_name), "info_player_team_any")) != NULL) {
		for (int32_t t = 0; t < MAX_TEAMS; t++) {
			team_spawns[t] = g_slist_prepend(team_spawns[t], spot);
		}
	}

	for (int32_t t = 0; t < MAX_TEAMS; t++) {
		spot = NULL;
		g_team_t *team = &g_teamlist[t];

		while ((spot = G_Find(spot, EOFS(class_name), team->spawn)) != NULL) {
			team_spawns[t] = g_slist_prepend(team_spawns[t], spot);
		}

		team->spawn_points.count = g_slist_length(team_spawns[t]);
	}

	// only one team
	if (!!g_team_red->spawn_points.count != !!g_team_blue->spawn_points.count) {
		gi.Error("Map has spawns for only a single team. Use info_player_deathmatch for these!\n");
	}

	g_level.spawn_points.count = g_slist_length(dm_spawns);

	GSList *point = NULL;

	// in the odd case that the map only has team spawns, we'll use them
	if (!g_level.spawn_points.count) {
		for (int32_t t = 0; t < MAX_TEAMS; t++) {
			for (point = team_spawns[t]; point; point = point->next) {
				dm_spawns = g_slist_prepend(dm_spawns, (g_entity_t *) point->data);
			}
		}
		
		g_level.spawn_points.count = g_slist_length(dm_spawns);

		if (!g_level.spawn_points.count) {
			gi.Error("Map has no spawn points! You need some info_player_deathmatch's (or info_player_team1/2/3/4/_any for teamplay maps).\n");
		}
	}

	// if we have team spawns, copy them over
	if (!g_team_red->spawn_points.count) {

		// none in the map, let's make some!
		G_CreateTeamSpawnPoints(&dm_spawns, &team_spawns[TEAM_RED], &team_spawns[TEAM_BLUE]);

		// re-calculate final values since the above may change them
		for (int32_t t = 0; t < MAX_TEAMS; t++) {
			g_teamlist[t].spawn_points.count = g_slist_length(team_spawns[t]);
		}

		g_level.spawn_points.count = g_slist_length(dm_spawns);
	}

	// copy all the data in!
	size_t i;

	for (int32_t t = 0; t < MAX_TEAMS; t++) {
		g_teamlist[t].spawn_points.spots = gi.Malloc(sizeof(g_entity_t *) * g_teamlist[t].spawn_points.count, MEM_TAG_GAME_LEVEL);
	
		for (i = 0, point = team_spawns[t]; point; point = point->next, i++) {
			g_teamlist[t].spawn_points.spots[i] = (g_entity_t *) point->data;
		}
	
		g_slist_free(team_spawns[t]);
	}
	
	g_level.spawn_points.spots = gi.Malloc(sizeof(g_entity_t *) * g_level.spawn_points.count, MEM_TAG_GAME_LEVEL);

	for (i = 0, point = dm_spawns; point; point = point->next, i++) {
		g_level.spawn_points.spots[i] = (g_entity_t *) point->data;
	}

	g_slist_free(dm_spawns);

	G_InitNumTeams();
}
Esempio n. 5
0
	F_INT,
	F_FLOAT,
	F_STRING, // string on disk, pointer in memory, TAG_LEVEL
	F_VECTOR,
	F_ANGLE
} g_field_type_t;

typedef struct g_field_s {
	char *name;
	ptrdiff_t ofs;
	g_field_type_t type;
	int32_t flags;
} g_field_t;

static const g_field_t fields[] = {
	{ "classname", EOFS(class_name), F_STRING, 0 },
	{ "model", EOFS(model), F_STRING, 0 },
	{ "spawnflags", LOFS(spawn_flags), F_INT, 0 },
	{ "speed", LOFS(speed), F_FLOAT, 0 },
	{ "accel", LOFS(accel), F_FLOAT, 0 },
	{ "decel", LOFS(decel), F_FLOAT, 0 },
	{ "target", LOFS(target), F_STRING, 0 },
	{ "targetname", LOFS(target_name), F_STRING, 0 },
	{ "pathtarget", LOFS(path_target), F_STRING, 0 },
	{ "killtarget", LOFS(kill_target), F_STRING, 0 },
	{ "message", LOFS(message), F_STRING, 0 },
	{ "team", LOFS(team), F_STRING, 0 },
	{ "command", LOFS(command), F_STRING, 0 },
	{ "script", LOFS(script), F_STRING, 0 },
	{ "wait", LOFS(wait), F_FLOAT, 0 },
	{ "delay", LOFS(delay), F_FLOAT, 0 },