#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));
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");
}
0 change darkplaces menu: move all options into a submenu so that people won't keep ignoring the other submenus
0 change darkplaces networking: make darkplaces detect its *public* client port from master server and send that in nq connect messages (wallace)
0 change darkplaces protocol: PRYDON_CLIENTCURSOR should use a stat and .prydoncursor field instead of the cl_prydoncursor cvar, because stuffcmd is a bit icky (FrikaC)
+0 change darkplaces protocol: in dp8 protocol change clc_move to include a separate want-prediction flag rather than sending 0 movesequence for unpredicted moves, this will allow the client to know its own ping regardless of whether prediction is used.
0 change darkplaces protocol: increase maxplayers limit to 65535, send maxplayers as an int in the serverinfo packet, send colormap indices as a short, send svc_update* using short player indices (discoloda)
0 change darkplaces protocol: make svc_cdtrack use strings rather than a numbers in next DP protocol, so that named tracks can be used by maps
0 change darkplaces protocol: send origin and angle updates as individual components in entities like Quake did, rather than combined ORIGIN/ANGLE bits like DP5/6/7 do