]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
fixed bug with effectinfo.txt loading so that it now loads the proper
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 10 May 2010 06:29:56 +0000 (06:29 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 10 May 2010 06:29:56 +0000 (06:29 +0000)
name for the map
added cl.worldmessage, cl.worldname, cl.worldbasename,
cl.worldnamenoextension strings (and sv. versions) as well as cvars

audited all use of these variables in the engine for consistent behavior
basename generation for maps now strips only maps/ prefix (allowing
subdirectory paths to be preserved)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10185 d7cf8633-e32d-0410-b094-e92efae38249

13 files changed:
cl_main.c
cl_parse.c
cl_particles.c
cl_screen.c
client.h
csprogs.c
gl_rmain.c
host_cmd.c
netconn.c
r_shadow.c
sbar.c
server.h
sv_main.c

index b6c293c0e525bb58c678ea2b30026e7c6a7c1e34..7d0a5f288f9e02f02e3d25e05b83d11cb244d3a6 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -2106,8 +2106,7 @@ void CL_Locs_Save_f(void)
                Con_Printf("No level loaded!\n");
                return;
        }
-       FS_StripExtension(cl.worldmodel->name, locfilename, sizeof(locfilename));
-       strlcat(locfilename, ".loc", sizeof(locfilename));
+       dpsnprintf(locfilename, sizeof(locfilename), "%s.loc", cl.worldnamenoextension);
 
        outfile = FS_OpenRealFile(locfilename, "w", false);
        if (!outfile)
@@ -2184,14 +2183,12 @@ void CL_Locs_Reload_f(void)
        CL_Locs_Clear_f();
 
        // try maps/something.loc first (LordHavoc: where I think they should be)
-       FS_StripExtension(cl.worldmodel->name, locfilename, sizeof(locfilename));
-       strlcat(locfilename, ".loc", sizeof(locfilename));
+       dpsnprintf(locfilename, sizeof(locfilename), "%s.loc", cl.worldnamenoextension);
        filedata = (char *)FS_LoadFile(locfilename, cls.levelmempool, false, &filesize);
        if (!filedata)
        {
                // try proquake name as well (LordHavoc: I hate path mangling)
-               FS_StripExtension(va("locs/%s", FS_FileWithoutPath(cl.worldmodel->name)), locfilename, sizeof(locfilename));
-               strlcat(locfilename, ".loc", sizeof(locfilename));
+               dpsnprintf(locfilename, sizeof(locfilename), "locs/%s.loc", cl.worldbasename);
                filedata = (char *)FS_LoadFile(locfilename, cls.levelmempool, false, &filesize);
                if (!filedata)
                        return;
index 63d49ab3142e7e9c57999f8df30fc827dc877ebb..93b8837db62a8a0987a0691bbce95e7581a55f3b 100644 (file)
@@ -160,6 +160,11 @@ char *qw_svc_strings[128] =
 
 //=============================================================================
 
+cvar_t cl_worldmessage = {CVAR_READONLY, "cl_worldmessage", "", "title of current level"};
+cvar_t cl_worldname = {CVAR_READONLY, "cl_worldname", "", "name of current worldmodel"};
+cvar_t cl_worldnamenoextension = {CVAR_READONLY, "cl_worldnamenoextension", "", "name of current worldmodel without extension"};
+cvar_t cl_worldbasename = {CVAR_READONLY, "cl_worldbasename", "", "name of current worldmodel without maps/ prefix or extension"};
+
 cvar_t demo_nehahra = {0, "demo_nehahra", "0", "reads all quake demos as nehahra movie protocol"};
 cvar_t developer_networkentities = {0, "developer_networkentities", "0", "prints received entities, value is 0-4 (higher for more info)"};
 cvar_t cl_gameplayfix_soundsmovewithentities = {0, "cl_gameplayfix_soundsmovewithentities", "1", "causes sounds made by lifts, players, projectiles, and any other entities, to move with the entity, so for example a rocket noise follows the rocket rather than staying at the starting position"};
@@ -441,11 +446,26 @@ static void CL_SetupWorldModel(void)
        cl.entities[0].render.model = cl.worldmodel = CL_GetModelByIndex(1);
        CL_UpdateRenderEntity(&cl.entities[0].render);
 
+       // make sure the cl.worldname and related cvars are set up now that we know the world model name
        // set up csqc world for collision culling
        if (cl.worldmodel)
-               World_SetSize(&cl.world, cl.worldmodel->name, cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
+       {
+               strlcpy(cl.worldname, cl.worldmodel->name, sizeof(cl.worldname));
+               FS_StripExtension(cl.worldname, cl.worldnamenoextension, sizeof(cl.worldnamenoextension));
+               strlcpy(cl.worldbasename, !strncmp(cl.worldnamenoextension, "maps/") ? cl.worldnamenoextension + 4 : cl.worldnamenoextension, sizeof(cl.worldbasename));
+               Cvar_SetQuick(&cl_worldmessage, cl.worldmessage);
+               Cvar_SetQuick(&cl_worldname, cl.worldname);
+               Cvar_SetQuick(&cl_worldnamenoextension, cl.worldnamenoextension);
+               Cvar_SetQuick(&cl_worldbasename, cl.worldbasename);
+               World_SetSize(&cl.world, cl.worldname, cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
+       }
        else
+       {
+               Cvar_SetQuick(&cl_worldmessage, cl.worldmessage);
+               Cvar_SetQuick(&cl_worldnamenoextension, "");
+               Cvar_SetQuick(&cl_worldbasename, "");
                World_SetSize(&cl.world, "", defaultmins, defaultmaxs);
+       }
        World_Start(&cl.world);
 
        // load or reload .loc file for team chat messages
@@ -1660,7 +1680,7 @@ void CL_ParseServerInfo (void)
 
                // get the full level name
                str = MSG_ReadString ();
-               strlcpy (cl.levelname, str, sizeof(cl.levelname));
+               strlcpy (cl.worldmessage, str, sizeof(cl.worldmessage));
 
                // get the movevars that are defined in the qw protocol
                cl.movevars_gravity            = MSG_ReadFloat();
@@ -1705,6 +1725,17 @@ void CL_ParseServerInfo (void)
                // note: on QW protocol we can't set up the gameworld until after
                // downloads finish...
                // (we don't even know the name of the map yet)
+               // this also means cl_autodemo does not work on QW protocol...
+
+               strlcpy(cl.worldname, "", sizeof(cl.worldname));
+               strlcpy(cl.worldnamenoextension, "", sizeof(cl.worldnamenoextension));
+               strlcpy(cl.worldbasename, "qw", sizeof(cl.worldbasename));
+               Cvar_SetQuick(&cl_worldname, cl.worldname);
+               Cvar_SetQuick(&cl_worldnamenoextension, cl.worldnamenoextension);
+               Cvar_SetQuick(&cl_worldbasename, cl.worldbasename);
+
+               // check memory integrity
+               Mem_CheckSentinelsGlobal();
        }
        else
        {
@@ -1726,7 +1757,7 @@ void CL_ParseServerInfo (void)
 
        // parse signon message
                str = MSG_ReadString ();
-               strlcpy (cl.levelname, str, sizeof(cl.levelname));
+               strlcpy (cl.worldmessage, str, sizeof(cl.worldmessage));
 
        // seperate the printfs so the server message can have a color
                if (cls.protocol != PROTOCOL_NEHAHRAMOVIE) // no messages when playing the Nehahra movie
@@ -1760,6 +1791,15 @@ void CL_ParseServerInfo (void)
                        strlcpy (cl.sound_name[numsounds], str, sizeof (cl.sound_name[numsounds]));
                }
 
+               // set the base name for level-specific things...  this gets updated again by CL_SetupWorldModel later
+               strlcpy(cl.worldname, cl.model_name[1], sizeof(cl.worldname));
+               FS_StripExtension(cl.worldname, cl.worldnamenoextension, sizeof(cl.worldnamenoextension));
+               strlcpy(cl.worldbasename, FS_FileWithoutPath(cl.worldnamenoextension), sizeof(cl.worldbasename));
+               Cvar_SetQuick(&cl_worldmessage, cl.worldmessage);
+               Cvar_SetQuick(&cl_worldname, cl.worldname);
+               Cvar_SetQuick(&cl_worldnamenoextension, cl.worldnamenoextension);
+               Cvar_SetQuick(&cl_worldbasename, cl.worldbasename);
+
                // touch all of the precached models that are still loaded so we can free
                // anything that isn't needed
                if (!sv.active)
@@ -1803,50 +1843,46 @@ void CL_ParseServerInfo (void)
                cl.loadbegun = false;
                cl.loadfinished = false;
                cl.loadcsqc = true;
-       }
-
-       // check memory integrity
-       Mem_CheckSentinelsGlobal();
 
-// if cl_autodemo is set, automatically start recording a demo if one isn't being recorded already
-       if (cl_autodemo.integer && cls.netcon && cls.protocol != PROTOCOL_QUAKEWORLD)
-       {
-               char demofile[MAX_OSPATH];
-               char levelname[MAX_QPATH];
+               // check memory integrity
+               Mem_CheckSentinelsGlobal();
 
-               if (cls.demorecording)
+       // if cl_autodemo is set, automatically start recording a demo if one isn't being recorded already
+               if (cl_autodemo.integer && cls.netcon && cls.protocol != PROTOCOL_QUAKEWORLD)
                {
-                       // finish the previous level's demo file
-                       CL_Stop_f();
-               }
+                       char demofile[MAX_OSPATH];
 
-               // start a new demo file
-               strlcpy(levelname, FS_FileWithoutPath(cl.model_name[1]), sizeof(levelname));
-               if (strrchr(levelname, '.'))
-                       *(strrchr(levelname, '.')) = 0;
-               dpsnprintf (demofile, sizeof(demofile), "%s_%s.dem", Sys_TimeString (cl_autodemo_nameformat.string), levelname);
+                       if (cls.demorecording)
+                       {
+                               // finish the previous level's demo file
+                               CL_Stop_f();
+                       }
 
-               Con_Printf ("Auto-recording to %s.\n", demofile);
+                       // start a new demo file
+                       dpsnprintf (demofile, sizeof(demofile), "%s_%s.dem", Sys_TimeString (cl_autodemo_nameformat.string), cl.worldbasename);
 
-               // Reset bit 0 for every new demo
-               Cvar_SetValueQuick(&cl_autodemo_delete,
-                       (cl_autodemo_delete.integer & ~0x1)
-                       |
-                       ((cl_autodemo_delete.integer & 0x2) ? 0x1 : 0)
-               );
+                       Con_Printf ("Auto-recording to %s.\n", demofile);
 
-               cls.demofile = FS_OpenRealFile(demofile, "wb", false);
-               if (cls.demofile)
-               {
-                       cls.forcetrack = -1;
-                       FS_Printf (cls.demofile, "%i\n", cls.forcetrack);
-                       cls.demorecording = true;
-                       strlcpy(cls.demoname, demofile, sizeof(cls.demoname));
-                       cls.demo_lastcsprogssize = -1;
-                       cls.demo_lastcsprogscrc = -1;
+                       // Reset bit 0 for every new demo
+                       Cvar_SetValueQuick(&cl_autodemo_delete,
+                               (cl_autodemo_delete.integer & ~0x1)
+                               |
+                               ((cl_autodemo_delete.integer & 0x2) ? 0x1 : 0)
+                       );
+
+                       cls.demofile = FS_OpenRealFile(demofile, "wb", false);
+                       if (cls.demofile)
+                       {
+                               cls.forcetrack = -1;
+                               FS_Printf (cls.demofile, "%i\n", cls.forcetrack);
+                               cls.demorecording = true;
+                               strlcpy(cls.demoname, demofile, sizeof(cls.demoname));
+                               cls.demo_lastcsprogssize = -1;
+                               cls.demo_lastcsprogscrc = -1;
+                       }
+                       else
+                               Con_Print ("ERROR: couldn't open.\n");
                }
-               else
-                       Con_Print ("ERROR: couldn't open.\n");
        }
 }
 
@@ -4135,6 +4171,11 @@ void CL_Parse_ErrorCleanUp(void)
 
 void CL_Parse_Init(void)
 {
+       Cvar_RegisterVariable(&cl_worldmessage);
+       Cvar_RegisterVariable(&cl_worldname);
+       Cvar_RegisterVariable(&cl_worldnamenoextension);
+       Cvar_RegisterVariable(&cl_worldbasename);
+
        // LordHavoc: added demo_nehahra cvar
        Cvar_RegisterVariable (&demo_nehahra);
        if (gamemode == GAME_NEHAHRA)
index a5b987eaae564254e5ec8d642421060754639be6..c33df7baf8b58af134f3d605ec37307e220184b7 100644 (file)
@@ -480,7 +480,11 @@ void CL_Particles_LoadEffectInfo(void)
                if (filepass == 0)
                        dpsnprintf(filename, sizeof(filename), "effectinfo.txt");
                else if (filepass == 1)
-                       dpsnprintf(filename, sizeof(filename), "maps/%s_effectinfo.txt", cl.levelname);
+               {
+                       if (!cl.worldbasename[0])
+                               continue;
+                       dpsnprintf(filename, sizeof(filename), "%s_effectinfo.txt", cl.worldnamenoextension);
+               }
                else
                        break;
                filedata = FS_LoadFile(filename, tempmempool, true, &filesize);
@@ -1520,13 +1524,12 @@ void CL_ReadPointFile_f (void)
        vec3_t org, leakorg;
        int r, c, s;
        char *pointfile = NULL, *pointfilepos, *t, tchar;
-       char name[MAX_OSPATH];
+       char name[MAX_QPATH];
 
        if (!cl.worldmodel)
                return;
 
-       FS_StripExtension (cl.worldmodel->name, name, sizeof (name));
-       strlcat (name, ".pts", sizeof (name));
+       dpsnprintf(name, sizeof(name), "%s.pts", cl.worldnamenoextension);
        pointfile = (char *)FS_LoadFile(name, tempmempool, true, NULL);
        if (!pointfile)
        {
index 76be67dc85efa1c15c02918524191c2ea9f8a60e..4121ae391cb2662a5cc83bb0dd4e9de738e6c416 100644 (file)
@@ -925,7 +925,6 @@ void SCR_ScreenShot_f (void)
        static char old_prefix_name[MAX_QPATH];
        char prefix_name[MAX_QPATH];
        char filename[MAX_QPATH];
-       char mapname[MAX_QPATH];
        unsigned char *buffer1;
        unsigned char *buffer2;
        qboolean jpeg = (scr_screenshot_jpeg.integer != 0);
@@ -960,15 +959,10 @@ void SCR_ScreenShot_f (void)
        else
        {
                // TODO maybe make capturevideo and screenshot use similar name patterns?
-               if (scr_screenshot_name_in_mapdir.integer && cl.worldmodel && *cl.worldmodel->name) {
-                       // figure out the map's filename without path or extension
-                       strlcpy(mapname, FS_FileWithoutPath(cl.worldmodel->name), sizeof(mapname));
-                       if (strrchr(mapname, '.'))
-                               *(strrchr(mapname, '.')) = 0;
-                       dpsnprintf (prefix_name, sizeof(prefix_name), "%s/%s", mapname, Sys_TimeString(scr_screenshot_name.string));
-               } else {
+               if (scr_screenshot_name_in_mapdir.integer && cl.worldbasename[0])
+                       dpsnprintf (prefix_name, sizeof(prefix_name), "%s/%s", cl.worldbasename, Sys_TimeString(scr_screenshot_name.string));
+               else
                        dpsnprintf (prefix_name, sizeof(prefix_name), "%s", Sys_TimeString(scr_screenshot_name.string));
-               }
 
                if (strcmp(old_prefix_name, prefix_name))
                {
index 3a7b69390d0fae1c852b96de07310516e5de960d..3ed504a39e9022f2974f6869d13b9446ac3c53e4 100644 (file)
--- a/client.h
+++ b/client.h
@@ -1011,7 +1011,11 @@ typedef struct client_state_s
        char sound_name[MAX_SOUNDS][MAX_QPATH];
 
        // for display on solo scoreboard
-       char levelname[40];
+       char worldmessage[40]; // map title (not related to filename)
+       // variants of map name
+       char worldbasename[MAX_QPATH]; // %s
+       char worldname[MAX_QPATH]; // maps/%s.bsp
+       char worldnamenoextension[MAX_QPATH]; // maps/%s
        // cl_entitites[cl.viewentity] = player
        int viewentity;
        // the real player entity (normally same as viewentity,
index bdb0e48561ac52d54ddbfa2b7f00fee9e7bf8da6..d417fa97ece0aae75c38c02f7f006e153c317ef0 100644 (file)
--- a/csprogs.c
+++ b/csprogs.c
@@ -976,13 +976,13 @@ void CL_VM_Init (void)
        prog->globals.client->time = cl.time;
        prog->globals.client->self = 0;
 
-       prog->globals.client->mapname = cl.worldmodel ? PRVM_SetEngineString(cl.worldmodel->name) : PRVM_SetEngineString("");
+       prog->globals.client->mapname = PRVM_SetEngineString(cl.worldname);
        prog->globals.client->player_localentnum = cl.playerentity;
 
        // set map description (use world entity 0)
        val = PRVM_EDICTFIELDVALUE(prog->edicts, prog->fieldoffsets.message);
        if(val)
-               val->string = PRVM_SetEngineString(cl.levelname);
+               val->string = PRVM_SetEngineString(cl.worldmessage);
        VectorCopy(cl.world.mins, prog->edicts->fields.client->mins);
        VectorCopy(cl.world.maxs, prog->edicts->fields.client->maxs);
 
index 2ae129dcb7f26c8f5aea4075e3dfeb3de1a38a69..d18c1a707306cd7917c57c513d69bf026ea9ddfc 100644 (file)
@@ -6297,7 +6297,6 @@ extern void CL_ParseEntityLump(char *entitystring);
 void gl_main_newmap(void)
 {
        // FIXME: move this code to client
-       int l;
        char *entities, entname[MAX_QPATH];
        if (r_qwskincache)
                Mem_Free(r_qwskincache);
@@ -6305,17 +6304,12 @@ void gl_main_newmap(void)
        r_qwskincache_size = 0;
        if (cl.worldmodel)
        {
-               strlcpy(entname, cl.worldmodel->name, sizeof(entname));
-               l = (int)strlen(entname) - 4;
-               if (l >= 0 && !strcmp(entname + l, ".bsp"))
+               dpsnprintf(entname, sizeof(entname), "%s.ent", cl.worldnamenoextension);
+               if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
                {
-                       memcpy(entname + l, ".ent", 5);
-                       if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
-                       {
-                               CL_ParseEntityLump(entities);
-                               Mem_Free(entities);
-                               return;
-                       }
+                       CL_ParseEntityLump(entities);
+                       Mem_Free(entities);
+                       return;
                }
                if (cl.worldmodel->brush.entities)
                        CL_ParseEntityLump(cl.worldmodel->brush.entities);
index 24111c58ccf9c396ae8793628cea9bd2eea843eb..f341d7d6e3fad00d0026d6b0e3bf54d4863b20a7 100644 (file)
@@ -999,7 +999,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);
index 2700ee4ae894ff58489539319e6946f825fba0d1..3f0796e54e9485027ae685c18c4f981cfc751412 100755 (executable)
--- a/netconn.c
+++ b/netconn.c
@@ -2213,7 +2213,7 @@ static qboolean NetConn_BuildStatusResponse(const char* challenge, char* out_msg
                                                "%s",
                                                fullstatus ? "statusResponse" : "infoResponse",
                                                gamename, com_modname, gameversion.integer, svs.maxclients,
-                                               nb_clients, nb_bots, sv.name, hostname.string, NET_PROTOCOL_VERSION,
+                                               nb_clients, nb_bots, sv.worldbasename, hostname.string, NET_PROTOCOL_VERSION,
                                                *qcstatus ? "\\qcstatus\\" : "", qcstatus,
                                                challenge ? "\\challenge\\" : "", challenge ? challenge : "",
                                                fullstatus ? "\n" : "");
index 445d0deab879c6d16992ceea0567f3c5c8ada24e..f546b146ca6bbd551b1d31ee9eac96a127cf7abc 100644 (file)
@@ -666,7 +666,7 @@ void r_shadow_newmap(void)
        if (r_editlights_sprcubemaplight)         R_SkinFrame_MarkUsed(r_editlights_sprcubemaplight);
        if (r_editlights_sprcubemapnoshadowlight) R_SkinFrame_MarkUsed(r_editlights_sprcubemapnoshadowlight);
        if (r_editlights_sprselection)            R_SkinFrame_MarkUsed(r_editlights_sprselection);
-       if (cl.worldmodel && strncmp(cl.worldmodel->name, r_shadow_mapname, sizeof(r_shadow_mapname)))
+       if (strncmp(cl.worldname, r_shadow_mapname, sizeof(r_shadow_mapname)))
                R_Shadow_EditLights_Reload_f();
 }
 
@@ -5001,8 +5001,7 @@ void R_Shadow_LoadWorldLights(void)
                Con_Print("No map loaded.\n");
                return;
        }
-       FS_StripExtension (cl.worldmodel->name, name, sizeof (name));
-       strlcat (name, ".rtlights", sizeof (name));
+       dpsnprintf(name, sizeof(name), "%s.rtlights", cl.worldnamenoextension);
        lightsstring = (char *)FS_LoadFile(name, tempmempool, false, NULL);
        if (lightsstring)
        {
@@ -5112,8 +5111,7 @@ void R_Shadow_SaveWorldLights(void)
                Con_Print("No map loaded.\n");
                return;
        }
-       FS_StripExtension (cl.worldmodel->name, name, sizeof (name));
-       strlcat (name, ".rtlights", sizeof (name));
+       dpsnprintf(name, sizeof(name), "%s.rtlights", cl.worldnamenoextension);
        bufchars = bufmaxchars = 0;
        buf = NULL;
        for (lightindex = 0;lightindex < range;lightindex++)
@@ -5161,8 +5159,7 @@ void R_Shadow_LoadLightsFile(void)
                Con_Print("No map loaded.\n");
                return;
        }
-       FS_StripExtension (cl.worldmodel->name, name, sizeof (name));
-       strlcat (name, ".lights", sizeof (name));
+       dpsnprintf(name, sizeof(name), "%s.lights", cl.worldnamenoextension);
        lightsstring = (char *)FS_LoadFile(name, tempmempool, false, NULL);
        if (lightsstring)
        {
@@ -5224,8 +5221,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
                return;
        }
        // try to load a .ent file first
-       FS_StripExtension (cl.worldmodel->name, key, sizeof (key));
-       strlcat (key, ".ent", sizeof (key));
+       dpsnprintf(key, sizeof(key), "%s.ent", cl.worldnamenoextension);
        data = entfiledata = (char *)FS_LoadFile(key, tempmempool, true, NULL);
        // and if that is not found, fall back to the bsp file entity string
        if (!data)
@@ -5474,7 +5470,7 @@ void R_Shadow_EditLights_Reload_f(void)
 {
        if (!cl.worldmodel)
                return;
-       strlcpy(r_shadow_mapname, cl.worldmodel->name, sizeof(r_shadow_mapname));
+       strlcpy(r_shadow_mapname, cl.worldname, sizeof(r_shadow_mapname));
        R_Shadow_ClearWorldLights();
        R_Shadow_LoadWorldLights();
        if (!Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray))
diff --git a/sbar.c b/sbar.c
index 81c72f8d55cffbae5db10494af1033e47ccbfbbd..e4390b6b86c15da145b7d3648163c46420ce6ca5 100644 (file)
--- a/sbar.c
+++ b/sbar.c
@@ -684,14 +684,8 @@ void Sbar_SoloScoreboard (void)
        else if (cl.stats[STAT_SECRETS]) // LA: And similarly for secrets
                Sbar_DrawString(8+22*8, 4, va("Secrets:%3i", cl.stats[STAT_SECRETS]));
 
-       // figure out the map's filename without path or extension
-       strlcpy(str, FS_FileWithoutPath(cl.worldmodel ? cl.worldmodel->name : ""), sizeof(str));
-       if (strrchr(str, '.'))
-               *(strrchr(str, '.')) = 0;
-
-       // append a : separator and then the full title
-       strlcat(str, ":", sizeof(str));
-       strlcat(str, cl.levelname, sizeof(str));
+       // format is like this: e1m1:The Sligpate Complex
+       dpsnprintf(str, sizeof(str), "%s:%s", cl.worldbasename, cl.worldmessage);
 
        // if there's a newline character, terminate the string there
        if (strchr(str, '\n'))
@@ -734,11 +728,11 @@ void Sbar_SoloScoreboard (void)
 
 // draw level name
        if (gamemode == GAME_NEXUIZ) {
-               l = (int) strlen (cl.worldmodel->name);
-               Sbar_DrawString (232 - l*4, 12, cl.worldmodel->name);
+               l = (int) strlen (cl.worldname);
+               Sbar_DrawString (232 - l*4, 12, cl.worldname);
        } else {
-               l = (int) strlen (cl.levelname);
-               Sbar_DrawString (232 - l*4, 12, cl.levelname);
+               l = (int) strlen (cl.worldmessage);
+               Sbar_DrawString (232 - l*4, 12, cl.worldmessage);
        }
 #endif
 }
index ad15e21f0bb0feeef21c85df66a0e41b786bdabd..fdea10760234675d7e8d8c8b9e98105893f865da 100644 (file)
--- a/server.h
+++ b/server.h
@@ -98,9 +98,12 @@ typedef struct server_s
        world_t world;
 
        /// map name
-       char name[64];
-       /// maps/<name>.bsp, for model_precache[0]
-       char modelname[64];
+       char name[64]; // %s followed by entrance name
+       // variants of map name
+       char worldmessage[40]; // map title (not related to filename)
+       char worldbasename[MAX_QPATH]; // %s
+       char worldname[MAX_QPATH]; // maps/%s.bsp
+       char worldnamenoextension[MAX_QPATH]; // maps/%s
        struct model_s *worldmodel;
        // NULL terminated
        // LordHavoc: precaches are now MAX_QPATH rather than a pointer
index 60f2dbe8e82d89a7e52e9e5a63222d447c3a50d8..69e6b065163189af5994f5747287a49ec9471491 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -33,6 +33,11 @@ extern cvar_t net_connecttimeout;
 void VM_CustomStats_Clear (void);
 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats);
 
+cvar_t sv_worldmessage = {CVAR_READONLY, "sv_worldmessage", "", "title of current level"};
+cvar_t sv_worldname = {CVAR_READONLY, "sv_worldname", "", "name of current worldmodel"};
+cvar_t sv_worldnamenoextension = {CVAR_READONLY, "sv_worldnamenoextension", "", "name of current worldmodel without extension"};
+cvar_t sv_worldbasename = {CVAR_READONLY, "sv_worldbasename", "", "name of current worldmodel without maps/ prefix or extension"};
+
 cvar_t coop = {0, "coop","0", "coop mode, 0 = no coop, 1 = coop mode, multiple players playing through the singleplayer game (coop mode also shuts off deathmatch)"};
 cvar_t deathmatch = {0, "deathmatch","0", "deathmatch mode, values depend on mod but typically 0 = no deathmatch, 1 = normal deathmatch with respawning weapons, 2 = weapons stay (players can only pick up new weapons)"};
 cvar_t fraglimit = {CVAR_NOTIFY, "fraglimit","0", "ends level if this many frags is reached by any player"};
@@ -340,6 +345,12 @@ void SV_Init (void)
        extern cvar_t csqc_progname;    //[515]: csqc crc check and right csprogs name according to progs.dat
        extern cvar_t csqc_progcrc;
        extern cvar_t csqc_progsize;
+
+       Cvar_RegisterVariable(&sv_worldmessage);
+       Cvar_RegisterVariable(&sv_worldname);
+       Cvar_RegisterVariable(&sv_worldnamenoextension);
+       Cvar_RegisterVariable(&sv_worldbasename);
+
        Cvar_RegisterVariable (&csqc_progname);
        Cvar_RegisterVariable (&csqc_progcrc);
        Cvar_RegisterVariable (&csqc_progsize);
@@ -531,14 +542,12 @@ void SV_Init (void)
 
 static void SV_SaveEntFile_f(void)
 {
-       char basename[MAX_QPATH];
        if (!sv.active || !sv.worldmodel)
        {
                Con_Print("Not running a server\n");
                return;
        }
-       FS_StripExtension(sv.worldmodel->name, basename, sizeof(basename));
-       FS_WriteFile(va("%s.ent", basename), sv.worldmodel->brush.entities, (fs_offset_t)strlen(sv.worldmodel->brush.entities));
+       FS_WriteFile(va("%s.ent", sv.worldnamenoextension), sv.worldmodel->brush.entities, (fs_offset_t)strlen(sv.worldmodel->brush.entities));
 }
 
 
@@ -835,20 +844,15 @@ void SV_SendServerinfo (client_t *client)
        if(sv_autodemo_perclient.integer && client->netconnection)
        {
                char demofile[MAX_OSPATH];
-               char levelname[MAX_QPATH];
                char ipaddress[MAX_QPATH];
                size_t i;
 
                // start a new demo file
-               strlcpy(levelname, FS_FileWithoutPath(sv.worldmodel->name), sizeof(levelname));
-               if (strrchr(levelname, '.'))
-                       *(strrchr(levelname, '.')) = 0;
-
                LHNETADDRESS_ToString(&(client->netconnection->peeraddress), ipaddress, sizeof(ipaddress), true);
                for(i = 0; ipaddress[i]; ++i)
                        if(!isalnum(ipaddress[i]))
                                ipaddress[i] = '-';
-               dpsnprintf (demofile, sizeof(demofile), "%s_%s_%d_%s.dem", Sys_TimeString (sv_autodemo_perclient_nameformat.string), levelname, PRVM_NUM_FOR_EDICT(client->edict), ipaddress);
+               dpsnprintf (demofile, sizeof(demofile), "%s_%s_%d_%s.dem", Sys_TimeString (sv_autodemo_perclient_nameformat.string), sv.worldbasename, PRVM_NUM_FOR_EDICT(client->edict), ipaddress);
 
                SV_StartDemoRecording(client, demofile, -1);
        }
@@ -2718,7 +2722,7 @@ int SV_ModelIndex(const char *s, int precachemode)
                                if (precachemode == 1)
                                        Con_Printf("SV_ModelIndex(\"%s\"): not precached (fix your code), precaching anyway\n", filename);
                                strlcpy(sv.model_precache[i], filename, sizeof(sv.model_precache[i]));
-                               sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, s[0] == '*' ? sv.modelname : NULL);
+                               sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, s[0] == '*' ? sv.worldname : NULL);
                                if (sv.state != ss_loading)
                                {
                                        MSG_WriteByte(&sv.reliable_datagram, svc_precache);
@@ -2813,7 +2817,7 @@ int SV_ParticleEffectIndex(const char *name)
                        if (filepass == 0)
                                dpsnprintf(filename, sizeof(filename), "effectinfo.txt");
                        else if (filepass == 1)
-                               dpsnprintf(filename, sizeof(filename), "maps/%s_effectinfo.txt", sv.name);
+                               dpsnprintf(filename, sizeof(filename), "%s_effectinfo.txt", sv.worldnamenoextension);
                        else
                                break;
                        filedata = FS_LoadFile(filename, tempmempool, true, &filesize);
@@ -3061,7 +3065,7 @@ void SV_SpawnServer (const char *server)
        int i;
        char *entities;
        dp_model_t *worldmodel;
-       char modelname[sizeof(sv.modelname)];
+       char modelname[sizeof(sv.worldname)];
 
        Con_DPrintf("SpawnServer: %s\n", server);
 
@@ -3164,7 +3168,15 @@ void SV_SpawnServer (const char *server)
 
        sv.active = true;
 
+       // set level base name variables for later use
        strlcpy (sv.name, server, sizeof (sv.name));
+       strlcpy(sv.worldname, modelname, sizeof(sv.worldname));
+       FS_StripExtension(sv.worldname, sv.worldnamenoextension, sizeof(sv.worldnamenoextension));
+       strlcpy(sv.worldbasename, !strncmp(sv.worldnamenoextension, "maps/") ? sv.worldnamenoextension + 4 : sv.worldnamenoextension, sizeof(sv.worldbasename));
+       //Cvar_SetQuick(&sv_worldmessage, sv.worldmessage); // set later after QC is spawned
+       Cvar_SetQuick(&sv_worldname, sv.worldname);
+       Cvar_SetQuick(&sv_worldnamenoextension, sv.worldnamenoextension);
+       Cvar_SetQuick(&sv_worldbasename, sv.worldbasename);
 
        sv.protocol = Protocol_EnumForName(sv_protocolname.string);
        if (sv.protocol == PROTOCOL_UNKNOWN)
@@ -3204,25 +3216,23 @@ void SV_SpawnServer (const char *server)
        Mod_ClearUsed();
        worldmodel->used = true;
 
-       strlcpy (sv.name, server, sizeof (sv.name));
-       strlcpy(sv.modelname, modelname, sizeof(sv.modelname));
        sv.worldmodel = worldmodel;
        sv.models[1] = sv.worldmodel;
 
 //
 // clear world interaction links
 //
-       World_SetSize(&sv.world, sv.worldmodel->name, sv.worldmodel->normalmins, sv.worldmodel->normalmaxs);
+       World_SetSize(&sv.world, sv.worldname, sv.worldmodel->normalmins, sv.worldmodel->normalmaxs);
        World_Start(&sv.world);
 
        strlcpy(sv.sound_precache[0], "", sizeof(sv.sound_precache[0]));
 
        strlcpy(sv.model_precache[0], "", sizeof(sv.model_precache[0]));
-       strlcpy(sv.model_precache[1], sv.modelname, sizeof(sv.model_precache[1]));
+       strlcpy(sv.model_precache[1], sv.worldname, sizeof(sv.model_precache[1]));
        for (i = 1;i < sv.worldmodel->brush.numsubmodels && i+1 < MAX_MODELS;i++)
        {
                dpsnprintf(sv.model_precache[i+1], sizeof(sv.model_precache[i+1]), "*%i", i);
-               sv.models[i+1] = Mod_ForName (sv.model_precache[i+1], false, false, sv.modelname);
+               sv.models[i+1] = Mod_ForName (sv.model_precache[i+1], false, false, sv.worldname);
        }
        if(i < sv.worldmodel->brush.numsubmodels)
                Con_Printf("Too many submodels (MAX_MODELS is %i)\n", MAX_MODELS);
@@ -3234,7 +3244,7 @@ void SV_SpawnServer (const char *server)
        ent = PRVM_EDICT_NUM(0);
        memset (ent->fields.server, 0, prog->progs->entityfields * 4);
        ent->priv.server->free = false;
-       ent->fields.server->model = PRVM_SetEngineString(sv.modelname);
+       ent->fields.server->model = PRVM_SetEngineString(sv.worldname);
        ent->fields.server->modelindex = 1;             // world model
        ent->fields.server->solid = SOLID_BSP;
        ent->fields.server->movetype = MOVETYPE_PUSH;
@@ -3265,9 +3275,9 @@ void SV_SpawnServer (const char *server)
        }
 
        // load replacement entity file if found
-       if (sv_entpatch.integer && (entities = (char *)FS_LoadFile(va("maps/%s.ent", sv.name), tempmempool, true, NULL)))
+       if (sv_entpatch.integer && (entities = (char *)FS_LoadFile(va("%s.ent", sv.worldnamenoextension), tempmempool, true, NULL)))
        {
-               Con_Printf("Loaded maps/%s.ent\n", sv.name);
+               Con_Printf("Loaded %s.ent\n", sv.worldnamenoextension);
                PRVM_ED_LoadFromFile (entities);
                Mem_Free(entities);
        }
@@ -3330,6 +3340,10 @@ void SV_SpawnServer (const char *server)
                }
        }
 
+       // update the map title cvar
+       strlcpy(sv.worldmessage, PRVM_GetString(prog->edicts->fields.server->message), sizeof(sv.worldmessage)); // map title (not related to filename)
+       Cvar_SetQuick(&sv_worldmessage, sv.worldmessage);
+
        Con_DPrint("Server spawned.\n");
        NetConn_Heartbeat (2);