Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
mapinfo.qc File Reference
#include "mapinfo.qh"
#include <common/util.qh>
#include <common/weapons/_all.qh>
Include dependency graph for mapinfo.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define WARN_COND   (!autocvar_g_mapinfo_ignore_warnings && MapInfo_Map_bspname == mi_shortname)

Functions

vector _GametypeFlags_FromGametype (int a)
string _MapInfo_CheckArenaFile (string pFilename, string pMapname)
float _MapInfo_CheckMap (string s, bool gametype_only)
float _MapInfo_FilterGametype (vector pGametype, int pFeatures, int pFlagsRequired, int pFlagsForbidden, bool pAbortOnGenerate)
float _MapInfo_FilterList_cmp (float i, float j, entity pass)
void _MapInfo_FilterList_swap (float i, float j, entity pass)
string _MapInfo_FindArenaFile (string pFilename, string extension)
float _MapInfo_Generate (string pFilename)
string _MapInfo_GetDefault (Gametype t)
string _MapInfo_GetDefaultEx (Gametype t)
float _MapInfo_GetTeamPlayBool (Gametype t)
string _MapInfo_GlobItem (float i)
void _MapInfo_Map_ApplyGametype (string s, Gametype pWantedType, Gametype pThisType, int load_default)
void _MapInfo_Map_ApplyGametypeEx (string s, Gametype pWantedType, Gametype pThisType)
void _MapInfo_Map_Reset ()
void _MapInfo_Parse_Settemp (string pFilename, string acl, float type, string s, float recurse)
bool _MapInfo_ParseArena (string arena_filename, int fh, string pFilename, Gametype pGametypeToSet, bool isdefi, bool isgenerator)
string MapInfo_BSPName_ByID (float i)
void MapInfo_Cache_Create ()
void MapInfo_Cache_Destroy ()
void MapInfo_Cache_Invalidate ()
float MapInfo_Cache_Retrieve (string map)
void MapInfo_Cache_Store ()
float MapInfo_CheckMap (string s)
void MapInfo_ClearTemps ()
int MapInfo_CurrentFeatures ()
Gametype MapInfo_CurrentGametype ()
void MapInfo_Enumerate ()
void MapInfo_Filter_Free ()
float MapInfo_FilterGametype (Gametype pGametype, int pFeatures, int pFlagsRequired, int pFlagsForbidden, bool pAbortOnGenerate)
float MapInfo_FilterList_Lookup (float i)
void MapInfo_FilterString (string sf)
float MapInfo_FindName (string s)
string MapInfo_FixName (string s)
int MapInfo_ForbiddenFlags ()
bool MapInfo_Get_ByID (int i)
int MapInfo_Get_ByName (string pFilename, float pAllowGenerate, Gametype pGametypeToSet)
float MapInfo_Get_ByName_NoFallbacks (string pFilename, int pAllowGenerate, Gametype pGametypeToSet)
bool MapInfo_isRedundant (string fn, string t)
string MapInfo_ListAllAllowedMaps (float pRequiredFlags, float pForbiddenFlags)
string MapInfo_ListAllowedMaps (Gametype type, float pRequiredFlags, float pForbiddenFlags)
void MapInfo_LoadMap (string s, float reinit)
void MapInfo_LoadMapSettings (string s)
void MapInfo_LoadMapSettings_SaveGameType (Gametype t)
int MapInfo_RequiredFlags ()
void MapInfo_Shutdown ()
void MapInfo_SwitchGameType (Gametype t)
string MapInfo_title_sans_author (string title)
 Removes author string from title (if found) and copies it to MapInfo_Map_author if that wasn't set.
string MapInfo_Type_Description (Gametype t)
Gametype MapInfo_Type_FromString (string gtype, bool dowarn, bool is_q3compat)
string MapInfo_Type_ToString (Gametype t)
string MapInfo_Type_ToText (Gametype t)
bool MapReadSizes (string map)
string unquote (string s)

Variables

int _MapInfo_Cache_Active
int _MapInfo_Cache_Buf_IndexToMapData
int _MapInfo_Cache_DB_NameToIndex
float _MapInfo_filtered
float _MapInfo_filtered_allocated
float _MapInfo_globcount
float _MapInfo_globhandle
float _MapInfo_globopen
string _MapInfo_Map_worldspawn_music
bool autocvar_g_mapinfo_ignore_warnings
int autocvar_g_mapinfo_q3compat = 1

Macro Definition Documentation

◆ WARN_COND

Function Documentation

◆ _GametypeFlags_FromGametype()

vector _GametypeFlags_FromGametype ( int a)

Definition at line 20 of file mapinfo.qc.

21{
22 if (REGISTRY_MAX(Gametypes) > 24)
23 if (a >= 24)
24 {
25 a -= 24;
26 if (REGISTRY_MAX(Gametypes) > 48)
27 if (a >= 24)
28 {
29 a -= 24;
30 return '0 0 1' * BIT(a);
31 }
32 return '0 1 0' * BIT(a);
33 }
34 return '1 0 0' * BIT(a);
35}
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition bits.qh:8
#define REGISTRY_MAX(id)
Definition registry.qh:17

References BIT, REGISTRY_MAX, and vector.

Referenced by STATIC_INIT().

◆ _MapInfo_CheckArenaFile()

string _MapInfo_CheckArenaFile ( string pFilename,
string pMapname )

Definition at line 972 of file mapinfo.qc.

973{
974 // returns the file name if valid, otherwise returns ""
975 // a string is returned to optimise the use cases where a filename is also returned
976 int fh = fopen(pFilename, FILE_READ);
977 if(fh < 0)
978 return "";
979 for(string s; (s = fgets(fh)); )
980 {
981 s = strreplace("\t", "", s);
982 while(substring(s, 0, 1) == " ")
983 s = substring(s, 1, -1);
984 if(substring(s, 0, 2) == "//")
985 continue;
986 if(s == "")
987 continue;
988 int offset = strstrofs(s, "map", 0);
989 if(offset >= 0)
990 {
991 if(strstrofs(strtolower(s), strcat("\"", strtolower(pMapname), "\""), offset) >= 0) // quake 3 is case insensitive
992 {
993 fclose(fh);
994 return pFilename; // FOUND IT!
995 }
996 }
997 }
998 fclose(fh);
999 return ""; // file did not contain a "map" field matching our map name
1000}
string strtolower(string s)
const float FILE_READ
#define strstrofs
string fgets(float fhandle)
void fclose(float fhandle)
string substring(string s, float start, float length)
float fopen(string filename, float mode)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))

References fclose(), fgets(), FILE_READ, fopen(), strcat(), strstrofs, strtolower(), and substring().

Referenced by _MapInfo_FindArenaFile().

◆ _MapInfo_CheckMap()

float _MapInfo_CheckMap ( string s,
bool gametype_only )

Definition at line 1489 of file mapinfo.qc.

1490{
1491 if(!MapInfo_Get_ByName(s, 1, NULL))
1492 return 0;
1494 return 0;
1495 if (gametype_only)
1496 return 1;
1498 return 0;
1499 return 1;
1500}
Gametype MapInfo_CurrentGametype()
Definition mapinfo.qc:1482
int MapInfo_Get_ByName(string pFilename, float pAllowGenerate, Gametype pGametypeToSet)
Definition mapinfo.qc:1382
int MapInfo_CurrentFeatures()
Definition mapinfo.qc:1472
vector MapInfo_Map_supportedGametypes
Definition mapinfo.qh:13
int MapInfo_Map_supportedFeatures
Definition mapinfo.qh:14
vector gametype_flags
Definition mapinfo.qh:28
#define NULL
Definition post.qh:14

References gametype_flags, MapInfo_CurrentFeatures(), MapInfo_CurrentGametype(), MapInfo_Get_ByName(), MapInfo_Map_supportedFeatures, MapInfo_Map_supportedGametypes, and NULL.

Referenced by MapInfo_CheckMap(), and MapInfo_LoadMapSettings().

◆ _MapInfo_FilterGametype()

float _MapInfo_FilterGametype ( vector pGametype,
int pFeatures,
int pFlagsRequired,
int pFlagsForbidden,
bool pAbortOnGenerate )

Definition at line 180 of file mapinfo.qc.

181{
182 float i, j;
184 {
187 }
188 MapInfo_count = 0;
189 for(i = 0, j = -1; i < _MapInfo_globcount; ++i)
190 {
191 if(MapInfo_Get_ByName(_MapInfo_GlobItem(i), 1, NULL) == 2) // if we generated one... BAIL OUT and let the caller continue in the next frame.
192 if(pAbortOnGenerate)
193 {
194 LOG_TRACE("Autogenerated a .mapinfo, doing the rest later.");
196 return 0;
197 }
198 if(MapInfo_Map_supportedGametypes & pGametype)
199 if((MapInfo_Map_supportedFeatures & pFeatures) == pFeatures)
200 if((MapInfo_Map_flags & pFlagsForbidden) == 0)
201 if((MapInfo_Map_flags & pFlagsRequired) == pFlagsRequired)
202 bufstr_set(_MapInfo_filtered, ++j, ftos(i));
203 }
204 MapInfo_count = j + 1;
206
207 // sometimes the glob isn't sorted nicely, so fix it here...
209
210 return 1;
211}
#define buf_create
#define LOG_TRACE(...)
Definition log.qh:76
float _MapInfo_globcount
Definition mapinfo.qc:123
void _MapInfo_FilterList_swap(float i, float j, entity pass)
Definition mapinfo.qc:161
string _MapInfo_GlobItem(float i)
Definition mapinfo.qc:125
float _MapInfo_FilterList_cmp(float i, float j, entity pass)
Definition mapinfo.qc:168
void MapInfo_ClearTemps()
Definition mapinfo.qc:1630
float _MapInfo_filtered_allocated
Definition mapinfo.qc:155
float _MapInfo_filtered
Definition mapinfo.qc:154
float MapInfo_count
Definition mapinfo.qh:166
float MapInfo_progress
Definition mapinfo.qh:173
int MapInfo_Map_flags
Definition mapinfo.qh:15
string ftos(float f)
ERASEABLE void heapsort(int n, swapfunc_t swap, comparefunc_t cmp, entity pass)
Definition sort.qh:9

References _MapInfo_filtered, _MapInfo_filtered_allocated, _MapInfo_FilterList_cmp(), _MapInfo_FilterList_swap(), _MapInfo_globcount, _MapInfo_GlobItem(), buf_create, ftos(), heapsort(), LOG_TRACE, MapInfo_ClearTemps(), MapInfo_count, MapInfo_Get_ByName(), MapInfo_Map_flags, MapInfo_Map_supportedFeatures, MapInfo_Map_supportedGametypes, MapInfo_progress, NULL, and vector.

Referenced by GameTypeVote_MapInfo_FixName(), make_mapinfo_Think(), MapInfo_FilterGametype(), MapInfo_ListAllAllowedMaps(), MapList_Add_All(), and preMenuInit().

◆ _MapInfo_FilterList_cmp()

float _MapInfo_FilterList_cmp ( float i,
float j,
entity pass )

Definition at line 168 of file mapinfo.qc.

169{
170 string a, b;
171 a = _MapInfo_GlobItem(stof(bufstr_get(_MapInfo_filtered, i)));
172 b = _MapInfo_GlobItem(stof(bufstr_get(_MapInfo_filtered, j)));
173 return strcasecmp(a, b);
174}
#define strcasecmp
float stof(string val,...)

References _MapInfo_filtered, _MapInfo_GlobItem(), entity(), pass, stof(), and strcasecmp.

Referenced by _MapInfo_FilterGametype(), and MapInfo_FilterString().

◆ _MapInfo_FilterList_swap()

void _MapInfo_FilterList_swap ( float i,
float j,
entity pass )

Definition at line 161 of file mapinfo.qc.

162{
163 string h = bufstr_get(_MapInfo_filtered, i);
164 bufstr_set(_MapInfo_filtered, i, bufstr_get(_MapInfo_filtered, j));
165 bufstr_set(_MapInfo_filtered, j, h);
166}

References _MapInfo_filtered, entity(), and pass.

Referenced by _MapInfo_FilterGametype(), and MapInfo_FilterString().

◆ _MapInfo_FindArenaFile()

string _MapInfo_FindArenaFile ( string pFilename,
string extension )

Definition at line 1002 of file mapinfo.qc.

1003{
1004 // A valid arena file with the "default" name may have been created as a map-specific
1005 // override of an arena file with a different name (possibly multi-map) in the pk3
1006 // (occasionally in the wild such file exists in the pk3 but isn't valid for a map in the pk3).
1007 // Therefore we try the "default" name first.
1008 string afile = _MapInfo_CheckArenaFile(strcat("scripts/", pFilename, extension), pFilename);
1009 if (afile != ""
1010 || !checkextension("DP_QC_FS_SEARCH_PACKFILE"))
1011 return afile;
1012
1013 string base_pack = whichpack(strcat("maps/", pFilename, ".bsp"));
1014 if(base_pack == "") // this map isn't packaged!
1015 return "";
1016 int glob = search_packfile_begin(strcat("scripts/*", extension), true, true, base_pack);
1017 if(glob < 0) // there's no matching file in the pack
1018 return "";
1019 int n = search_getsize(glob);
1020 for(int j = 0; j < n; ++j)
1021 {
1022 afile = search_getfilename(glob, j);
1023 if(_MapInfo_CheckArenaFile(afile, pFilename) != "")
1024 {
1025 search_end(glob);
1026 return afile;
1027 }
1028 }
1029 search_end(glob);
1030
1031 return ""; // if we get here, a valid .arena file could not be found
1032}
string _MapInfo_CheckArenaFile(string pFilename, string pMapname)
Definition mapinfo.qc:972
string search_getfilename(float handle, float num)
float search_getsize(float handle)
float checkextension(string ext)
void search_end(float handle)

References _MapInfo_CheckArenaFile(), checkextension(), search_end(), search_getfilename(), search_getsize(), and strcat().

Referenced by _MapInfo_Generate(), MapInfo_Get_ByName_NoFallbacks(), and spawnfunc().

◆ _MapInfo_Generate()

float _MapInfo_Generate ( string pFilename)

Definition at line 281 of file mapinfo.qc.

282{
283 string fn;
284 float fh;
285 string s, k, v;
286 vector o;
287 float i;
288 float inWorldspawn;
289 float r;
290 float diameter, spawnpoints;
291 float spawnplaces;
292 bool is_q3df_map = false;
293 vector mapMins, mapMaxs;
294
295 if(autocvar_g_mapinfo_q3compat >= 2) // generate mapinfo using arena data
296 {
297 // try for .arena or .defi files, as they may have more accurate information
298 // supporting .arena AND .defi for the same map
299 bool success = false;
300 fh = -1;
301 fn = _MapInfo_FindArenaFile(pFilename, ".arena");
302 if(fn != "" && (fh = fopen(fn, FILE_READ)) >= 0)
303 {
304 success = _MapInfo_ParseArena(fn, fh, pFilename, NULL, false, true);
305 fclose(fh);
306 }
307 fn = _MapInfo_FindArenaFile(pFilename, ".defi");
308 if(fn != "" && (fh = fopen(fn, FILE_READ)) >= 0)
309 {
310 success |= _MapInfo_ParseArena(fn, fh, pFilename, NULL, true, true);
311 fclose(fh);
312 }
313 if (success && autocvar_g_mapinfo_q3compat == 3)
314 return 3; // skip entity analysis
315 }
316
317 r = 1;
318 fn = strcat("maps/", pFilename, ".ent");
319 fh = fopen(fn, FILE_READ);
320 if(fh < 0)
321 {
322 r = 2;
323 fn = strcat("maps/", pFilename, ".bsp");
324 fh = fopen(fn, FILE_READ);
325 }
326 if(fh < 0)
327 return 0;
328 LOG_INFO("Generating ", pFilename, ".mapinfo: analyzing ", fn);
329
330 inWorldspawn = 2;
331 spawnpoints = 0;
332 spawnplaces = 0;
334 mapMins = '0 0 0';
335 mapMaxs = '0 0 0';
336
337 for (;;)
338 {
339 if (!((s = fgets(fh))))
340 break;
341 if(inWorldspawn == 1)
342 if(startsWith(s, "}"))
343 inWorldspawn = 0;
344 k = unquote(car(s));
345 v = unquote(cdr(s));
346 if(inWorldspawn)
347 {
348 if(k == "classname" && v == "worldspawn")
349 inWorldspawn = 1;
350 else if(k == "author")
352 else if(k == "_description")
354 else if(k == "music")
356 else if(k == "noise")
358 else if(k == "message" && (!MapInfo_Map_title || MapInfo_Map_title == "<TITLE>") && v != "")
360 }
361 else
362 {
363 if(k == "origin")
364 {
365 o = stov(strcat("'", v, "'"));
366 mapMins.x = min(mapMins.x, o.x);
367 mapMins.y = min(mapMins.y, o.y);
368 mapMins.z = min(mapMins.z, o.z);
369 mapMaxs.x = max(mapMaxs.x, o.x);
370 mapMaxs.y = max(mapMaxs.y, o.y);
371 mapMaxs.z = max(mapMaxs.z, o.z);
372 }
373 else if(k == "race_place")
374 {
375 if(stof(v) > 0)
376 spawnplaces = 1;
377 }
378 else if(k == "classname")
379 {
380 if(v == "info_player_team1")
381 ++spawnpoints;
382 else if(v == "info_player_team2")
383 ++spawnpoints;
384 else if(v == "info_player_start")
385 ++spawnpoints;
386 else if(v == "info_player_deathmatch")
387 ++spawnpoints;
388 else if(v == "weapon_nex")
389 { }
390 else if(v == "weapon_railgun")
391 { }
392 else if(startsWith(v, "weapon_"))
394 else if(startsWith(v, "turret_"))
396 else if(startsWith(v, "vehicle_"))
398 else if(startsWith(v, "monster_"))
400 else if(v == "target_music" || v == "trigger_music")
401 _MapInfo_Map_worldspawn_music = string_null; // don't use regular BGM
402 else if(v == "target_stopTimer")
403 is_q3df_map = true; // don't support standard gametypes UNLESS we found them in .arena
404 else
405 FOREACH(Gametypes, true, it.m_generate_mapinfo(it, v));
406 }
407 }
408 }
409 if(inWorldspawn)
410 {
411 LOG_WARN(fn, " ended still in worldspawn, BUG");
412 return 0;
413 }
414 diameter = vlen(mapMaxs - mapMins);
415
416 vector twoBaseModes = '0 0 0';
417 FOREACH(Gametypes, it.m_isTwoBaseMode(), twoBaseModes |= it.gametype_flags);
418 if(twoBaseModes && (twoBaseModes &= MapInfo_Map_supportedGametypes))
419 {
420 // we have a symmetrical map, don't add the modes without bases
421 }
422 else if(!is_q3df_map)
423 {
424 FOREACH(Gametypes, it.m_isAlwaysSupported(it, spawnpoints, diameter), MapInfo_Map_supportedGametypes |= it.gametype_flags);
425 }
426
427 if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_RACE.gametype_flags)
428 if(!spawnplaces)
429 {
430 MapInfo_Map_supportedGametypes &= ~MAPINFO_TYPE_RACE.gametype_flags;
431 MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_CTS.gametype_flags;
432 }
433
434 LOG_TRACE("-> diameter ", ftos(diameter));
435 LOG_TRACE("; spawnpoints ", ftos(spawnpoints));
437
438 fclose(fh);
439
440 return r;
441}
#define FOREACH(list, cond, body)
Definition iter.qh:19
#define LOG_INFO(...)
Definition log.qh:65
#define LOG_WARN(...)
Definition log.qh:61
int autocvar_g_mapinfo_q3compat
Definition mapinfo.qc:11
string unquote(string s)
Definition mapinfo.qc:254
string _MapInfo_FindArenaFile(string pFilename, string extension)
Definition mapinfo.qc:1002
string _MapInfo_Map_worldspawn_music
Definition mapinfo.qc:279
bool _MapInfo_ParseArena(string arena_filename, int fh, string pFilename, Gametype pGametypeToSet, bool isdefi, bool isgenerator)
Definition mapinfo.qc:820
const int MAPINFO_FEATURE_MONSTERS
Definition mapinfo.qh:159
string MapInfo_Map_title
Definition mapinfo.qh:7
string MapInfo_Map_author
Definition mapinfo.qh:10
const int MAPINFO_FEATURE_WEAPONS
Definition mapinfo.qh:156
const int MAPINFO_FEATURE_VEHICLES
Definition mapinfo.qh:157
const int MAPINFO_FEATURE_TURRETS
Definition mapinfo.qh:158
string MapInfo_Map_description
Definition mapinfo.qh:9
vector stov(string s)
float vlen(vector v)
string vtos(vector v)
float min(float f,...)
float max(float f,...)
string string_null
Definition nil.qh:9
vector
Definition self.qh:92
ERASEABLE string car(string s)
returns first word
Definition string.qh:259
ERASEABLE string cdr(string s)
returns all but first word
Definition string.qh:268
#define startsWith(haystack, needle)
Definition string.qh:236

References _MapInfo_FindArenaFile(), _MapInfo_Map_worldspawn_music, _MapInfo_ParseArena(), autocvar_g_mapinfo_q3compat, car(), cdr(), fclose(), fgets(), FILE_READ, fopen(), FOREACH, ftos(), LOG_INFO, LOG_TRACE, LOG_WARN, MAPINFO_FEATURE_MONSTERS, MAPINFO_FEATURE_TURRETS, MAPINFO_FEATURE_VEHICLES, MAPINFO_FEATURE_WEAPONS, MapInfo_Map_author, MapInfo_Map_description, MapInfo_Map_supportedFeatures, MapInfo_Map_supportedGametypes, MapInfo_Map_title, max(), min(), NULL, startsWith, stof(), stov(), strcat(), string_null, unquote(), vector, vlen(), and vtos().

Referenced by MapInfo_Get_ByName_NoFallbacks().

◆ _MapInfo_GetDefault()

string _MapInfo_GetDefault ( Gametype t)

Definition at line 458 of file mapinfo.qc.

459{
460 return t.m_legacydefaults;
461}
string m_legacydefaults
DO NOT USE, this is compatibility for legacy maps!
Definition mapinfo.qh:68

References Gametype::m_legacydefaults.

Referenced by _MapInfo_Map_ApplyGametype().

◆ _MapInfo_GetDefaultEx()

string _MapInfo_GetDefaultEx ( Gametype t)

Definition at line 533 of file mapinfo.qc.

534{
535 return t ? t.model2 : "";
536}

Referenced by _MapInfo_Map_ApplyGametypeEx().

◆ _MapInfo_GetTeamPlayBool()

float _MapInfo_GetTeamPlayBool ( Gametype t)

Definition at line 538 of file mapinfo.qc.

539{
540 return t ? t.team : false;
541}
bool team
does this gametype support teamplay?
Definition mapinfo.qh:46

References Gametype::team.

Referenced by MapHasRightSize(), NET_HANDLE(), and XonoticGametypeList_drawListBoxItem().

◆ _MapInfo_GlobItem()

string _MapInfo_GlobItem ( float i)

Definition at line 125 of file mapinfo.qc.

126{
127 string s;
129 return string_null;
131 return substring(s, 5, strlen(s) - 9); // without maps/ and .bsp
132}
#define strlen
float _MapInfo_globopen
Definition mapinfo.qc:122
float _MapInfo_globhandle
Definition mapinfo.qc:124

References _MapInfo_globhandle, _MapInfo_globopen, search_getfilename(), string_null, strlen, and substring().

Referenced by _MapInfo_FilterGametype(), _MapInfo_FilterList_cmp(), MapInfo_BSPName_ByID(), MapInfo_FindName(), MapInfo_ListAllAllowedMaps(), and MapInfo_ListAllowedMaps().

◆ _MapInfo_Map_ApplyGametype()

void _MapInfo_Map_ApplyGametype ( string s,
Gametype pWantedType,
Gametype pThisType,
int load_default )

Definition at line 463 of file mapinfo.qc.

464{
465 string sa;
466 MapInfo_Map_supportedGametypes |= pThisType.gametype_flags;
467 if(!(pThisType.gametype_flags & pWantedType.gametype_flags))
468 return;
469
470 if(load_default)
471 _MapInfo_Map_ApplyGametype(_MapInfo_GetDefault(pThisType), pWantedType, pThisType, false);
472
473 if(!pWantedType.frags) // these modes don't use fraglimit
474 {
475 cvar_set("fraglimit", "0");
476 }
477 else
478 {
479 sa = car(s);
480 if(sa != "")
481 cvar_set("fraglimit", sa);
482 s = cdr(s);
483 }
484
485 sa = car(s);
486 if(sa != "")
487 cvar_set("timelimit", sa);
488 s = cdr(s);
489
490 if(pWantedType.m_setTeams)
491 {
492 sa = car(s);
493 if(sa != "")
494 pWantedType.m_setTeams(sa);
495 s = cdr(s);
496 }
497
498 // rc = timelimit timelimit_qualification laps laps_teamplay
499 if(pWantedType == MAPINFO_TYPE_RACE)
500 {
501 cvar_set("fraglimit", "0"); // special case!
502
503 sa = car(s); if(sa == "") sa = cvar_string("timelimit");
504 cvar_set("g_race_qualifying_timelimit", sa);
505 s = cdr(s);
506
507 sa = car(s);
508 if(sa != "")
509 if(cvar("g_race_teams") < 2)
510 cvar_set("fraglimit", sa);
511 s = cdr(s);
512
513 sa = car(s);
514 if(sa != "")
515 if(cvar("g_race_teams") >= 2)
516 cvar_set("fraglimit", sa);
517 s = cdr(s);
518 }
519
520 if(!pWantedType.frags) // these modes don't use fraglimit
521 {
522 cvar_set("leadlimit", "0");
523 }
524 else
525 {
526 sa = car(s);
527 if(sa != "")
528 cvar_set("leadlimit", sa);
529 s = cdr(s);
530 }
531}
bool frags
does this gametype use a point limit?
Definition mapinfo.qh:48
string _MapInfo_GetDefault(Gametype t)
Definition mapinfo.qc:458
void _MapInfo_Map_ApplyGametype(string s, Gametype pWantedType, Gametype pThisType, int load_default)
Definition mapinfo.qc:463
void cvar_set(string name, string value)
float cvar(string name)
const string cvar_string(string name)

References _MapInfo_GetDefault(), _MapInfo_Map_ApplyGametype(), car(), cdr(), cvar(), cvar_set(), cvar_string(), Gametype::frags, and MapInfo_Map_supportedGametypes.

Referenced by _MapInfo_Map_ApplyGametype(), and MapInfo_Get_ByName_NoFallbacks().

◆ _MapInfo_Map_ApplyGametypeEx()

void _MapInfo_Map_ApplyGametypeEx ( string s,
Gametype pWantedType,
Gametype pThisType )

Definition at line 543 of file mapinfo.qc.

544{
545 MapInfo_Map_supportedGametypes |= pThisType.gametype_flags;
546 if (!(pThisType.gametype_flags & pWantedType.gametype_flags))
547 return;
548
549 // reset all the cvars to their defaults
550
551 cvar_set("timelimit", cvar_defstring("timelimit"));
552 cvar_set("leadlimit", cvar_defstring("leadlimit"));
553 cvar_set("fraglimit", cvar_defstring("fraglimit"));
554 FOREACH(Gametypes, true, it.m_parse_mapinfo(string_null, string_null));
555
556 string fraglimit_normal = string_null;
557 string fraglimit_teams = string_null;
558
559 for (s = strcat(_MapInfo_GetDefaultEx(pWantedType), " ", s); s != ""; s = cdr(s)) {
560 string sa = car(s);
561 if (sa == "") continue;
562 int p = strstrofs(sa, "=", 0);
563 if (p < 0) {
564 if(WARN_COND)
565 LOG_WARNF("Invalid gametype setting in mapinfo for gametype %s: %s", MapInfo_Type_ToString(pWantedType), sa);
566 continue;
567 }
568 string k = substring(sa, 0, p);
569 string v = substring(sa, p + 1, -1);
570 bool handled = true;
571 switch (k) {
572 case "timelimit":
573 {
574 cvar_set("timelimit", v);
575 break;
576 }
577 case "leadlimit":
578 {
579 cvar_set("leadlimit", v);
580 break;
581 }
582 case "pointlimit":
583 case "fraglimit":
584 case "lives":
585 case "laplimit":
586 case "caplimit":
587 {
588 fraglimit_normal = v;
589 break;
590 }
591 case "teampointlimit":
592 case "teamlaplimit":
593 {
594 fraglimit_teams = v;
595 break;
596 }
597 default:
598 {
599 handled = false;
600 break;
601 }
602 }
603 FOREACH(Gametypes, true, handled |= it.m_parse_mapinfo(k, v));
604 if (!handled && WARN_COND)
605 LOG_WARNF("Invalid gametype setting in mapinfo for gametype %s: %s", MapInfo_Type_ToString(pWantedType), sa);
606 }
607
608 if (pWantedType == MAPINFO_TYPE_RACE && cvar("g_race_teams") >= 2)
609 {
610 if(fraglimit_teams)
611 cvar_set("fraglimit", fraglimit_teams);
612 }
613 else
614 {
615 if(fraglimit_normal)
616 cvar_set("fraglimit", fraglimit_normal);
617 }
618}
#define LOG_WARNF(...)
Definition log.qh:62
string MapInfo_Type_ToString(Gametype t)
Definition mapinfo.qc:655
string _MapInfo_GetDefaultEx(Gametype t)
Definition mapinfo.qc:533
#define WARN_COND
Definition mapinfo.qc:15
const string cvar_defstring(string name)

References _MapInfo_GetDefaultEx(), car(), cdr(), cvar(), cvar_defstring(), cvar_set(), FOREACH, LOG_WARNF, MapInfo_Map_supportedGametypes, MapInfo_Type_ToString(), strcat(), string_null, strstrofs, substring(), and WARN_COND.

Referenced by MapInfo_Get_ByName(), MapInfo_Get_ByName_NoFallbacks(), and MapInfo_LoadMapSettings().

◆ _MapInfo_Map_Reset()

void _MapInfo_Map_Reset ( )

Definition at line 443 of file mapinfo.qc.

444{
445 MapInfo_Map_title = "<TITLE>";
446 MapInfo_Map_titlestring = "<TITLE>";
447 MapInfo_Map_description = "<DESCRIPTION>";
448 MapInfo_Map_author = "<AUTHOR>";
453 MapInfo_Map_fog = "";
454 MapInfo_Map_mins = '0 0 0';
455 MapInfo_Map_maxs = '0 0 0';
456}
vector MapInfo_Map_maxs
Definition mapinfo.qh:17
vector MapInfo_Map_mins
Definition mapinfo.qh:16
string MapInfo_Map_fog
Definition mapinfo.qh:12
string MapInfo_Map_titlestring
Definition mapinfo.qh:8
string MapInfo_Map_clientstuff
Definition mapinfo.qh:11

References MapInfo_Map_author, MapInfo_Map_clientstuff, MapInfo_Map_description, MapInfo_Map_flags, MapInfo_Map_fog, MapInfo_Map_maxs, MapInfo_Map_mins, MapInfo_Map_supportedFeatures, MapInfo_Map_supportedGametypes, MapInfo_Map_title, and MapInfo_Map_titlestring.

Referenced by MapInfo_Get_ByName_NoFallbacks().

◆ _MapInfo_Parse_Settemp()

void _MapInfo_Parse_Settemp ( string pFilename,
string acl,
float type,
string s,
float recurse )

Definition at line 666 of file mapinfo.qc.

667{
668 string t;
669 float o;
670 // tabs are invalid, treat them as "empty"
671 s = strreplace("\t", "", s);
672
673 t = car(s); s = cdr(s);
674
675 // limited support of "" and comments
676 // remove trailing and leading " of t
677 if(substring(t, 0, 1) == "\"")
678 {
679 if(substring(t, -1, 1) == "\"")
680 t = substring(t, 1, -2);
681 }
682
683 // remove leading " of s
684 if(substring(s, 0, 1) == "\"")
685 {
686 s = substring(s, 1, -1);
687 }
688 // remove trailing " of s, and all that follows (cvar description)
689 o = strstrofs(s, "\"", 0);
690 if(o >= 0)
691 s = substring(s, 0, o);
692
693 // remove // comments
694 o = strstrofs(s, "//", 0);
695 if(o >= 0)
696 s = substring(s, 0, o);
697
698 // remove trailing spaces
699 while(substring(s, -1, 1) == " ")
700 s = substring(s, 0, -2);
701
702 if(t == "#include")
703 {
704 if(recurse > 0)
705 {
706 float fh = fopen(s, FILE_READ);
707 if(fh < 0)
708 {
709 if(WARN_COND)
710 LOG_WARN("Map ", pFilename, " references not existing config file ", s);
711 }
712 else
713 {
714 while((s = fgets(fh)))
715 {
716 s = strreplace("\t", "", s); // treat tabs as "empty", perform here first to ensure coments are detected
717 // catch different sorts of comments
718 if(s == "") // empty lines
719 continue;
720 if(substring(s, 0, 1) == "#") // UNIX style
721 continue;
722 if(substring(s, 0, 2) == "//") // C++ style
723 continue;
724 if(substring(s, 0, 1) == "_") // q3map style
725 continue;
726
727 if(substring(s, 0, 4) == "set ")
728 s = substring(s, 4, -1);
729 if(substring(s, 0, 5) == "seta ")
730 s = substring(s, 5, -1);
731
732 _MapInfo_Parse_Settemp(pFilename, acl, type, s, recurse - 1);
733 }
734 fclose(fh);
735 }
736 }
737 else if(WARN_COND)
738 LOG_WARN("Map ", pFilename, " uses too many levels of inclusion");
739 }
740 else if(t == ""
741 || !cvar_value_issafe(t)
742 || !cvar_value_issafe(s)
744 {
745 if (WARN_COND)
746 LOG_WARN("Map ", pFilename, " contains a potentially harmful setting, ignored");
747 }
748 else if(matchacl(acl, t) <= 0)
749 {
750 if (WARN_COND)
751 LOG_WARN("Map ", pFilename, " contains a denied setting, ignored");
752 }
753 else
754 {
755 if(type == 0) // server set
756 {
757 LOG_TRACE("Applying temporary setting ", t, " := ", s);
758 cvar_settemp(t, s);
759 }
760 else
761 {
762 LOG_TRACE("Applying temporary client setting ", t, " := ", s);
764 MapInfo_Map_clientstuff, "cl_cmd settemp \"", t, "\" \"", s, "\"\n"
765 );
766 }
767 }
768}
float matchacl(string acl, string str)
Definition util.qc:1437
float cvar_settemp(string tmp_cvar, string tmp_value)
Definition util.qc:807
ERASEABLE bool cvar_value_issafe(string s)
Definition cvar.qh:11
void _MapInfo_Parse_Settemp(string pFilename, string acl, float type, string s, float recurse)
Definition mapinfo.qc:666
#define MAPINFO_SETTEMP_ACL_SYSTEM
Definition mapinfo.qh:237

References _MapInfo_Parse_Settemp(), car(), cdr(), cvar_settemp(), cvar_value_issafe(), fclose(), fgets(), FILE_READ, fopen(), LOG_TRACE, LOG_WARN, MapInfo_Map_clientstuff, MAPINFO_SETTEMP_ACL_SYSTEM, matchacl(), strcat(), strstrofs, substring(), and WARN_COND.

Referenced by _MapInfo_Parse_Settemp(), CampaignPreInit(), and MapInfo_Get_ByName_NoFallbacks().

◆ _MapInfo_ParseArena()

bool _MapInfo_ParseArena ( string arena_filename,
int fh,
string pFilename,
Gametype pGametypeToSet,
bool isdefi,
bool isgenerator )

Definition at line 820 of file mapinfo.qc.

821{
822 // NOTE: .arena files can hold more than 1 map's information!
823 // to handle this, we're going to store gathered information in local variables and save it if we encounter the correct map name
824 bool in_brackets = false; // testing a potential mapinfo section (within brackets)
825 bool dosave = false;
826 string stored_Map_description = "";
827 string stored_Map_title = "";
828 string stored_Map_author = "";
829 vector stored_supportedGametypes = '0 0 0';
830 int stored_supportedFeatures = 0;
831 int stored_flags = 0;
832 string t, s;
833
834 if (isgenerator)
835 LOG_INFO("Generating ", pFilename, ".mapinfo: analyzing ", arena_filename);
836
837 for (;;)
838 {
839 if (!((s = fgets(fh))))
840 break;
841
842 // catch different sorts of comments
843 if(s == "") // empty lines
844 continue;
845 if(substring(s, 0, 2) == "//") // C++ style
846 continue;
847 if(strstrofs(s, "{", 0) >= 0)
848 {
849 if(in_brackets)
850 return false; // edge case? already in a bracketed section!
851 in_brackets = true;
852 continue;
853 }
854 else if(!in_brackets)
855 {
856 // if we're not inside a bracket, don't process map info
857 continue;
858 }
859 if(strstrofs(s, "}", 0) >= 0)
860 {
861 if(!in_brackets)
862 return false; // no starting bracket! let the mapinfo generation system handle it
863 in_brackets = false;
864 if(dosave)
865 {
866 MapInfo_Map_description = stored_Map_description;
867 if(stored_Map_title != "")
868 MapInfo_Map_title = stored_Map_title;
869 if(stored_Map_author != "") // write the usual "<AUTHOR>" if we have nothing better
870 MapInfo_Map_author = stored_Map_author;
871 // might have .arena AND .defi for the same map so these bitfields are OR'd
872 if(isgenerator)
873 MapInfo_Map_supportedGametypes |= stored_supportedGametypes;
874 else
875 {
876 FOREACH(Gametypes, it.gametype_flags & stored_supportedGametypes,
877 {
878 _MapInfo_Map_ApplyGametype ("", pGametypeToSet, it, true);
879 });
880 }
881 MapInfo_Map_supportedFeatures |= stored_supportedFeatures;
882 MapInfo_Map_flags |= stored_flags;
883 return true; // no need to continue through the file, we have our map!
884 }
885 else
886 {
887 // discard any gathered locals, we're not using the correct map!
888 stored_Map_description = "";
889 stored_Map_title = "";
890 stored_Map_author = "";
891 stored_supportedGametypes = '0 0 0';
892 stored_supportedFeatures = 0;
893 stored_flags = 0;
894 continue;
895 }
896 }
897
898 s = strreplace("\t", " ", s);
899
900 float p = strstrofs(s, "//", 0);
901 if(p >= 0)
902 s = substring(s, 0, p);
903
904 // perform an initial trim to ensure the first argument is properly obtained
905 // remove leading spaces
906 while(substring(s, 0, 1) == " ")
907 s = substring(s, 1, -1);
908
909 t = car(s); s = cdr(s);
910 t = strtolower(t); // apparently some q3 maps use capitalized parameters
911
912 // remove trailing spaces
913 while(substring(t, -1, 1) == " ")
914 t = substring(t, 0, -2);
915
916 // remove trailing spaces
917 while(substring(s, -1, 1) == " ")
918 s = substring(s, 0, -2);
919 // remove leading spaces
920 while(substring(s, 0, 1) == " ")
921 s = substring(s, 1, -1);
922 // limited support of ""
923 // remove trailing and leading " of s
924 if(substring(s, 0, 1) == "\"")
925 {
926 if(substring(s, -1, 1) == "\"")
927 s = substring(s, 1, -2);
928 }
929 if(t == "longname")
930 stored_Map_title = s;
931 else if(t == "author")
932 stored_Map_author = s;
933 else if(t == "type")
934 {
935 // if there is a valid gametype in this .arena file, include it in the menu
936 stored_supportedFeatures |= MAPINFO_FEATURE_WEAPONS;
937 // type in quake 3 holds all the supported gametypes, so we must loop through all of them
938 // TODO: handle support here better to include more Xonotic teamplay modes
939 string types = s;
940 types = strreplace("team", "tdm ft", types);
941 types = strreplace("ffa", "dm lms ka", types);
942 types = strreplace("tourney", "duel", types); // QL used duel so the following check must support it
943 if(strstrofs(types, "duel", 0) < 0 && strstrofs(types, "tdm", 0) >= 0) // larger team map, support additional gametypes!
944 types = cons(types, "ca kh");
945 FOREACH_WORD(types, true,
946 {
947 Gametype f = MapInfo_Type_FromString(it, false, true);
948 if(f)
949 stored_supportedGametypes |= f.gametype_flags;
950 });
951 }
952 else if(t == "style" && isdefi)
953 {
954 // we have a defrag map on our hands, add CTS!
955 // TODO: styles
956 stored_supportedGametypes |= MAPINFO_TYPE_CTS.gametype_flags;
957 }
958 else if(t == "map")
959 {
960 if(strtolower(s) == strtolower(pFilename))
961 dosave = true; // yay, found our map!
962 }
963 else if(t == "quote")
964 stored_Map_description = s;
965 // TODO: fraglimit
966 }
967
968 // if the map wasn't found in the .arena, fall back to generated .mapinfo
969 return false;
970}
#define FOREACH_WORD(words, cond, body)
Definition iter.qh:33
Gametype MapInfo_Type_FromString(string gtype, bool dowarn, bool is_q3compat)
Definition mapinfo.qc:620
ERASEABLE string cons(string a, string b)
Definition string.qh:276

References car(), cdr(), cons(), fgets(), FOREACH, FOREACH_WORD, LOG_INFO, MAPINFO_FEATURE_WEAPONS, MapInfo_Map_author, MapInfo_Map_description, MapInfo_Map_flags, MapInfo_Map_supportedFeatures, MapInfo_Map_supportedGametypes, MapInfo_Map_title, MapInfo_Type_FromString(), strstrofs, strtolower(), substring(), and vector.

Referenced by _MapInfo_Generate(), and MapInfo_Get_ByName_NoFallbacks().

◆ MapInfo_BSPName_ByID()

◆ MapInfo_Cache_Create()

void MapInfo_Cache_Create ( )

Definition at line 53 of file mapinfo.qc.

54{
59}
ERASEABLE int db_create()
Definition map.qh:25
int _MapInfo_Cache_DB_NameToIndex
Definition mapinfo.qc:40
void MapInfo_Cache_Destroy()
Definition mapinfo.qc:43
int _MapInfo_Cache_Buf_IndexToMapData
Definition mapinfo.qc:41
int _MapInfo_Cache_Active
Definition mapinfo.qc:39

References _MapInfo_Cache_Active, _MapInfo_Cache_Buf_IndexToMapData, _MapInfo_Cache_DB_NameToIndex, buf_create, db_create(), and MapInfo_Cache_Destroy().

Referenced by MapInfo_Cache_Invalidate(), and preMenuInit().

◆ MapInfo_Cache_Destroy()

void MapInfo_Cache_Destroy ( )

◆ MapInfo_Cache_Invalidate()

void MapInfo_Cache_Invalidate ( )

Definition at line 61 of file mapinfo.qc.

62{
64 return;
65
67}
void MapInfo_Cache_Create()
Definition mapinfo.qc:53

References _MapInfo_Cache_Active, and MapInfo_Cache_Create().

Referenced by MapInfo_Enumerate().

◆ MapInfo_Cache_Retrieve()

float MapInfo_Cache_Retrieve ( string map)

◆ MapInfo_Cache_Store()

void MapInfo_Cache_Store ( )

Definition at line 69 of file mapinfo.qc.

70{
71 float i;
72 string s;
74 return;
75
77 if(s == "")
78 {
79 i = buf_getsize(_MapInfo_Cache_Buf_IndexToMapData);
81 }
82 else
83 i = stof(s);
84
85 // now store all the stuff
94}
ERASEABLE void db_put(int db, string key, string value)
Definition map.qh:101

References _MapInfo_Cache_Active, _MapInfo_Cache_Buf_IndexToMapData, _MapInfo_Cache_DB_NameToIndex, db_get(), db_put(), ftos(), MapInfo_Map_author, MapInfo_Map_bspname, MapInfo_Map_description, MapInfo_Map_flags, MapInfo_Map_supportedFeatures, MapInfo_Map_supportedGametypes, MapInfo_Map_title, MapInfo_Map_titlestring, stof(), and vtos().

Referenced by MapInfo_Get_ByName_NoFallbacks().

◆ MapInfo_CheckMap()

float MapInfo_CheckMap ( string s)

Definition at line 1502 of file mapinfo.qc.

1503{
1504 float r = _MapInfo_CheckMap(s, false);
1506 return r;
1507}
float _MapInfo_CheckMap(string s, bool gametype_only)
Definition mapinfo.qc:1489

References _MapInfo_CheckMap(), and MapInfo_ClearTemps().

Referenced by DoNextMapOverride(), GenericCommand_maplist(), getmaplist(), GotoMap(), Map_Check(), MapList_LoadMap(), MapVote_AddVotable(), MapVote_Suggest(), and ValidateMap().

◆ MapInfo_ClearTemps()

◆ MapInfo_CurrentFeatures()

int MapInfo_CurrentFeatures ( )

Definition at line 1472 of file mapinfo.qc.

1473{
1474 int req = 0;
1475 // TODO: find a better way to check if weapons are required on the map
1476 if(!(cvar("g_instagib") || cvar("g_overkill") || cvar("g_nix") || cvar("g_weaponarena") || !cvar("g_pickup_items") || !cvar("g_melee_only")
1477 || cvar("g_race") || cvar("g_cts") || cvar("g_nexball") || cvar("g_ca") || cvar("g_freezetag") || cvar("g_lms")))
1479 return req;
1480}

References cvar(), and MAPINFO_FEATURE_WEAPONS.

Referenced by _MapInfo_CheckMap(), GameTypeVote_SetGametype(), GenericCommand_maplist(), GotoFirstMap(), InstantAction_LoadMap(), make_mapinfo_Think(), MapInfo_ListAllAllowedMaps(), MapInfo_ListAllowedMaps(), MapVote_Start(), MapVote_Think(), RestoreGame(), spawnfunc(), spawnfunc(), and XonoticMapList_refilter().

◆ MapInfo_CurrentGametype()

◆ MapInfo_Enumerate()

◆ MapInfo_Filter_Free()

void MapInfo_Filter_Free ( )

Definition at line 239 of file mapinfo.qc.

240{
242 {
243 buf_del(_MapInfo_filtered);
245 }
246}

References _MapInfo_filtered, and _MapInfo_filtered_allocated.

Referenced by MapInfo_Shutdown().

◆ MapInfo_FilterGametype()

float MapInfo_FilterGametype ( Gametype pGametype,
int pFeatures,
int pFlagsRequired,
int pFlagsForbidden,
bool pAbortOnGenerate )

Definition at line 176 of file mapinfo.qc.

177{
178 return _MapInfo_FilterGametype(pGametype.gametype_flags, pFeatures, pFlagsRequired, pFlagsForbidden, pAbortOnGenerate);
179}
float _MapInfo_FilterGametype(vector pGametype, int pFeatures, int pFlagsRequired, int pFlagsForbidden, bool pAbortOnGenerate)
Definition mapinfo.qc:180

References _MapInfo_FilterGametype().

Referenced by GameTypeVote_SetGametype(), GenericCommand_maplist(), GotoFirstMap(), InstantAction_LoadMap(), make_mapinfo_Think(), MapInfo_ListAllAllowedMaps(), MapInfo_ListAllowedMaps(), MapVote_Start(), MapVote_Think(), RestoreGame(), spawnfunc(), spawnfunc(), and XonoticMapList_refilter().

◆ MapInfo_FilterList_Lookup()

float MapInfo_FilterList_Lookup ( float i)

Definition at line 156 of file mapinfo.qc.

157{
158 return stof(bufstr_get(_MapInfo_filtered, i));
159}

References _MapInfo_filtered, and stof().

Referenced by MapInfo_BSPName_ByID(), MapInfo_FindName(), MapInfo_ListAllAllowedMaps(), and MapInfo_ListAllowedMaps().

◆ MapInfo_FilterString()

void MapInfo_FilterString ( string sf)

Definition at line 212 of file mapinfo.qc.

213{
214 // this function further filters _MapInfo_filtered, which is prepared by MapInfo_FilterGametype by string
215 float i, j;
216 string title;
217
218 for(i = 0, j = -1; i < MapInfo_count; ++i)
219 {
220 if (MapInfo_Get_ByID(i))
221 {
222 // prepare for keyword filter
223 if (MapInfo_Map_title && strstrofs(MapInfo_Map_title, "<TITLE>", 0) == -1)
224 title = MapInfo_Map_title;
225 else
226 title = MapInfo_Map_bspname;
227 // keyword filter
228 if((strstrofs(strtolower(title), strtolower(sf), 0)) >= 0)
229 bufstr_set(_MapInfo_filtered, ++j, bufstr_get(_MapInfo_filtered, i));
230 }
231 }
232 MapInfo_count = j + 1;
234
235 // sometimes the glob isn't sorted nicely, so fix it here...
237}
bool MapInfo_Get_ByID(int i)
Definition mapinfo.qc:274

References _MapInfo_filtered, _MapInfo_FilterList_cmp(), _MapInfo_FilterList_swap(), heapsort(), MapInfo_ClearTemps(), MapInfo_count, MapInfo_Get_ByID(), MapInfo_Map_bspname, MapInfo_Map_title, NULL, strstrofs, and strtolower().

Referenced by XonoticMapList_refilter().

◆ MapInfo_FindName()

float MapInfo_FindName ( string s)

Definition at line 1418 of file mapinfo.qc.

1419{
1420 // if there is exactly one map of prefix s, return it
1421 // if not, return the null string
1422 // note that DP sorts glob results... so I can use a binary search
1423 float l, r, m, cmp;
1424 l = 0;
1425 r = MapInfo_count;
1426 // invariants: r is behind s, l-1 is equal or before
1427 while(l != r)
1428 {
1429 m = floor((l + r) / 2);
1432 if(cmp == 0)
1433 return m; // found and good
1434 if(cmp < 0)
1435 l = m + 1; // l-1 is before s
1436 else
1437 r = m; // behind s
1438 }
1441 // r == l, so: l is behind s, l-1 is before
1442 // SO: if there is any, l is the one with the right prefix
1443 // and l+1 may be one too
1444 if(l == MapInfo_count)
1445 {
1448 return -1; // no MapInfo_FindName_match, behind last item
1449 }
1451 {
1454 return -1; // wrong prefix
1455 }
1456 if(l == MapInfo_count - 1)
1457 return l; // last one, nothing can follow => unique
1459 {
1461 return -1; // ambigous MapInfo_FindName_match
1462 }
1463 return l;
1464}
string MapInfo_FindName_match
Definition mapinfo.qh:195
float MapInfo_FindName_firstResult
Definition mapinfo.qh:196
float floor(float f)
ERASEABLE bool startsWithNocase(string haystack, string needle)
Definition string.qh:239

References _MapInfo_GlobItem(), floor(), MapInfo_count, MapInfo_FilterList_Lookup(), MapInfo_FindName_firstResult, MapInfo_FindName_match, startsWithNocase(), strcasecmp, and string_null.

Referenced by MapInfo_FixName(), XonoticMapList_keyDown(), and XonoticMapList_refilter().

◆ MapInfo_FixName()

string MapInfo_FixName ( string s)

Definition at line 1466 of file mapinfo.qc.

1467{
1470}
float MapInfo_FindName(string s)
Definition mapinfo.qc:1418

References MapInfo_FindName(), and MapInfo_FindName_match.

Referenced by GameTypeVote_MapInfo_FixName(), and ValidateMap().

◆ MapInfo_ForbiddenFlags()

int MapInfo_ForbiddenFlags ( )

Definition at line 1655 of file mapinfo.qc.

1656{
1657 int f = MAPINFO_FLAG_FORBIDDEN;
1658
1659#ifdef GAMEQC
1660 if (!cvar("g_maplist_allow_hidden"))
1661#endif
1663
1664 if (!cvar("g_maplist_allow_frustrating"))
1666
1667 return f;
1668}
const int MAPINFO_FLAG_FORBIDDEN
Definition mapinfo.qh:162
const int MAPINFO_FLAG_HIDDEN
Definition mapinfo.qh:161
const int MAPINFO_FLAG_FRUSTRATING
Definition mapinfo.qh:163

References cvar(), MAPINFO_FLAG_FORBIDDEN, MAPINFO_FLAG_FRUSTRATING, and MAPINFO_FLAG_HIDDEN.

Referenced by GameTypeVote_MapInfo_FixName(), GameTypeVote_SetGametype(), GenericCommand_maplist(), getlsmaps(), GotoFirstMap(), InstantAction_LoadMap(), make_mapinfo_Think(), MapList_Add_All(), Maplist_Init(), MapVote_Start(), MapVote_Think(), RestoreGame(), spawnfunc(), spawnfunc(), and XonoticMapList_refilter().

◆ MapInfo_Get_ByID()

◆ MapInfo_Get_ByName()

int MapInfo_Get_ByName ( string pFilename,
float pAllowGenerate,
Gametype pGametypeToSet )

Definition at line 1382 of file mapinfo.qc.

1383{
1384 int r = MapInfo_Get_ByName_NoFallbacks(pFilename, pAllowGenerate, pGametypeToSet);
1385
1386 FOREACH(Gametypes, it.m_isForcedSupported(it), _MapInfo_Map_ApplyGametypeEx("", pGametypeToSet, it));
1387
1388 if(pGametypeToSet)
1389 {
1390 if(!(MapInfo_Map_supportedGametypes & pGametypeToSet.gametype_flags))
1391 {
1392 error("Can't select the requested gametype. This should never happen as the caller should prevent it!\n");
1393 //_MapInfo_Map_ApplyGametypeEx("", pGametypeToSet, MAPINFO_TYPE_DEATHMATCH);
1394 //return;
1395 }
1396 }
1397
1398 return r;
1399}
void _MapInfo_Map_ApplyGametypeEx(string s, Gametype pWantedType, Gametype pThisType)
Definition mapinfo.qc:543
float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gametype pGametypeToSet)
Definition mapinfo.qc:1035
#define error
Definition pre.qh:6

References _MapInfo_Map_ApplyGametypeEx(), error, FOREACH, MapInfo_Get_ByName_NoFallbacks(), and MapInfo_Map_supportedGametypes.

Referenced by _MapInfo_CheckMap(), _MapInfo_FilterGametype(), GameTypeVote_AvailabilityStatus(), get_mi_min_max(), MapInfo_Get_ByID(), MapInfo_LoadMapSettings(), and SendWelcomeMessage().

◆ MapInfo_Get_ByName_NoFallbacks()

float MapInfo_Get_ByName_NoFallbacks ( string pFilename,
int pAllowGenerate,
Gametype pGametypeToSet )

Definition at line 1035 of file mapinfo.qc.

1036{
1037 string fn;
1038 string s, t;
1039 float fh;
1040 int f, i;
1041 float r, n;
1042 string acl = MAPINFO_SETTEMP_ACL_USER;
1043
1044 if(strstrofs(pFilename, "/", 0) >= 0)
1045 {
1046 LOG_WARN("Invalid character in map name, ignored");
1047 return 0;
1048 }
1049
1050 if(pGametypeToSet == NULL)
1051 if(MapInfo_Cache_Retrieve(pFilename))
1052 return 1;
1053
1054 r = 1;
1055
1056 MapInfo_Map_bspname = pFilename;
1057
1058 // default all generic fields so they have "good" values in case something fails
1059 fn = strcat("maps/", pFilename, ".mapinfo");
1060 fh = fopen(fn, FILE_READ);
1061 if(fh < 0)
1062 {
1063 if(autocvar_g_mapinfo_q3compat == 1) // use arena data instead of generating a mapinfo file
1064 {
1065 // supporting .arena AND .defi for the same map
1066 bool success = false;
1067 fn = _MapInfo_FindArenaFile(pFilename, ".arena");
1068 if(fn != "" && (fh = fopen(fn, FILE_READ)) >= 0)
1069 {
1071 success = _MapInfo_ParseArena(fn, fh, pFilename, pGametypeToSet, false, false);
1072 fclose(fh);
1073 }
1074 fn = _MapInfo_FindArenaFile(pFilename, ".defi");
1075 if(fn != "" && (fh = fopen(fn, FILE_READ)) >= 0)
1076 {
1077 if(!success)
1079 success |= _MapInfo_ParseArena(fn, fh, pFilename, pGametypeToSet, true, false);
1080 fclose(fh);
1081 }
1082 if(success)
1083 goto mapinfo_handled; // skip generation
1084 }
1085
1086 fn = strcat("maps/autogenerated/", pFilename, ".mapinfo");
1087 fh = fopen(fn, FILE_READ);
1088 if(fh < 0)
1089 {
1090 if(!pAllowGenerate)
1091 return 0;
1093 r = _MapInfo_Generate(pFilename);
1094 if(!r)
1095 return 0;
1097 fh = fopen(fn, FILE_WRITE);
1098 fputs(fh, strcat("title ", MapInfo_Map_title, "\n"));
1099 fputs(fh, strcat("description ", MapInfo_Map_description, "\n"));
1100 fputs(fh, strcat("author ", MapInfo_Map_author, "\n"));
1102 {
1104 fputs(fh, strcat("cdtrack ", substring(_MapInfo_Map_worldspawn_music, 0, -4), "\n"));
1105 else
1106 fputs(fh, strcat("cdtrack ", _MapInfo_Map_worldspawn_music, "\n"));
1107 }
1108 else
1109 {
1110 n = tokenize_console(cvar_string("g_cdtracks_remaplist"));
1111 s = strcat(" ", cvar_string("g_cdtracks_dontusebydefault"), " ");
1112 for (;;)
1113 {
1114 i = floor(random() * n);
1115 if(strstrofs(s, strcat(" ", argv(i), " "), 0) < 0)
1116 break;
1117 }
1118 fputs(fh, strcat("cdtrack ", ftos(i + 1), "\n"));
1119 }
1121 fputs(fh, "has weapons\n");
1122 else
1123 fputs(fh, "// uncomment this if you added weapon pickups: has weapons\n");
1125 fputs(fh, "has turrets\n");
1126 else
1127 fputs(fh, "// uncomment this if you added turrets: has turrets\n");
1129 fputs(fh, "has vehicles\n");
1130 else
1131 fputs(fh, "// uncomment this if you added vehicles: has vehicles\n");
1133 fputs(fh, "frustrating\n");
1134
1135 FOREACH(Gametypes, MapInfo_Map_supportedGametypes & it.gametype_flags, {
1136 fputs(fh, sprintf("gametype %s // defaults: %s\n", MapInfo_Type_ToString(it), _MapInfo_GetDefaultEx(it)));
1137 });
1138
1139 fputs(fh, "// optional: fog density red green blue alpha mindist maxdist\n");
1140 fputs(fh, "// optional: settemp_for_type (all|gametypename) cvarname value\n");
1141 fputs(fh, "// optional: clientsettemp_for_type (all|gametypename) cvarname value\n");
1142 fputs(fh, "// optional: size mins_x mins_y mins_z maxs_x maxs_y maxs_z\n");
1143 fputs(fh, "// optional: hidden\n");
1144
1145 fclose(fh);
1146 r = 2;
1147 // return r;
1148 fh = fopen(fn, FILE_READ);
1149 if(fh < 0)
1150 error("... but I just wrote it!");
1151 }
1152
1153 if(WARN_COND)
1154 LOG_WARN("autogenerated mapinfo file ", fn, " has been loaded; please edit that file and move it to maps/", pFilename, ".mapinfo");
1155 }
1156
1158 for (;;)
1159 {
1160 if (!((s = fgets(fh))))
1161 break;
1162
1163 // catch different sorts of comments
1164 if(s == "") // empty lines
1165 continue;
1166 if(substring(s, 0, 1) == "#") // UNIX style
1167 continue;
1168 if(substring(s, 0, 2) == "//") // C++ style
1169 continue;
1170 if(substring(s, 0, 1) == "_") // q3map style
1171 continue;
1172
1173 float p = strstrofs(s, "//", 0);
1174 if(p >= 0)
1175 s = substring(s, 0, p);
1176
1177 t = car(s); s = cdr(s);
1178 if(t == "title")
1180 else if(t == "description")
1182 else if(t == "author")
1184 else if(t == "has")
1185 {
1186 t = car(s); // s = cdr(s);
1188 else if(t == "turrets") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_TURRETS;
1189 else if(t == "vehicles") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_VEHICLES;
1190 else if(t == "monsters") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_MONSTERS;
1191 else if(t == "new_toys") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_WEAPONS;
1192 else if(WARN_COND)
1193 LOG_WARN("Map ", pFilename, " supports unknown feature ", t, ", ignored");
1194 }
1195 else if(t == "hidden")
1196 {
1198 }
1199 else if(t == "forbidden")
1200 {
1202 }
1203 else if(t == "frustrating")
1204 {
1206 }
1207 else if(t == "donotwant" || t == "noautomaplist")
1208 {
1210 }
1211 else if(t == "gameversion_min")
1212 {
1213 if (cvar("gameversion") < stof(s))
1215 }
1216 else if(t == "type")
1217 {
1218 t = car(s); s = cdr(s);
1219 Gametype f = MapInfo_Type_FromString(t, true, false);
1220 //if(WARN_COND)
1221 //LOG_WARN("Map ", pFilename, " contains the legacy 'type' keyword which is deprecated and will be removed in the future. Please migrate the mapinfo file to 'gametype'.");
1222 if(f)
1223 _MapInfo_Map_ApplyGametype (s, pGametypeToSet, f, true);
1224 else if(WARN_COND)
1225 LOG_DEBUG("Map ", pFilename, " supports unknown gametype ", t, ", ignored");
1226 }
1227 else if(t == "gametype")
1228 {
1229 t = car(s); s = cdr(s);
1230 Gametype f = MapInfo_Type_FromString(t, true, false);
1231 if(f)
1232 _MapInfo_Map_ApplyGametypeEx (s, pGametypeToSet, f);
1233 else if(WARN_COND)
1234 LOG_DEBUG("Map ", pFilename, " supports unknown gametype ", t, ", ignored");
1235 }
1236 else if(t == "size")
1237 {
1238 float a, b, c, d, e;
1239 t = car(s); s = cdr(s); a = stof(t);
1240 t = car(s); s = cdr(s); b = stof(t);
1241 t = car(s); s = cdr(s); c = stof(t);
1242 t = car(s); s = cdr(s); d = stof(t);
1243 t = car(s); s = cdr(s); e = stof(t);
1244 if(s == "")
1245 {
1246 if(WARN_COND)
1247 LOG_WARN("Map ", pFilename, " contains an incorrect size line (not enough params), syntax: size mins_x mins_y mins_z maxs_x maxs_y maxs_z");
1248 }
1249 else
1250 {
1251 t = car(s); s = cdr(s); f = stof(t);
1252 if(s != "")
1253 {
1254 if(WARN_COND)
1255 LOG_WARN("Map ", pFilename, " contains an incorrect size line (too many params), syntax: size mins_x mins_y mins_z maxs_x maxs_y maxs_z");
1256 }
1257 else
1258 {
1259 if(a >= d || b >= e || c >= f)
1260 {
1261 if(WARN_COND)
1262 LOG_WARN("Map ", pFilename, " contains an incorrect size line, mins have to be < maxs");
1263 }
1264 else
1265 {
1266 MapInfo_Map_mins.x = a;
1267 MapInfo_Map_mins.y = b;
1268 MapInfo_Map_mins.z = c;
1269 MapInfo_Map_maxs.x = d;
1270 MapInfo_Map_maxs.y = e;
1271 MapInfo_Map_maxs.z = f;
1272 }
1273 }
1274 }
1275 }
1276 else if(t == "settemp_for_type")
1277 {
1278 t = car(s); s = cdr(s);
1279 bool all = t == "all";
1280 Gametype f = NULL;
1281 if(all || (f = MapInfo_Type_FromString(t, true, false)))
1282 {
1283 if((all ? MAPINFO_TYPE_ALL : f.gametype_flags) & pGametypeToSet.gametype_flags)
1284 {
1285 _MapInfo_Parse_Settemp(pFilename, acl, 0, s, 1);
1286 }
1287 }
1288 else
1289 {
1290 LOG_DEBUG("Map ", pFilename, " has a setting for unknown gametype ", t, ", ignored");
1291 }
1292 }
1293 else if(t == "clientsettemp_for_type")
1294 {
1295 t = car(s); s = cdr(s);
1296 bool all = t == "all";
1297 Gametype f = NULL;
1298 if(all || (f = MapInfo_Type_FromString(t, true, false)))
1299 {
1300 if((all ? MAPINFO_TYPE_ALL : f.gametype_flags) & pGametypeToSet.gametype_flags)
1301 {
1302 _MapInfo_Parse_Settemp(pFilename, acl, 1, s, 1);
1303 }
1304 }
1305 else
1306 {
1307 LOG_DEBUG("Map ", pFilename, " has a client setting for unknown gametype ", t, ", ignored");
1308 }
1309 }
1310 else if(t == "fog")
1311 {
1312 if (!cvar_value_issafe(s))
1313 {
1314 if(WARN_COND)
1315 LOG_WARN("Map ", pFilename, " contains a potentially harmful fog setting, ignored");
1316 }
1317 else
1318 MapInfo_Map_fog = s;
1319 }
1320 else if(t == "cdtrack")
1321 {
1322 t = car(s); s = cdr(s);
1323 // We do this only if pGametypeToSet even though this
1324 // content is theoretically gametype independent,
1325 // because MapInfo_Map_clientstuff contains otherwise
1326 // gametype dependent stuff. That way this value stays
1327 // empty when not setting a gametype to not set any
1328 // false expectations.
1329 if(pGametypeToSet)
1330 {
1331 if (!cvar_value_issafe(t))
1332 {
1333 if(WARN_COND)
1334 LOG_WARN("Map ", pFilename, " contains a potentially harmful cdtrack, ignored");
1335 }
1336 else
1338 MapInfo_Map_clientstuff, "cd loop \"", t, "\"\n"
1339 );
1340 }
1341 }
1342 else if(WARN_COND)
1343 LOG_WARN("Map ", pFilename, " provides unknown info item ", t, ", ignored");
1344 }
1345 fclose(fh);
1346
1347LABEL(mapinfo_handled)
1348#ifdef SVQC
1349 // if the map is currently loaded we can read worldspawn fields directly
1350 if (pFilename == mi_shortname)
1351 {
1352 if (MapInfo_Map_title == "<TITLE>")
1353 if (world.message != "")
1354 MapInfo_Map_title = world.message;
1355 if (MapInfo_Map_author == "<AUTHOR>")
1356 if ((s = GetField_fullspawndata(world, "author", false)) != "")
1358 }
1359#endif
1360 // Could skip removing author from title when it's source is .mapinfo
1361 // but must always do it for world.message and .arena/.defi as VQ3 didn't support author
1362 // so mappers tended to put it in world.message and/or longname.
1363 MapInfo_Map_title = MapInfo_title_sans_author(MapInfo_Map_title); // may set author if not set
1364
1365 if(MapInfo_Map_title == "<TITLE>")
1369 else
1371
1372 if (MapInfo_Map_author == "<AUTHOR>")
1373 MapInfo_Map_author = ""; // don't display "<AUTHOR>" in the UI (we do write it to .mapinfo files)
1374
1376 if(MapInfo_Map_supportedGametypes != '0 0 0')
1377 return r;
1378 if (WARN_COND)
1379 LOG_WARN("Map ", pFilename, " supports no gametypes, ignored");
1380 return 0;
1381}
string mi_shortname
Definition util.qh:126
#define LABEL(id)
Definition compiler.qh:34
const float FILE_WRITE
#define tokenize_console
#define LOG_DEBUG(...)
Definition log.qh:80
bool MapInfo_isRedundant(string fn, string t)
Definition mapinfo.qc:798
string MapInfo_title_sans_author(string title)
Removes author string from title (if found) and copies it to MapInfo_Map_author if that wasn't set.
Definition mapinfo.qc:772
float _MapInfo_Generate(string pFilename)
Definition mapinfo.qc:281
void MapInfo_Cache_Store()
Definition mapinfo.qc:69
float MapInfo_Cache_Retrieve(string map)
Definition mapinfo.qc:96
void _MapInfo_Map_Reset()
Definition mapinfo.qc:443
vector MAPINFO_TYPE_ALL
Definition mapinfo.qh:27
#define MAPINFO_SETTEMP_ACL_USER
Definition mapinfo.qh:236
const int MAPINFO_FLAG_DONOTWANT
Definition mapinfo.qh:164
void fputs(float fhandle, string s)
float random(void)
string argv(float n)
#define world
Definition post.qh:15
string GetField_fullspawndata(entity e, string fieldname, bool vfspath)
Retrieves the value of a map entity field from fullspawndata.
Definition main.qc:451

References _MapInfo_FindArenaFile(), _MapInfo_Generate(), _MapInfo_Map_ApplyGametype(), _MapInfo_Map_ApplyGametypeEx(), _MapInfo_Map_Reset(), _MapInfo_Map_worldspawn_music, _MapInfo_Parse_Settemp(), _MapInfo_ParseArena(), argv(), autocvar_g_mapinfo_q3compat, car(), cdr(), cvar(), cvar_string(), cvar_value_issafe(), error, fclose(), fgets(), FILE_READ, FILE_WRITE, floor(), fopen(), FOREACH, fputs(), ftos(), GetField_fullspawndata(), LABEL, LOG_DEBUG, LOG_WARN, MapInfo_Cache_Retrieve(), MapInfo_Cache_Store(), MAPINFO_FEATURE_MONSTERS, MAPINFO_FEATURE_TURRETS, MAPINFO_FEATURE_VEHICLES, MAPINFO_FEATURE_WEAPONS, MAPINFO_FLAG_DONOTWANT, MAPINFO_FLAG_FORBIDDEN, MAPINFO_FLAG_FRUSTRATING, MAPINFO_FLAG_HIDDEN, MapInfo_isRedundant(), MapInfo_Map_author, MapInfo_Map_bspname, MapInfo_Map_clientstuff, MapInfo_Map_description, MapInfo_Map_flags, MapInfo_Map_fog, MapInfo_Map_maxs, MapInfo_Map_mins, MapInfo_Map_supportedFeatures, MapInfo_Map_supportedGametypes, MapInfo_Map_title, MapInfo_Map_titlestring, MAPINFO_SETTEMP_ACL_USER, MapInfo_title_sans_author(), MAPINFO_TYPE_ALL, MapInfo_Type_FromString(), mi_shortname, NULL, random(), stof(), strcasecmp, strcat(), strstrofs, substring(), tokenize_console, WARN_COND, and world.

Referenced by MapInfo_Get_ByName().

◆ MapInfo_isRedundant()

bool MapInfo_isRedundant ( string fn,
string t )

Definition at line 798 of file mapinfo.qc.

799{
800 // normalize file name
801 fn = strreplace("_", "", fn);
802 fn = strreplace("-", "", fn);
803
804 // normalize visible title
805 t = strreplace(":", "", t);
806 t = strreplace(" ", "", t);
807 t = strreplace("_", "", t);
808 t = strreplace("-", "", t);
809 t = strreplace("'", "", t);
810 t = strdecolorize(t);
811
812 // we allow the visible title to have punctuation the file name does
813 // not, but not vice versa
814 if(!strcasecmp(fn, t))
815 return true;
816
817 return false;
818}

References strcasecmp.

Referenced by MapInfo_Get_ByName_NoFallbacks().

◆ MapInfo_ListAllAllowedMaps()

string MapInfo_ListAllAllowedMaps ( float pRequiredFlags,
float pForbiddenFlags )

Definition at line 1547 of file mapinfo.qc.

1548{
1549 string out;
1550
1551 // to make absolutely sure:
1553 _MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, pRequiredFlags, pForbiddenFlags, 0);
1554
1555 out = "";
1556 for(float i = 0; i < MapInfo_count; ++i)
1558
1559 MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), pRequiredFlags, pForbiddenFlags, 0);
1560
1561 return substring(out, 1, strlen(out) - 1);
1562}
float MapInfo_FilterGametype(Gametype pGametype, int pFeatures, int pFlagsRequired, int pFlagsForbidden, bool pAbortOnGenerate)
Definition mapinfo.qc:176
void MapInfo_Enumerate()
Definition mapinfo.qc:134

References _MapInfo_FilterGametype(), _MapInfo_GlobItem(), MapInfo_count, MapInfo_CurrentFeatures(), MapInfo_CurrentGametype(), MapInfo_Enumerate(), MapInfo_FilterGametype(), MapInfo_FilterList_Lookup(), MAPINFO_TYPE_ALL, strcat(), strlen, and substring().

◆ MapInfo_ListAllowedMaps()

string MapInfo_ListAllowedMaps ( Gametype type,
float pRequiredFlags,
float pForbiddenFlags )

Definition at line 1533 of file mapinfo.qc.

1534{
1535 string out;
1536
1537 // to make absolutely sure:
1539 MapInfo_FilterGametype(type, MapInfo_CurrentFeatures(), pRequiredFlags, pForbiddenFlags, 0);
1540
1541 out = "";
1542 for(float i = 0; i < MapInfo_count; ++i)
1544 return substring(out, 1, strlen(out) - 1);
1545}

References _MapInfo_GlobItem(), MapInfo_count, MapInfo_CurrentFeatures(), MapInfo_Enumerate(), MapInfo_FilterGametype(), MapInfo_FilterList_Lookup(), strcat(), strlen, and substring().

Referenced by GameTypeVote_SetGametype(), and Maplist_Init().

◆ MapInfo_LoadMap()

void MapInfo_LoadMap ( string s,
float reinit )

Definition at line 1514 of file mapinfo.qc.

1515{
1517 // we shouldn't need this, as LoadMapSettings already fixes the gametype
1518 //if(!MapInfo_CheckMap(s))
1519 //{
1520 // print("EMERGENCY: can't play the selected map in the given gametype. Falling back to DM.\n");
1521 // MapInfo_SwitchGameType(MAPINFO_TYPE_DEATHMATCH.gametype_flags);
1522 //}
1523
1524 LOG_INFO("Switching to map ", s);
1525
1527 if(reinit)
1528 localcmd(strcat("\nmap ", s, "\n"));
1529 else
1530 localcmd(strcat("\nchangelevel ", s, "\n"));
1531}
int cvar_settemp_restore()
Definition util.qc:845
void localcmd(string command,...)

References cvar_settemp_restore(), localcmd(), LOG_INFO, MapInfo_Map_supportedGametypes, and strcat().

Referenced by CampaignSetup(), InstantAction_LoadMap(), Map_Goto(), and MapList_LoadMap().

◆ MapInfo_LoadMapSettings()

void MapInfo_LoadMapSettings ( string s)

Definition at line 1571 of file mapinfo.qc.

1572{
1575
1576 if(!_MapInfo_CheckMap(s, true)) // with underscore, it keeps temps
1577 {
1578 if(cvar("g_mapinfo_allow_unsupported_modes_and_let_stuff_break"))
1579 {
1580 LOG_SEVERE("can't play the selected map in the given gametype. Working with only the override settings.");
1582 return; // do not call Get_ByName!
1583 }
1584
1585 if(MapInfo_Map_supportedGametypes == '0 0 0')
1586 {
1588 FOREACH(Gametypes, it.m_priority == 2,
1589 {
1590 MapInfo_Map_supportedGametypes |= it.gametype_flags;
1591 RandomSelection_AddEnt(it, 1, 1);
1592 });
1595 LOG_SEVEREF("Mapinfo system is not functional at all. Falling back to a preferred mode (%s).", t.mdl);
1598 return; // do not call Get_ByName!
1599 }
1600
1601#if 0
1602 // find the lowest bit in the supported gametypes
1603 // unnecessary now that we select one at random
1604 int _t = 1;
1605 while(!(MapInfo_Map_supportedGametypes & 1))
1606 {
1607 _t <<= 1;
1609 }
1610#endif
1612 Gametype t_prev = t;
1613 FOREACH(Gametypes, MapInfo_Map_supportedGametypes & it.gametype_flags,
1614 {
1615 RandomSelection_AddEnt(it, 1, it.m_priority);
1616 });
1619
1620 // t is now a supported mode!
1621 LOG_WARNF("can't play the selected map in the given gametype (%s). Falling back to a supported mode (%s).", t_prev.mdl, t.mdl);
1623 }
1624 if(!_MapInfo_CheckMap(s, false)) { // with underscore, it keeps temps
1625 LOG_WARNF("the selected map lacks features required by current settings; playing anyway.");
1626 }
1627 MapInfo_Get_ByName(s, 1, t);
1628}
#define LOG_SEVEREF(...)
Definition log.qh:58
#define LOG_SEVERE(...)
Definition log.qh:57
void MapInfo_LoadMapSettings_SaveGameType(Gametype t)
Definition mapinfo.qc:1564
ERASEABLE void RandomSelection_Init()
Definition random.qc:4
entity RandomSelection_chosen_ent
Definition random.qh:5

References _MapInfo_CheckMap(), _MapInfo_Map_ApplyGametypeEx(), cvar(), floor(), FOREACH, LOG_SEVERE, LOG_SEVEREF, LOG_WARNF, MapInfo_CurrentGametype(), MapInfo_Get_ByName(), MapInfo_LoadMapSettings_SaveGameType(), MapInfo_Map_supportedGametypes, RandomSelection_chosen_ent, and RandomSelection_Init().

Referenced by InitGameplayMode().

◆ MapInfo_LoadMapSettings_SaveGameType()

void MapInfo_LoadMapSettings_SaveGameType ( Gametype t)

Definition at line 1564 of file mapinfo.qc.

1565{
1567 cvar_set("gamecfg", t.mdl);
1569}
void MapInfo_SwitchGameType(Gametype t)
Definition mapinfo.qc:1509
Gametype MapInfo_LoadedGametype
Definition mapinfo.qh:220

References cvar_set(), MapInfo_LoadedGametype, and MapInfo_SwitchGameType().

Referenced by MapInfo_LoadMapSettings().

◆ MapInfo_RequiredFlags()

int MapInfo_RequiredFlags ( )

◆ MapInfo_Shutdown()

◆ MapInfo_SwitchGameType()

void MapInfo_SwitchGameType ( Gametype t)

Definition at line 1509 of file mapinfo.qc.

1510{
1511 FOREACH(Gametypes, true, cvar_set(it.netname, (it == t) ? "1" : "0"));
1512}

References cvar_set(), and FOREACH.

Referenced by CampaignPreInit(), GameTypeVote_SetGametype(), InstantAction_LoadMap(), MapInfo_LoadMapSettings_SaveGameType(), target_changelevel_use(), and XonoticGametypeList_saveCvars().

◆ MapInfo_title_sans_author()

string MapInfo_title_sans_author ( string title)

Removes author string from title (if found) and copies it to MapInfo_Map_author if that wasn't set.

Definition at line 772 of file mapinfo.qc.

773{
774 int offset;
775
776 if ((offset = strstrofs(title, " by ", 0)) >= 0)
777 {
778 if (MapInfo_Map_author == "<AUTHOR>")
779 MapInfo_Map_author = substring(title, offset + 4, strlen(title) - (offset + 4));
780 title = substring(title, 0, offset);
781 }
782 else if ((offset = strstrofs(title, " (by ", 0)) >= 0 || (offset = strstrofs(title, " [by ", 0)) >= 0)
783 {
784 if (MapInfo_Map_author == "<AUTHOR>")
785 MapInfo_Map_author = substring(title, offset + 5, strlen(title) - (offset + 5) - 1);
786 title = substring(title, 0, offset);
787 }
788 else if ((offset = strstrofs(title, "Made By ", 0)) >= 0) // often at the start of the string
789 {
790 if (MapInfo_Map_author == "<AUTHOR>")
791 MapInfo_Map_author = substring(title, offset + 8, strlen(title) - (offset + 8));
792 title = substring(title, 0, offset);
793 }
794
795 return title != "" ? title : "<TITLE>";
796}

References MapInfo_Map_author, strlen, strstrofs, and substring().

Referenced by MapInfo_Get_ByName_NoFallbacks().

◆ MapInfo_Type_Description()

string MapInfo_Type_Description ( Gametype t)

Definition at line 650 of file mapinfo.qc.

651{
652 return t ? t.m_description : "";
653}

Referenced by GameTypeVote_ReadOption(), and XonoticGametypeList_focusedItemChangeNotify().

◆ MapInfo_Type_FromString()

Gametype MapInfo_Type_FromString ( string gtype,
bool dowarn,
bool is_q3compat )

Definition at line 620 of file mapinfo.qc.

621{
622 string replacement = "";
623
624 switch (gtype)
625 {
626 case "nexball": replacement = "nb"; break;
627 case "freezetag": replacement = "ft"; break;
628 case "keepaway": replacement = "ka"; break;
629 case "invasion": replacement = "inv"; break;
630 case "assault": replacement = "as"; break;
631 case "race": replacement = "rc"; break;
632 // Q3/QL compat, see DoesQ3ARemoveThisEntity() in quake3.qc for complete lists
633 case "ffa": replacement = "dm"; break;
634 case "cctf": // from ThreeWave, maps with this should all have "ctf" too
635 case "oneflag": replacement = "ctf"; break;
636 case "tourney": replacement = "duel"; break;
637 case "arena": // which Q3 mod is this from? In Nexuiz it was 'duel with rounds'.
638 if(is_q3compat) { replacement = "ca"; } break;
639 }
640 if (replacement != "")
641 {
642 if (dowarn && WARN_COND)
643 LOG_WARNF("MapInfo_Type_FromString (probably %s): using deprecated name '%s'. Should use '%s'.", MapInfo_Map_bspname, gtype, replacement);
644 gtype = replacement;
645 }
646 FOREACH(Gametypes, it.mdl == gtype, return it);
647 return NULL;
648}

References FOREACH, LOG_WARNF, MapInfo_Map_bspname, NULL, and WARN_COND.

Referenced by _MapInfo_ParseArena(), Campaign_Invalid(), CampaignPreInit(), GameCommand_gametype(), GameTypeVote_AvailabilityStatus(), GameTypeVote_ReadOption(), GameTypeVote_Type_FromString(), MapInfo_CurrentGametype(), MapInfo_Get_ByName_NoFallbacks(), target_changelevel_use(), and XonoticServerInfoDialog_loadServerInfo().

◆ MapInfo_Type_ToString()

◆ MapInfo_Type_ToText()

◆ MapReadSizes()

bool MapReadSizes ( string map)

Definition at line 1401 of file mapinfo.qc.

1402{
1403 // TODO: implement xonotic#28 / xonvote 172 (sizes in mapinfo)
1404 string readsize_msg = strcat("MapReadSizes ", map);
1405 float fh = fopen(strcat("maps/", map, ".sizes"), FILE_READ);
1406 if(fh >= 0)
1407 {
1408 map_minplayers = stoi(fgets(fh));
1409 map_maxplayers = stoi(fgets(fh));
1410 fclose(fh);
1411 LOG_TRACEF(readsize_msg, ": ok, min %d max %d", map_minplayers, map_maxplayers);
1412 return true;
1413 }
1414 LOG_TRACE(readsize_msg, ": not found");
1415 return false;
1416}
#define stoi(s)
Definition int.qh:4
#define LOG_TRACEF(...)
Definition log.qh:77
int map_minplayers
Definition mapinfo.qh:190
int map_maxplayers
Definition mapinfo.qh:191

References fclose(), fgets(), FILE_READ, fopen(), LOG_TRACE, LOG_TRACEF, map_maxplayers, map_minplayers, stoi, and strcat().

Referenced by GameplayMode_DelayedInit(), and MapHasRightSize().

◆ unquote()

string unquote ( string s)

Definition at line 254 of file mapinfo.qc.

255{
256 float l = strlen(s);
257 for(float i = 0; i < l; ++i)
258 {
259 string ch = substring(s, i, 1);
260 if((ch != " ") && (ch != "\""))
261 {
262 for(float j = l - i - 1; j > 0; --j)
263 {
264 ch = substring(s, i+j, 1);
265 if(ch != " ") if(ch != "\"")
266 return substring(s, i, j+1);
267 }
268 return substring(s, i, 1);
269 }
270 }
271 return "";
272}

References strlen, and substring().

Referenced by _MapInfo_Generate().

Variable Documentation

◆ _MapInfo_Cache_Active

◆ _MapInfo_Cache_Buf_IndexToMapData

int _MapInfo_Cache_Buf_IndexToMapData

◆ _MapInfo_Cache_DB_NameToIndex

int _MapInfo_Cache_DB_NameToIndex

◆ _MapInfo_filtered

◆ _MapInfo_filtered_allocated

float _MapInfo_filtered_allocated

Definition at line 155 of file mapinfo.qc.

Referenced by _MapInfo_FilterGametype(), and MapInfo_Filter_Free().

◆ _MapInfo_globcount

float _MapInfo_globcount

Definition at line 123 of file mapinfo.qc.

Referenced by _MapInfo_FilterGametype(), and MapInfo_Enumerate().

◆ _MapInfo_globhandle

float _MapInfo_globhandle

Definition at line 124 of file mapinfo.qc.

Referenced by _MapInfo_GlobItem(), MapInfo_Enumerate(), and MapInfo_Shutdown().

◆ _MapInfo_globopen

float _MapInfo_globopen

Definition at line 122 of file mapinfo.qc.

Referenced by _MapInfo_GlobItem(), MapInfo_Enumerate(), and MapInfo_Shutdown().

◆ _MapInfo_Map_worldspawn_music

string _MapInfo_Map_worldspawn_music

Definition at line 279 of file mapinfo.qc.

Referenced by _MapInfo_Generate(), and MapInfo_Get_ByName_NoFallbacks().

◆ autocvar_g_mapinfo_ignore_warnings

bool autocvar_g_mapinfo_ignore_warnings

Definition at line 14 of file mapinfo.qc.

◆ autocvar_g_mapinfo_q3compat

int autocvar_g_mapinfo_q3compat = 1

Definition at line 11 of file mapinfo.qc.

Referenced by _MapInfo_Generate(), and MapInfo_Get_ByName_NoFallbacks().