From: Mario Date: Tue, 14 Jul 2020 18:08:04 +0000 (+1000) Subject: Fix compatibility with .arena and .defi files that contain multiple map listings X-Git-Tag: xonotic-v0.8.6~328^2~31 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=b9c59152504a440b69a20c797337eed22f046917;p=xonotic%2Fxonotic-data.pk3dir.git Fix compatibility with .arena and .defi files that contain multiple map listings --- diff --git a/qcsrc/common/mapinfo.qc b/qcsrc/common/mapinfo.qc index 60f5c40d1..cc9c0f93c 100644 --- a/qcsrc/common/mapinfo.qc +++ b/qcsrc/common/mapinfo.qc @@ -761,8 +761,15 @@ float MapInfo_isRedundant(string fn, string t) return false; } -void _MapInfo_ParseArena(int fh, Gametype pGametypeToSet, bool isdefi) +bool _MapInfo_ParseArena(int fh, string pFilename, Gametype pGametypeToSet, bool isdefi) { + // 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 + bool testing_map = false; // testing a potential mapinfo section (within brackets) + bool dosave = false; // variables will be stored in map info upon reaching finishing bracket + string stored_Map_description = ""; + string stored_Map_title = ""; + int stored_supportedGametypes = 0; string t, s; for (;;) { @@ -778,8 +785,38 @@ void _MapInfo_ParseArena(int fh, Gametype pGametypeToSet, bool isdefi) continue; if(substring(s, 0, 1) == "_") // q3map style continue; - if(s == "{" || s == "}") // opening/closing brackets TODO: make sure we're checking this map's brackets! Q3 can have multiple + if(s == "{") + { + if(testing_map) + return false; // edge case? already in a bracketed section! + testing_map = true; continue; + } + if(s == "}" || s == " }") // check for a space (common practice in kool maps) + { + if(!testing_map) + return false; // no starting bracket! let the mapinfo generation system handle it + testing_map = false; + if(dosave) + { + MapInfo_Map_description = stored_Map_description; + MapInfo_Map_title = stored_Map_title; + FOREACH(Gametypes, it.m_flags & stored_supportedGametypes, + { + _MapInfo_Map_ApplyGametype ("", pGametypeToSet, it, true); + }); + break; // no need to continue through the file, we have our map! + } + else + { + // discard any gathered locals, we're not using the correct map! + stored_Map_description = ""; + stored_Map_title = ""; + stored_supportedGametypes = 0; + continue; + } + } + s = strreplace("\t", " ", s); float p = strstrofs(s, "//", 0); @@ -804,9 +841,9 @@ void _MapInfo_ParseArena(int fh, Gametype pGametypeToSet, bool isdefi) { // in .defi files, this is the description, whereas in .arena files, this is generally the title if(isdefi) - MapInfo_Map_description = s; + stored_Map_description = s; else - MapInfo_Map_title = s; + stored_Map_title = s; } else if(t == "author") MapInfo_Map_author = s; @@ -819,17 +856,28 @@ void _MapInfo_ParseArena(int fh, Gametype pGametypeToSet, bool isdefi) { Gametype f = MapInfo_Type_FromString(it); if(f) - _MapInfo_Map_ApplyGametype ("", pGametypeToSet, f, true); + stored_supportedGametypes |= f.m_flags; }); } else if(t == "style" && isdefi) { // we have a defrag map on our hands, add CTS! // TODO: styles - _MapInfo_Map_ApplyGametype ("", pGametypeToSet, MAPINFO_TYPE_CTS, true); + stored_supportedGametypes |= MAPINFO_TYPE_CTS.m_flags; + } + else if(t == "map") + { + if(strtolower(s) == strtolower(pFilename)) + dosave = true; // yay, found our map! } // TODO: fraglimit } + + // didn't find a closing bracket, uh oh! + // nothing has been saved anyway, let's abort and use generated mapinfo + if(testing_map) + return false; + return true; } #if defined(CSQC) || defined(MENUQC) @@ -919,8 +967,8 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet if(fh >= 0) { _MapInfo_Map_Reset(); - _MapInfo_ParseArena(fh, pGametypeToSet, isdefi); - goto mapinfo_handled; // skip generation + if(_MapInfo_ParseArena(fh, pFilename, pGametypeToSet, isdefi)) + goto mapinfo_handled; // skip generation } fn = strcat("maps/autogenerated/", pFilename, ".mapinfo");