#pragma once #include "util.qh" // info about a map that MapInfo loads string MapInfo_Map_bspname; string MapInfo_Map_title; string MapInfo_Map_titlestring; // either bspname: title or just title, depending on whether bspname is redundant string MapInfo_Map_description; string MapInfo_Map_author; string MapInfo_Map_clientstuff; // not in cache, only for map load string MapInfo_Map_fog; // not in cache, only for map load vector MapInfo_Map_supportedGametypes; int MapInfo_Map_supportedFeatures; int MapInfo_Map_flags; vector MapInfo_Map_mins; // these are '0 0 0' if not supported! vector MapInfo_Map_maxs; // these are '0 0 0' if not specified! const int GAMETYPE_FLAG_TEAMPLAY = BIT(0); // teamplay based const int GAMETYPE_FLAG_USEPOINTS = BIT(1); // gametype has point-based scoring const int GAMETYPE_FLAG_PREFERRED = BIT(2); // preferred (when available) in random selections const int GAMETYPE_FLAG_PRIORITY = BIT(3); // priority selection when preferred gametype isn't available in random selections const int GAMETYPE_FLAG_HIDELIMITS = BIT(4); // don't display a score limit needed for winning the match in the scoreboard const int GAMETYPE_FLAG_WEAPONARENA = BIT(5); // gametype has a forced weapon arena, weapon arena mutators should disable themselves when this is set const int GAMETYPE_FLAG_1V1 = BIT(6); // 1v1 gameplay vector MAPINFO_TYPE_ALL; .vector gametype_flags; // must be defined before the registry vector _GametypeFlags_FromGametype(int a); CLASS(Gametype, Object) ATTRIB(Gametype, m_id, int, 0); /** game type ID */ ATTRIB(Gametype, items, int, 0); /** game type name as in cvar (with g_ prefix) */ ATTRIB(Gametype, netname, string); /** game type short name */ ATTRIB(Gametype, mdl, string); /** human readable name */ ATTRIB(Gametype, message, string); /** does this gametype support teamplay? */ ATTRIB(Gametype, team, bool, false); /** does this gametype use a point limit? */ ATTRIB(Gametype, frags, bool, true); /** should this gametype display a score limit in the scoreboard? */ ATTRIB(Gametype, m_hidelimits, bool, false); /** does this gametype enforce its own weapon arena? */ ATTRIB(Gametype, m_weaponarena, bool, false); /** 1v1 gameplay? */ ATTRIB(Gametype, m_1v1, bool, false); /** game type defaults */ ATTRIB(Gametype, model2, string); /** game type description */ ATTRIB(Gametype, gametype_description, string); /** game type priority in random selections */ ATTRIB(Gametype, m_priority, int, 0); #ifdef CSQC ATTRIB(Gametype, m_modicons, void(vector pos, vector mySize)); ATTRIB(Gametype, m_modicons_reset, void()); ATTRIB(Gametype, m_modicons_export, void(int fh)); #endif /** DO NOT USE, this is compatibility for legacy maps! */ ATTRIB(Gametype, m_legacydefaults, string, ""); ATTRIB(Gametype, m_mutators, string); METHOD(Gametype, m_parse_mapinfo, bool(string k, string v)) { return false; } METHOD(Gametype, m_generate_mapinfo, void(Gametype this, string v)) { TC(Gametype, this); } METHOD(Gametype, m_isTwoBaseMode, bool()) { return false; } METHOD(Gametype, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter)) { return false; } METHOD(Gametype, m_isForcedSupported, bool(Gametype this)) { return false; } METHOD(Gametype, m_configuremenu, void(Gametype this, entity menu, void(entity me, string pLabel, float pMin, float pMax, float pStep, string pCvar, string tCvar, string pTooltip) returns)) { TC(Gametype, this); returns(menu, _("Frag limit:"), 5, 100, 5, "fraglimit_override", string_null, _("The amount of frags needed before the match will end")); } METHOD(Gametype, describe, string(Gametype this)) { TC(Gametype, this); return this.gametype_description; } METHOD(Gametype, display, void(Gametype this, void(string name, string icon) returns)) { TC(Gametype, this); returns(this.message, strcat("gametype_", this.mdl)); } METHOD(Gametype, gametype_init, void(Gametype this, string hname, string sname, string g_name, int gflags, string mutators, string defaults, string gdescription)) { this.netname = g_name; this.mdl = sname; this.message = hname; this.team = (gflags & GAMETYPE_FLAG_TEAMPLAY); this.m_mutators = cons(sname, mutators); this.model2 = defaults; this.gametype_description = gdescription; this.frags = (gflags & GAMETYPE_FLAG_USEPOINTS); this.m_priority = ((gflags & GAMETYPE_FLAG_PREFERRED) ? 2 : ((gflags & GAMETYPE_FLAG_PRIORITY) ? 1 : 0)); this.m_hidelimits = (gflags & GAMETYPE_FLAG_HIDELIMITS); this.m_weaponarena = (gflags & GAMETYPE_FLAG_WEAPONARENA); this.m_1v1 = (gflags & GAMETYPE_FLAG_1V1); } ENDCLASS(Gametype) REGISTRY(Gametypes, 32) REGISTER_REGISTRY(Gametypes) REGISTRY_SORT(Gametypes) REGISTRY_CHECK(Gametypes) REGISTRY_DEFINE_GET(Gametypes, NULL) STATIC_INIT(Gametypes_renumber) { FOREACH(Gametypes, true, { it.m_id = i; vector set = it.gametype_flags = _GametypeFlags_FromGametype(it.m_id); MAPINFO_TYPE_ALL |= set; }); } #define REGISTER_GAMETYPE(NAME, inst) REGISTER(Gametypes, MAPINFO_TYPE, NAME, m_id, inst) #ifndef CSQC // NOTE: ISGAMETYPE in csqc (temporary hack) #define IS_GAMETYPE(NAME) (MapInfo_LoadedGametype == MAPINFO_TYPE_##NAME) #endif const int MAPINFO_FEATURE_WEAPONS = 1; // not defined for instagib-only maps const int MAPINFO_FEATURE_VEHICLES = 2; const int MAPINFO_FEATURE_TURRETS = 4; const int MAPINFO_FEATURE_MONSTERS = 8; const int MAPINFO_FLAG_HIDDEN = 1; // not in lsmaps/menu/vcall/etc., can just be changed to manually const int MAPINFO_FLAG_FORBIDDEN = 2; // don't even allow the map by a cvar setting that allows hidden maps const int MAPINFO_FLAG_FRUSTRATING = 4; // this map is near impossible to play, enable at your own risk const int MAPINFO_FLAG_DONOTWANT = 8; // do not include in GUI voting screen or select in GotoNextMap()/GetNextMap(), unless added with `suggestmap` or required as a fallback float MapInfo_count; // load MapInfo_count; generate mapinfo for maps that miss them, and clear the // cache; you need to call MapInfo_FilterGametype afterwards! void MapInfo_Enumerate(); // filter the info by game type mask (updates MapInfo_count) float MapInfo_progress; float MapInfo_FilterGametype(Gametype gametypeFlags, float features, float pFlagsRequired, float pFlagsForbidden, float pAbortOnGenerate); // 1 on success, 0 on temporary failure (call it again next frame then; use MapInfo_progress as progress indicator) float _MapInfo_FilterGametype(vector gametypeFlags, float features, float pFlagsRequired, float pFlagsForbidden, float pAbortOnGenerate); // 1 on success, 0 on temporary failure (call it again next frame then; use MapInfo_progress as progress indicator) void MapInfo_FilterString(string sf); // filter _MapInfo_filtered (created by MapInfo_FilterGametype) with keyword int MapInfo_CurrentFeatures(); // retrieves currently required features from cvars Gametype MapInfo_CurrentGametype(); // retrieves current gametype from cvars int MapInfo_ForbiddenFlags(); // retrieves current flags from cvars int MapInfo_RequiredFlags(); // retrieves current flags from cvars // load info about the i-th map into the MapInfo_Map_* globals bool MapInfo_Get_ByID(int i); // 1 on success, 0 on failure string MapInfo_BSPName_ByID(float i); // load info about a map by name into the MapInfo_Map_* globals int MapInfo_Get_ByName(string s, float allowGenerate, Gametype gametypeToSet); // 1 on success, 0 on failure, 2 if it autogenerated a mapinfo file // load map-specific player limits int map_minplayers; int map_maxplayers; bool MapReadSizes(string map); // look for a map by a prefix, returns the actual map name on success, string_null on failure or ambigous match string MapInfo_FindName_match; // the name of the map that was found float MapInfo_FindName_firstResult; // -1 if none were found, index of first one if not unique but found (FindName then returns -1) float MapInfo_FindName(string s); string MapInfo_FixName(string s); // play a map float MapInfo_CheckMap(string s); // returns 0 if the map can't be played with the current settings void MapInfo_LoadMap(string s, float reinit); // list all maps for the current game type string MapInfo_ListAllowedMaps(Gametype type, float pFlagsRequired, float pFlagsForbidden); // list all allowed maps (for any game type) string MapInfo_ListAllAllowedMaps(float pFlagsRequired, float pFlagsForbidden); // gets a gametype from a string string _MapInfo_GetDefaultEx(Gametype t); float _MapInfo_GetTeamPlayBool(Gametype t); Gametype MapInfo_Type_FromString(string t, bool dowarn, bool is_q3compat); string MapInfo_Type_Description(Gametype t); string MapInfo_Type_ToString(Gametype t); string MapInfo_Type_ToText(Gametype t); void MapInfo_SwitchGameType(Gametype t); // to be called from worldspawn to set up cvars void MapInfo_LoadMapSettings(string s); Gametype MapInfo_LoadedGametype; // game type that was active during map load 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 void MapInfo_Shutdown(); // call this in the shutdown handler #define MAPINFO_SETTEMP_ACL_USER cvar_string("g_mapinfo_settemp_acl") #define MAPINFO_SETTEMP_ACL_SYSTEM "-g_mapinfo_* -rcon_* -_* -g_ban* +*"