]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Fix display of maps with missing previews, add a new option (enabled by default)...
authorMario <mario.mario@y7mail.com>
Thu, 16 Jul 2020 14:19:36 +0000 (00:19 +1000)
committerMario <mario.mario@y7mail.com>
Thu, 16 Jul 2020 14:19:36 +0000 (00:19 +1000)
qcsrc/common/mapinfo.qc
qcsrc/common/mapinfo.qh
qcsrc/dpdefs/upstream/menudefs.qc
qcsrc/menu/draw.qc
qcsrc/menu/draw.qh
qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc
qcsrc/menu/xonotic/maplist.qc
qcsrc/server/g_world.qc
xonotic-common.cfg

index 29538b621a4f8f586a0066803c36985fd5a5187c..1a03102186c774203956e03f98e13ec1dd2020a9 100644 (file)
@@ -9,6 +9,8 @@
     #include <common/monsters/_mod.qh>
 #endif
 
+bool autocvar_g_mapinfo_arena_compat = true;
+
 #ifdef MENUQC
 #define WARN_COND false
 #else
@@ -299,6 +301,22 @@ float _MapInfo_Generate(string pFilename) // 0: failure, 1: ok ent, 2: ok bsp
        mapMins = '0 0 0';
        mapMaxs = '0 0 0';
 
+       // try for a .arena or .defi file if no .mapinfo exists
+       bool isdefi = false;
+       string arena_fn = _MapInfo_FindArenaFile(pFilename, ".arena");
+       int arena_fh = fopen(arena_fn, FILE_READ);
+       if(arena_fh < 0)
+       {
+               isdefi = true;
+               arena_fn = _MapInfo_FindArenaFile(pFilename, ".defi");
+               arena_fh = fopen(arena_fn, FILE_READ);
+       }
+       if(arena_fh >= 0)
+       {
+               _MapInfo_ParseArena(arena_fn, arena_fh, pFilename, NULL, isdefi, true);
+               fclose(arena_fh);
+       }
+
        for (;;)
        {
                if (!((s = fgets(fh))))
@@ -761,7 +779,7 @@ float MapInfo_isRedundant(string fn, string t)
        return false;
 }
 
-bool _MapInfo_ParseArena(string arena_filename, int fh, string pFilename, Gametype pGametypeToSet, bool isdefi)
+bool _MapInfo_ParseArena(string arena_filename, int fh, string pFilename, Gametype pGametypeToSet, bool isdefi, bool isgenerator)
 {
        // NOTE: .arena files can hold more than 1 map's information!
        // to handle this, we're going to store gathered information in local variables and save it if we encounter the correct map name
@@ -809,10 +827,15 @@ bool _MapInfo_ParseArena(string arena_filename, int fh, string pFilename, Gamety
                                if(stored_Map_title != "")
                                        MapInfo_Map_title = stored_Map_title;
                                MapInfo_Map_author = stored_Map_author;
-                               FOREACH(Gametypes, it.m_flags & stored_supportedGametypes,
+                               if(isgenerator)
+                                       MapInfo_Map_supportedGametypes = stored_supportedGametypes;
+                               else
                                {
-                                       _MapInfo_Map_ApplyGametype ("", pGametypeToSet, it, true);
-                               });
+                                       FOREACH(Gametypes, it.m_flags & stored_supportedGametypes,
+                                       {
+                                               _MapInfo_Map_ApplyGametype ("", pGametypeToSet, it, true);
+                                       });
+                               }
                                return true; // no need to continue through the file, we have our map!
                        }
                        else
@@ -898,20 +921,20 @@ string(string filename) whichpack = #503;
 #endif
 string _MapInfo_FindArenaFile(string pFilename, string extension)
 {
-       string base_pack = whichpack(strcat("maps/", pFilename, ".bsp"));
        string fallback = strcat("scripts/", pFilename, extension);
+       if(!checkextension("DP_QC_FS_SEARCH_PACKFILE"))
+               return fallback;
+       string base_pack = whichpack(strcat("maps/", pFilename, ".bsp"));
        if(base_pack == "") // this map isn't packaged!
                return fallback;
 
-       int glob = search_begin(strcat("scripts/*", extension), true, true);
+       int glob = search_packfile_begin(strcat("scripts/*", extension), true, true, base_pack);
        if(glob < 0)
                return fallback;
        int n = search_getsize(glob);
        for(int j = 0; j < n; ++j)
        {
                string file = search_getfilename(glob, j);
-               if(whichpack(file) != base_pack)
-                       continue; // not in the same pk3!
 
                int fh = fopen(file, FILE_READ);
                if(fh < 0)
@@ -967,21 +990,24 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
        fh = fopen(fn, FILE_READ);
        if(fh < 0)
        {
-               bool isdefi = false;
-               // try for a .arena or .defi file if no .mapinfo exists
-               fn = _MapInfo_FindArenaFile(pFilename, ".arena");
-               fh = fopen(fn, FILE_READ);
-               if(fh < 0)
+               if(autocvar_g_mapinfo_arena_compat)
                {
-                       isdefi = true;
-                       fn = _MapInfo_FindArenaFile(pFilename, ".defi");
+                       // try for .arena or .defi files if no .mapinfo exists
+                       bool isdefi = false;
+                       fn = _MapInfo_FindArenaFile(pFilename, ".arena");
                        fh = fopen(fn, FILE_READ);
-               }
-               if(fh >= 0)
-               {
-                       _MapInfo_Map_Reset();
-                       if(_MapInfo_ParseArena(fn, fh, pFilename, pGametypeToSet, isdefi))
-                               goto mapinfo_handled; // skip generation
+                       if(fh < 0)
+                       {
+                               isdefi = true;
+                               fn = _MapInfo_FindArenaFile(pFilename, ".defi");
+                               fh = fopen(fn, FILE_READ);
+                       }
+                       if(fh >= 0)
+                       {
+                               _MapInfo_Map_Reset();
+                               if(_MapInfo_ParseArena(fn, fh, pFilename, pGametypeToSet, isdefi, false))
+                                       goto mapinfo_handled; // skip generation
+                       }
                }
 
                fn = strcat("maps/autogenerated/", pFilename, ".mapinfo");
index 9b4dfa2575aff6461a2fd56857f27ca6da066a1c..43f5b30cfa993e7df3184a1c37e8204200f536c2 100644 (file)
@@ -673,6 +673,10 @@ void MapInfo_Cache_Destroy(); // disable caching
 void MapInfo_Cache_Create(); // enable caching
 void MapInfo_Cache_Invalidate(); // delete cache if any, but keep enabled
 
+bool _MapInfo_ParseArena(string arena_filename, int fh, string pFilename, Gametype pGametypeToSet, bool isdefi, bool isgenerator);
+
+string _MapInfo_FindArenaFile(string pFilename, string extension);
+
 void _MapInfo_Parse_Settemp(string pFilename, string acl, float type, string s, float recurse);
 
 void MapInfo_ClearTemps(); // call this when done with mapinfo for this frame
index 36cedec4f2fdfd1b96e935f1f5f91b84b230fd53..63d2c6388e8447e90e46445abbe65506e93e074b 100644 (file)
@@ -159,7 +159,7 @@ float OS_MAC                = 2;
 //////////////////////////////////////////////////
 // AK FIXME: Create perhaps a special builtin file for the common cmds
 
-void   checkextension(string ext)      = #1;
+float  checkextension(string ext)      = #1;
 
 // error cmds
 void   error(string err,...)           = #2;
@@ -542,7 +542,7 @@ void coverage() = #642;  // Reports a coverage event. The engine counts for each
 //idea: Mario
 //darkplaces implementation: Mario
 //builtin definitions:
-float(string pattern, float caseinsensitive, float quiet, string packfile) search_packfile_begin = #444;
+float(string pattern, float caseinsensitive, float quiet, string packfile) search_packfile_begin = #74;
 //description:
 //extension to search_begin (DP_QC_FS_SEARCH), performs a filename search with the specified pattern (for example "maps/*.bsp") and stores the results in a search slot (minimum of 128 supported by any engine with this extension), the other functions take this returned search slot number, be sure to search_free when done (they are also freed on progs reload).
 //only searches for files within the specified packfile, which is expected to match the results of whichpack().
index ae6967e367565fc02c38f08f57c77ac0ccca706d..0bd4e29fe02c435de2d0c429bf9d82db0f877ae0 100644 (file)
@@ -83,6 +83,17 @@ vector draw_PictureSize(string pic)
        return drawgetimagesize(pic);
 }
 
+bool draw_PictureExists(string pic)
+{
+       pic = draw_UseSkinFor(pic);
+       if (fexists(strcat(pic, ".tga"))) return true;
+       if (fexists(strcat(pic, ".png"))) return true;
+       if (fexists(strcat(pic, ".jpg"))) return true;
+       if (fexists(strcat(pic, ".pcx"))) return true;
+
+       return false;
+}
+
 void draw_Fill(vector theOrigin, vector theSize, vector theColor, float theAlpha)
 {
        drawfill(boxToGlobal(theOrigin, draw_shift, draw_scale), boxToGlobalSize(theSize, draw_scale), theColor, theAlpha * draw_alpha, 0);
index 69178cb03eedb522c29a0597b22c9f09303133cb..611281913d8d8ed209123a8ae4ec4813f8d5cf81 100644 (file)
@@ -21,6 +21,7 @@ void draw_VertButtonPicture(vector theOrigin, string pic, vector theSize, vector
 void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha, vector theBorderSize);
 void draw_Picture(vector origin, string pic, vector size, vector color, float alpha);
 vector draw_PictureSize(string pic);
+bool draw_PictureExists(string pic);
 void draw_Fill(vector theOrigin, vector theSize, vector theColor, float theAlpha);
 void draw_Text(vector origin, string text, vector size, vector color, float alpha, float allowColorCodes);
 void draw_CenterText(vector origin, string text, vector size, vector color, float alpha, float allowColorCodes);
@@ -40,3 +41,4 @@ vector globalToBoxSize(vector v, vector scale);
 
 float draw_TextWidth_WithColors(string s, vector size);
 float draw_TextWidth_WithoutColors(string s, vector size);
+
index 6e2d28297d61e49d9733586047b7d442f9723ade..57c2c61e6908ed5a8d4175cf23634bc459eee629 100644 (file)
@@ -17,14 +17,14 @@ void XonoticMapInfoDialog_loadMapInfo(entity me, int i, entity mlb)
        strcpy(me.currentMapAuthor, strdecolorize(MapInfo_Map_author));
        strcpy(me.currentMapDescription, MapInfo_Map_description);
        strcpy(me.currentMapPreviewImage, strcat("/maps/", MapInfo_Map_bspname));
-       if(draw_PictureSize(me.currentMapPreviewImage) == '0 0 0') // Quake 3 compatibility
+       if(!draw_PictureExists(me.currentMapPreviewImage)) // Quake 3 compatibility
                strcpy(me.currentMapPreviewImage, strcat("/levelshots/", MapInfo_Map_bspname));
 
        me.frame.setText(me.frame, me.currentMapBSPName);
        me.titleLabel.setText(me.titleLabel, me.currentMapTitle);
        me.authorLabel.setText(me.authorLabel, me.currentMapAuthor);
        me.descriptionLabel.setText(me.descriptionLabel, me.currentMapDescription);
-       if(draw_PictureSize(me.currentMapPreviewImage) == '0 0 0')
+       if(!draw_PictureExists(me.currentMapPreviewImage))
                me.previewImage.src = "nopreview_map";
        else
                me.previewImage.src = me.currentMapPreviewImage;
index 73ce4616be8d3ef5fd64d97e7f816bd8e20ce3fd..924924f01dcc72ccccfda2ca3bf2192f88d05018 100644 (file)
@@ -157,7 +157,7 @@ void XonoticMapList_drawListBoxItem(entity me, int i, vector absSize, bool isSel
 
        if(draw_PictureSize(strcat("/maps/", MapInfo_Map_bspname)) == '0 0 0')
        {
-               if(draw_PictureSize(strcat("/levelshots/", MapInfo_Map_bspname)) == '0 0 0')
+               if(!draw_PictureExists(strcat("/levelshots/", MapInfo_Map_bspname)))
                        draw_Picture(me.columnPreviewOrigin * eX, "nopreview_map", me.columnPreviewSize * eX + eY, '1 1 1', theAlpha);
                else
                        draw_Picture(me.columnPreviewOrigin * eX, strcat("/levelshots/", MapInfo_Map_bspname), me.columnPreviewSize * eX + eY, '1 1 1', theAlpha);
index cc2b5e871fbb62f570f62c37aa47aefffd79f879..92353f6d12e4f845ffe9538efb5114928e50d487 100644 (file)
@@ -882,10 +882,10 @@ spawnfunc(worldspawn)
        MapInfo_Enumerate();
        MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1);
 
-       if(fexists(strcat("scripts/", mapname, ".arena")))
+       if(fexists(_MapInfo_FindArenaFile(mapname, ".arena")))
                cvar_settemp("sv_q3acompat_machineshotgunswap", "1");
 
-       if(fexists(strcat("scripts/", mapname, ".defi")))
+       if(fexists(_MapInfo_FindArenaFile(mapname, ".defi")))
                cvar_settemp("sv_q3defragcompat", "1");
 
        // quake 3 music support
index 88958889af0a9b52f1624b59eb14359db12f69f7..a0c4b679e55aedc283152dc7b07bdf2ecc14efdd 100644 (file)
@@ -150,6 +150,8 @@ set debug_deglobalization_clear 0 "make the new wrappers set globals to NaN afte
 // disabling until it's complete
 set prvm_garbagecollection_enable 0
 
+set g_mapinfo_arena_compat 1 "allow mapinfo data to be pulled directly from .arena and .defi files if they exist, rather than generating .mapinfo files based on their contents"
+
 // load console command aliases and settings
 exec commands.cfg