Пример #1
0
// changing levels within a unit
void Host_Changelevel2_f (void)
{
    char	level[MAX_QPATH];
    char	_startspot[MAX_QPATH];
    char	*startspot;

    if (Cmd_Argc() < 2)
    {
        Con_Printf ("changelevel2 <levelname> : continue game on a new level in the unit\n");
        return;
    }
    if (!sv.active || cls.demoplayback)
    {
        Con_Printf ("Only the server may changelevel\n");
        return;
    }

    strcpy (level, Cmd_Argv(1));
    if (Cmd_Argc() == 2)
        startspot = NULL;
    else
    {
        strcpy (_startspot, Cmd_Argv(2));
        startspot = _startspot;
    }

    SV_SaveSpawnparms ();

    // save the current level's state
    SaveGamestate ();

    // try to restore the new level
    if (LoadGamestate (level, startspot))
        SV_SpawnServer (level, startspot);
}
Пример #2
0
/*
==================
Host_Changelevel2_f

changing levels within a unit
==================
*/
static void Host_Changelevel2_f (void)
{
	char	level[MAX_QPATH];
	char	_startspot[MAX_QPATH];
	char	*startspot;

	if (Cmd_Argc() < 2)
	{
		Con_Printf ("changelevel2 <levelname> : continue game on a new level in the unit\n");
		return;
	}
	if (!sv.active || cls.demoplayback)
	{
		Con_Printf ("Only the server may changelevel\n");
		return;
	}

	q_snprintf (level, sizeof(level), "maps/%s.bsp", Cmd_Argv(1));
	if (!FS_FileExists(level, NULL))
		Host_Error ("%s: cannot find map %s", __thisfunc__, level);

	q_strlcpy (level, Cmd_Argv(1), sizeof(level));
	if (Cmd_Argc() == 2)
		startspot = NULL;
	else
	{
		q_strlcpy (_startspot, Cmd_Argv(2), sizeof(_startspot));
		startspot = _startspot;
	}

	SV_SaveSpawnparms ();

	// save the current level's state
	old_svtime = sv.time;
	if (SaveGamestate(false) != 0)
		return;

	// try to restore the new level
	if (LoadGamestate(level, startspot, 0) != 0)
	{
		SV_SpawnServer (level, startspot);
		if (!sv.active)
			Host_Error ("%s: cannot run map %s", __thisfunc__, level);
		RestoreClients (0);
	}
}
Пример #3
0
static void RestoreClients (int ClientsMode)
{
	int		i, j;
	edict_t		*ent;
	double		time_diff;

	if (LoadGamestate(NULL, NULL, 1) != 0)
		return;

/* O.S. -- mode 3 is only in response to the single player game "restart restore"
 * command issued by progs.dat::client.hc::respawn() function.  No level change,
 * just respawning in the same map with the same playtime from when clients.gip
 * was saved, therefore there _CANNOT_ be a time_diff.  See uhexen2 bug #2176023:
 * http://sourceforge.net/tracker/?group_id=124987&atid=701006&aid=2176023&func=detail
 */
	time_diff = (ClientsMode == 3) ? 0 : sv.time - old_svtime;

	for (i = 0, host_client = svs.clients; i < svs.maxclients; i++, host_client++)
	{
		if (host_client->active)
		{
			ent = host_client->edict;

			//ent->v.colormap = NUM_FOR_EDICT(ent);
			ent->v.team = (host_client->colors & 15) + 1;
			ent->v.netname = PR_SetEngineString(host_client->name);
			ent->v.playerclass = host_client->playerclass;

			// copy spawn parms out of the client_t
			for (j = 0; j < NUM_SPAWN_PARMS; j++)
				sv_globals.parm[j] = host_client->spawn_parms[j];
			// call the spawn function
			*sv_globals.time = sv.time;
			*sv_globals.self = EDICT_TO_PROG(ent);
			G_FLOAT(OFS_PARM0) = time_diff;
			PR_ExecuteProgram (*sv_globals.ClientReEnter);
		}
	}

	SaveGamestate (true);
}
Пример #4
0
/*
===============
Host_Savegame_f
===============
*/
static void Host_Savegame_f (void)
{
	FILE	*f;
	int		i, error_state;
	char		comment[SAVEGAME_COMMENT_LENGTH+1];
	const char	*p;

	if (cmd_source != src_command)
		return;

	if (!sv.active)
	{
		Con_Printf ("Not playing a local game.\n");
		return;
	}

	if (cl.intermission)
	{
		Con_Printf ("Can't save in intermission.\n");
		return;
	}

#ifndef TESTSAVE
	if (svs.maxclients != 1)
	{
		Con_Printf ("Can't save multiplayer games.\n");
		return;
	}
#endif

	if (Cmd_Argc() != 2)
	{
		Con_Printf ("save <savename> : save a game\n");
		return;
	}

	p = Cmd_Argv(1);
	if (*p == '.' || strstr(p, ".."))
	{
		Con_Printf ("Invalid save name.\n");
		return;
	}

	for (i = 0; i < svs.maxclients; i++)
	{
		if (svs.clients[i].active && (svs.clients[i].edict->v.health <= 0) )
		{
			Con_Printf ("Can't savegame with a dead player\n");
			return;
		}
	}

	error_state = SaveGamestate (false);
	// don't bother doing more if SaveGamestate failed
	if (error_state)
		return;

	FS_MakePath_BUF (FS_USERDIR, &error_state, savename, sizeof(savename), p);
	if (error_state)
	{
		Con_Printf ("%s: save directory name too long\n", __thisfunc__);
		return;
	}
	if (Sys_mkdir(savename, false) != 0)
	{
		Con_Printf ("Unable to create save directory\n");
		return;
	}

	Host_RemoveGIPFiles(savename);

	FS_MakePath_BUF (FS_USERDIR, NULL, savename, sizeof(savename), "clients.gip");
	Sys_unlink(savename);

	FS_MakePath_BUF (FS_USERDIR, NULL, savedest, sizeof(savedest), p);
	Con_Printf ("Saving game to %s...\n", savedest);

	error_state = Host_CopyFiles(FS_GetUserdir(), "*.gip", savedest);
	if (error_state)
		goto finish;

	FS_MakePath_VABUF (FS_USERDIR, &error_state, savedest, sizeof(savedest), "%s/info.dat", p);
	if (error_state)
	{
		Host_Error("%s: %d: string buffer overflow!", __thisfunc__, __LINE__);
		return;
	}
	f = fopen (savedest, "w");
	if (!f)
	{
		error_state = 1;
		Con_Printf ("%s: Unable to open %s for writing!\n", __thisfunc__, savedest);
		goto finish;
	}

	fprintf (f, "%i\n", SAVEGAME_VERSION);
	Host_SavegameComment (comment);
	fprintf (f, "%s\n", comment);
	for (i = 0; i < NUM_SPAWN_PARMS; i++)
		fprintf (f, "%f\n", svs.clients->spawn_parms[i]);
	fprintf (f, "%d\n", current_skill);
	fprintf (f, "%s\n", sv.name);
	fprintf (f, "%f\n", sv.time);
	fprintf (f, "%d\n", svs.maxclients);
	fprintf (f, "%f\n", deathmatch.value);
	fprintf (f, "%f\n", coop.value);
	fprintf (f, "%f\n", teamplay.value);
	fprintf (f, "%f\n", randomclass.value);
	fprintf (f, "%f\n", cl_playerclass.value);
	// mission pack, objectives strings
	fprintf (f, "%u\n", info_mask);
	fprintf (f, "%u\n", info_mask2);

	error_state = ferror(f);
	fclose(f);

finish:
	if (error_state)
		Host_Error ("%s: The game could not be saved properly!", __thisfunc__);
}