]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - host_cmd.c
autocvars: update to current value after loading a savegame, to always fulfill the...
[xonotic/darkplaces.git] / host_cmd.c
index 635882da9a053ba1339fa79de81999355e01ce30..202e4d98837545e80f451366f854af79b9a7cca2 100644 (file)
@@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "sv_demo.h"
 #include "image.h"
 
+#include "utf8lib.h"
+
 // for secure rcon authentication
 #include "hmac.h"
 #include "mdfour.h"
@@ -172,8 +174,14 @@ void Host_Status_f (void)
                
                if (in == 0) // default layout
                {
-                       print ("#%-3u %-16.16s  %3i  %2i:%02i:%02i\n", i+1, client->name, frags, hours, minutes, seconds);
-                       print ("  %s\n", ip);
+                       // LordHavoc: we must use multiple prints for ProQuake compatibility
+                       print ("#%-3u ", i+1);
+                       print ("%-16.16s ", client->name);
+                       print ("%4i  ", frags);
+                       print ("%2i:%02i:%02i\n   ", hours, minutes, seconds);
+                       print ("%s\n", ip);
+//                     print ("#%-3u %-16.16s  %3i  %2i:%02i:%02i\n", i+1, client->name, frags, hours, minutes, seconds);
+//                     print ("   %s\n", ip);
                }
                else if (in == 1) // extended layout
                {
@@ -366,6 +374,8 @@ void Host_Map_f (void)
        }
 
        // remove menu
+       if (key_dest == key_menu || key_dest == key_menu_grabbed)
+               MR_ToggleMenu(0);
        key_dest = key_game;
 
        svs.serverflags = 0;                    // haven't completed an episode yet
@@ -399,6 +409,8 @@ void Host_Changelevel_f (void)
        }
 
        // remove menu
+       if (key_dest == key_menu || key_dest == key_menu_grabbed)
+               MR_ToggleMenu(0);
        key_dest = key_game;
 
        SV_VM_Begin();
@@ -434,6 +446,8 @@ void Host_Restart_f (void)
        }
 
        // remove menu
+       if (key_dest == key_menu || key_dest == key_menu_grabbed)
+               MR_ToggleMenu(0);
        key_dest = key_game;
 
        allowcheats = sv_cheats.integer != 0;
@@ -533,9 +547,11 @@ LOAD / SAVE GAME
 void Host_Savegame_to (const char *name)
 {
        qfile_t *f;
-       int             i, lightstyles = 64;
+       int             i, k, l, lightstyles = 64;
        char    comment[SAVEGAME_COMMENT_LENGTH+1];
+       char    line[MAX_INPUTLINE];
        qboolean isserver;
+       char    *s;
 
        // first we have to figure out if this can be saved in 64 lightstyles
        // (for Quake compatibility)
@@ -619,6 +635,51 @@ void Host_Savegame_to (const char *name)
        for (i=1 ; i<MAX_SOUNDS ; i++)
                if (sv.sound_precache[i][0])
                        FS_Printf(f,"sv.sound_precache %i %s\n", i, sv.sound_precache[i]);
+
+       // darkplaces extension - save buffers
+       for (i = 0; i < (int)Mem_ExpandableArray_IndexRange(&prog->stringbuffersarray); i++)
+       {
+               prvm_stringbuffer_t *stringbuffer = (prvm_stringbuffer_t*) Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i);
+               if(stringbuffer && (stringbuffer->flags & STRINGBUFFER_SAVED))
+               {
+                       for(k = 0; k < stringbuffer->num_strings; k++)
+                       {
+                               if (!stringbuffer->strings[k])
+                                       continue;
+                               // Parse the string a bit to turn special characters
+                               // (like newline, specifically) into escape codes
+                               s = stringbuffer->strings[k];
+                               for (l = 0;l < (int)sizeof(line) - 2 && *s;)
+                               {       
+                                       if (*s == '\n')
+                                       {
+                                               line[l++] = '\\';
+                                               line[l++] = 'n';
+                                       }
+                                       else if (*s == '\r')
+                                       {
+                                               line[l++] = '\\';
+                                               line[l++] = 'r';
+                                       }
+                                       else if (*s == '\\')
+                                       {
+                                               line[l++] = '\\';
+                                               line[l++] = '\\';
+                                       }
+                                       else if (*s == '"')
+                                       {
+                                               line[l++] = '\\';
+                                               line[l++] = '"';
+                                       }
+                                       else
+                                               line[l++] = *s;
+                                       s++;
+                               }
+                               line[l] = '\0';
+                               FS_Printf(f,"sv.bufstr %i %i \"%s\"\n", i, k, line);
+                       }
+               }
+       }
        FS_Printf(f,"*/\n");
 #endif
 
@@ -685,6 +746,7 @@ void Host_Savegame_f (void)
 Host_Loadgame_f
 ===============
 */
+
 void Host_Loadgame_f (void)
 {
        char filename[MAX_QPATH];
@@ -695,10 +757,12 @@ void Host_Loadgame_f (void)
        const char *t;
        char *text;
        prvm_edict_t *ent;
-       int i;
+       int i, k;
        int entnum;
        int version;
        float spawn_parms[NUM_SPAWN_PARMS];
+       prvm_stringbuffer_t *stringbuffer;
+       size_t alloclen;
 
        if (Cmd_Argc() != 2)
        {
@@ -716,6 +780,8 @@ void Host_Loadgame_f (void)
                CL_Disconnect ();
 
        // remove menu
+       if (key_dest == key_menu || key_dest == key_menu_grabbed)
+               MR_ToggleMenu(0);
        key_dest = key_game;
 
        cls.demonum = -1;               // stop demo loop in case this fails
@@ -829,6 +895,9 @@ void Host_Loadgame_f (void)
                }
        }
 
+       // unlink all entities
+       World_UnlinkAll(&sv.world);
+
 // load the edicts out of the savegame file
        end = t;
        for (;;)
@@ -855,6 +924,9 @@ void Host_Loadgame_f (void)
 
                        // parse the global vars
                        PRVM_ED_ParseGlobals (start);
+
+                       // restore the autocvar globals
+                       Cvar_UpdateAllAutoCvars();
                }
                else
                {
@@ -930,7 +1002,7 @@ void Host_Loadgame_f (void)
                                        if (i >= 0 && i < MAX_MODELS)
                                        {
                                                strlcpy(sv.model_precache[i], com_token, sizeof(sv.model_precache[i]));
-                                               sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, sv.model_precache[i][0] == '*' ? sv.modelname : NULL);
+                                               sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, sv.model_precache[i][0] == '*' ? sv.worldname : NULL);
                                        }
                                        else
                                                Con_Printf("unsupported model %i \"%s\"\n", i, com_token);
@@ -945,6 +1017,46 @@ void Host_Loadgame_f (void)
                                        else
                                                Con_Printf("unsupported sound %i \"%s\"\n", i, com_token);
                                }
+                               else if (!strcmp(com_token, "sv.bufstr"))
+                               {
+                                       COM_ParseToken_Simple(&t, false, false);
+                                       i = atoi(com_token);
+                                       COM_ParseToken_Simple(&t, false, false);
+                                       k = atoi(com_token);
+                                       COM_ParseToken_Simple(&t, false, false);
+                                       stringbuffer = (prvm_stringbuffer_t*) Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i);
+                                       // VorteX: nasty code, cleanup required
+                                       // create buffer at this index
+                                       if(!stringbuffer) 
+                                               stringbuffer = (prvm_stringbuffer_t *) Mem_ExpandableArray_AllocRecordAtIndex(&prog->stringbuffersarray, i);
+                                       if (!stringbuffer)
+                                               Con_Printf("cant write string %i into buffer %i\n", k, i);
+                                       else
+                                       {
+                                               // code copied from VM_bufstr_set
+                                               // expand buffer
+                                               if (stringbuffer->max_strings <= i)
+                                               {
+                                                       char **oldstrings = stringbuffer->strings;
+                                                       stringbuffer->max_strings = max(stringbuffer->max_strings * 2, 128);
+                                                       while (stringbuffer->max_strings <= i)
+                                                               stringbuffer->max_strings *= 2;
+                                                       stringbuffer->strings = (char **) Mem_Alloc(prog->progs_mempool, stringbuffer->max_strings * sizeof(stringbuffer->strings[0]));
+                                                       if (stringbuffer->num_strings > 0)
+                                                               memcpy(stringbuffer->strings, oldstrings, stringbuffer->num_strings * sizeof(stringbuffer->strings[0]));
+                                                       if (oldstrings)
+                                                               Mem_Free(oldstrings);
+                                               }
+                                               // allocate string
+                                               stringbuffer->num_strings = max(stringbuffer->num_strings, k + 1);
+                                               if(stringbuffer->strings[k])
+                                                       Mem_Free(stringbuffer->strings[k]);
+                                               stringbuffer->strings[k] = NULL;
+                                               alloclen = strlen(com_token) + 1;
+                                               stringbuffer->strings[k] = (char *)Mem_Alloc(prog->progs_mempool, alloclen);
+                                               memcpy(stringbuffer->strings[k], com_token, alloclen);
+                                       }
+                               }       
                                // skip any trailing text or unrecognized commands
                                while (COM_ParseToken_Simple(&t, true, false) && strcmp(com_token, "\n"))
                                        ;
@@ -1027,7 +1139,7 @@ void Host_Name_f (void)
                host_client->name[1] = '0' + STRING_COLOR_DEFAULT;
        }
 
-       COM_StringLengthNoColors(host_client->name, 0, &valid_colors);
+       u8_COM_StringLengthNoColors(host_client->name, 0, &valid_colors);
        if(!valid_colors) // NOTE: this also proves the string is not empty, as "" is a valid colored string
        {
                size_t l;
@@ -2764,7 +2876,7 @@ void Host_Pings_f (void)
 
 void Host_PingPLReport_f(void)
 {
-       char **errbyte;
+       char *errbyte;
        int i;
        int l = Cmd_Argc();
        if (l > cl.maxclients)