*/
#include "quakedef.h"
+#include "sv_demo.h"
int current_skill;
cvar_t sv_cheats = {0, "sv_cheats", "0", "enables cheat commands in any game, and cheat impulses in dpmod"};
#define SAVEGAME_VERSION 5
-/*
-===============
-Host_SavegameComment
-
-Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current
-===============
-*/
-void Host_SavegameComment (char *text)
-{
- int i;
- char kills[20];
-
- for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
- text[i] = ' ';
- // LordHavoc: added min() to prevent overflow
- memcpy (text, cl.levelname, min(strlen(cl.levelname), SAVEGAME_COMMENT_LENGTH));
- sprintf (kills,"kills:%3i/%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
- memcpy (text+22, kills, strlen(kills));
- // convert space to _ to make stdio happy
- // LordHavoc: convert control characters to _ as well
- for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
- if (text[i] <= ' ')
- text[i] = '_';
- text[SAVEGAME_COMMENT_LENGTH] = '\0';
-}
-
-
/*
===============
Host_Savegame_f
int i;
char comment[SAVEGAME_COMMENT_LENGTH+1];
- if (cls.state != ca_connected || !sv.active)
+ if (!sv.active)
{
- Con_Print("Not playing a local game.\n");
+ Con_Print("Can't save - no server running.\n");
return;
}
- if (cl.intermission)
+ if (cl.islocalgame)
{
- Con_Print("Can't save in intermission.\n");
- return;
- }
+ // singleplayer checks
+ if (cl.intermission)
+ {
+ Con_Print("Can't save in intermission.\n");
+ return;
+ }
- for (i = 0;i < svs.maxclients;i++)
- {
- if (svs.clients[i].active)
+ if (svs.clients[0].active && svs.clients[0].edict->fields.server->deadflag)
{
- if (i > 0)
- {
- Con_Print("Can't save multiplayer games.\n");
- return;
- }
- if (svs.clients[i].edict->fields.server->deadflag)
- {
- Con_Print("Can't savegame with a dead player\n");
- return;
- }
+ Con_Print("Can't savegame with a dead player\n");
+ return;
}
}
+ else
+ Con_Print("Warning: saving a multiplayer game may have strange results when restored (to properly resume, all players must join in the same player slots and then the game can be reloaded).\n");
if (Cmd_Argc() != 2)
{
return;
}
+ SV_VM_Begin();
+
FS_Printf(f, "%i\n", SAVEGAME_VERSION);
- Host_SavegameComment (comment);
+
+ memset(comment, 0, sizeof(comment));
+ sprintf(comment, "%-21s kills:%3i/%3i", PRVM_GetString(prog->edicts->fields.server->message), (int)prog->globals.server->killed_monsters, (int)prog->globals.server->total_monsters);
+ // convert space to _ to make stdio happy
+ // LordHavoc: convert control characters to _ as well
+ for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
+ if (comment[i] <= ' ')
+ comment[i] = '_';
+ comment[SAVEGAME_COMMENT_LENGTH] = '\0';
+
FS_Printf(f, "%s\n", comment);
for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
FS_Printf(f, "%f\n", svs.clients[0].spawn_parms[i]);
FS_Print(f,"m\n");
}
- SV_VM_Begin();
-
PRVM_ED_WriteGlobals (f);
for (i=0 ; i<prog->num_edicts ; i++)
PRVM_ED_Write (f, PRVM_EDICT_NUM(i));
}
// version
- COM_ParseToken_Simple(&t, false);
+ COM_ParseToken_Simple(&t, false, false);
version = atoi(com_token);
if (version != SAVEGAME_VERSION)
{
}
// description
- COM_ParseToken_Simple(&t, false);
+ COM_ParseToken_Simple(&t, false, false);
for (i = 0;i < NUM_SPAWN_PARMS;i++)
{
- COM_ParseToken_Simple(&t, false);
+ COM_ParseToken_Simple(&t, false, false);
spawn_parms[i] = atof(com_token);
}
// skill
- COM_ParseToken_Simple(&t, false);
+ COM_ParseToken_Simple(&t, false, false);
// this silliness is so we can load 1.06 save files, which have float skill values
current_skill = (int)(atof(com_token) + 0.5);
Cvar_SetValue ("skill", (float)current_skill);
// mapname
- COM_ParseToken_Simple(&t, false);
+ COM_ParseToken_Simple(&t, false, false);
strlcpy (mapname, com_token, sizeof(mapname));
// time
- COM_ParseToken_Simple(&t, false);
+ COM_ParseToken_Simple(&t, false, false);
time = atof(com_token);
allowcheats = sv_cheats.integer != 0;
{
// light style
oldt = t;
- COM_ParseToken_Simple(&t, false);
+ COM_ParseToken_Simple(&t, false, false);
// if this is a 64 lightstyle savegame produced by Quake, stop now
// we have to check this because darkplaces saves 256 lightstyle savegames
if (com_token[0] == '{')
for(;;)
{
oldt = t;
- COM_ParseToken_Simple(&t, false);
+ COM_ParseToken_Simple(&t, false, false);
if (com_token[0] == '{')
{
t = oldt;
for (;;)
{
start = t;
- while (COM_ParseToken_Simple(&t, false))
+ while (COM_ParseToken_Simple(&t, false, false))
if (!strcmp(com_token, "}"))
break;
- if (!COM_ParseToken_Simple(&start, false))
+ if (!COM_ParseToken_Simple(&start, false, false))
{
// end of file
break;
SV_VM_End();
// make sure we're connected to loopback
- if (cls.state == ca_disconnected || !(cls.state == ca_connected && cls.netcon != NULL && LHNETADDRESS_GetAddressType(&cls.netcon->peeraddress) == LHNETADDRESSTYPE_LOOP))
+ if (sv.active && cls.state == ca_disconnected)
CL_EstablishConnection("local:1");
}
MSG_WriteByte (&sv.reliable_datagram, svc_updatename);
MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients);
MSG_WriteString (&sv.reliable_datagram, host_client->name);
+ SV_WriteNetnameIntoDemo(host_client);
}
}
if (Cmd_Argc() > 2)
{
message = Cmd_Args();
- COM_ParseToken_Simple(&message, false);
+ COM_ParseToken_Simple(&message, false, false);
if (byNumber)
{
message++; // skip the #