From: TimePath Date: Fri, 14 Aug 2015 00:11:36 +0000 (+1000) Subject: Objectify gametypes X-Git-Tag: xonotic-v0.8.2~2073^3~1 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=50350e3ca2c9ad942ac410b71fd8d638307feab4;p=xonotic%2Fxonotic-data.pk3dir.git Objectify gametypes --- diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index a544e4fbd..25cbf8e88 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -142,8 +142,6 @@ void CSQC_Init(void) // needs to be done so early because of the constants they create static_init(); CALL_ACCUMULATED_FUNCTION(RegisterWeapons); - CALL_ACCUMULATED_FUNCTION(RegisterMonsters); - CALL_ACCUMULATED_FUNCTION(RegisterGametypes); CALL_ACCUMULATED_FUNCTION(RegisterNotifications); CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); CALL_ACCUMULATED_FUNCTION(RegisterHUD_Panels); diff --git a/qcsrc/common/items/all.qh b/qcsrc/common/items/all.qh index c42139e25..3bbd1946f 100644 --- a/qcsrc/common/items/all.qh +++ b/qcsrc/common/items/all.qh @@ -5,7 +5,7 @@ void RegisterItems(); const int MAX_ITEMS = 24; -entity ITEMS[MAX_ITEMS]; +entity ITEMS[MAX_ITEMS], ITEMS_first, ITEMS_last; int ITEM_COUNT; /** If you register a new item, make sure to add it to all.inc */ #define REGISTER_ITEM(id, class) REGISTER(RegisterItems, ITEM, ITEMS, ITEM_COUNT, id, class, m_id) diff --git a/qcsrc/common/mapinfo.qc b/qcsrc/common/mapinfo.qc index 55165a12c..b8622fd32 100644 --- a/qcsrc/common/mapinfo.qc +++ b/qcsrc/common/mapinfo.qc @@ -603,7 +603,7 @@ void _MapInfo_Map_ApplyGametype(string s, int pWantedType, int pThisType, int lo string _MapInfo_GetDefaultEx(float t) { entity e; - for(e = MapInfo_Type_first; e; e = e.enemy) + for(e = MAPINFO_TYPES_first; e; e = e.enemy) if(t == e.items) return e.model2; return ""; @@ -612,7 +612,7 @@ string _MapInfo_GetDefaultEx(float t) float _MapInfo_GetTeamPlayBool(float t) { entity e; - for(e = MapInfo_Type_first; e; e = e.enemy) + for(e = MAPINFO_TYPES_first; e; e = e.enemy) if(t == e.items) return e.team; return false; @@ -754,7 +754,7 @@ float MapInfo_Type_FromString(string t) } if(t == "all") return MAPINFO_TYPE_ALL; - for(e = MapInfo_Type_first; e; e = e.enemy) + for(e = MAPINFO_TYPES_first; e; e = e.enemy) if(t == e.mdl) return e.items; return 0; @@ -763,7 +763,7 @@ float MapInfo_Type_FromString(string t) string MapInfo_Type_Description(float t) { entity e; - for(e = MapInfo_Type_first; e; e = e.enemy) + for(e = MAPINFO_TYPES_first; e; e = e.enemy) if(t == e.items) return e.gametype_description; return ""; @@ -774,7 +774,7 @@ string MapInfo_Type_ToString(float t) entity e; if(t == MAPINFO_TYPE_ALL) return "all"; - for(e = MapInfo_Type_first; e; e = e.enemy) + for(e = MAPINFO_TYPES_first; e; e = e.enemy) if(t == e.items) return e.mdl; return ""; @@ -783,7 +783,7 @@ string MapInfo_Type_ToString(float t) string MapInfo_Type_ToText(float t) { entity e; - for(e = MapInfo_Type_first; e; e = e.enemy) + for(e = MAPINFO_TYPES_first; e; e = e.enemy) if(t == e.items) return e.message; /* xgettext:no-c-format */ @@ -1285,7 +1285,7 @@ int MapInfo_CurrentGametype() { entity e; int prev = cvar("gamecfg"); - for(e = MapInfo_Type_first; e; e = e.enemy) + for(e = MAPINFO_TYPES_first; e; e = e.enemy) if(cvar(e.netname)) if(prev != e.items) return e.items; @@ -1315,7 +1315,7 @@ float MapInfo_CheckMap(string s) // returns 0 if the map can't be played with th void MapInfo_SwitchGameType(int t) { - for (entity e = MapInfo_Type_first; e; e = e.enemy) { + for (entity e = MAPINFO_TYPES_first; e; e = e.enemy) { cvar_set(e.netname, (t == e.items) ? "1" : "0"); } } diff --git a/qcsrc/common/mapinfo.qh b/qcsrc/common/mapinfo.qh index 3038cce60..8d10b02ab 100644 --- a/qcsrc/common/mapinfo.qh +++ b/qcsrc/common/mapinfo.qh @@ -3,44 +3,52 @@ #include "util.qh" +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, string_null) + /** game type short name */ + ATTRIB(Gametype, mdl, string, string_null) + /** human readable name */ + ATTRIB(Gametype, message, string, string_null) + /** does this gametype support teamplay? */ + ATTRIB(Gametype, team, bool, false) + /** game type defaults */ + ATTRIB(Gametype, model2, string, string_null) + /** game type description */ + ATTRIB(Gametype, gametype_description, string, string_null) + CONSTRUCTOR(Gametype, string hname, string sname, string g_name, bool gteamplay, string defaults, string gdescription) + { + this.netname = g_name; + this.mdl = sname; + this.message = hname; + this.team = gteamplay; + this.model2 = defaults; + this.gametype_description = gdescription; + return this; + } +ENDCLASS(Gametype) + +void RegisterGametypes(); +const int MAX_MAPINFO_TYPES = 24; +entity MAPINFO_TYPES[MAX_MAPINFO_TYPES], MAPINFO_TYPES_first, MAPINFO_TYPES_last; +int MAPINFO_TYPE_COUNT; int MAPINFO_TYPE_ALL; -entity MapInfo_Type_first; -entity MapInfo_Type_last; -.entity enemy; // internal next pointer - -.int items; // game type ID -.string netname; // game type name as in cvar (with g_ prefix) -.string mdl; // game type short name -.string message; // human readable name -.int team; // does this gametype support teamplay? -.string model2; // game type defaults -.string gametype_description; // game type description - -#define REGISTER_GAMETYPE(hname,sname,g_name,NAME,gteamplay,defaults,gdescription) \ - int MAPINFO_TYPE_##NAME; \ - entity MapInfo_Type##g_name; \ - void RegisterGametypes_##g_name() \ - { \ - MAPINFO_TYPE_##NAME = MAPINFO_TYPE_ALL + 1; \ - MAPINFO_TYPE_ALL |= MAPINFO_TYPE_##NAME; \ - MapInfo_Type##g_name = spawn(); \ - MapInfo_Type##g_name.items = MAPINFO_TYPE_##NAME; \ - MapInfo_Type##g_name.netname = #g_name; \ - MapInfo_Type##g_name.mdl = #sname; \ - MapInfo_Type##g_name.message = hname; \ - MapInfo_Type##g_name.team = gteamplay; \ - MapInfo_Type##g_name.model2 = defaults; \ - MapInfo_Type##g_name.gametype_description = gdescription; \ - if(!MapInfo_Type_first) \ - MapInfo_Type_first = MapInfo_Type##g_name; \ - if(MapInfo_Type_last) \ - MapInfo_Type_last.enemy = MapInfo_Type##g_name; \ - MapInfo_Type_last = MapInfo_Type##g_name; \ - } \ - ACCUMULATE_FUNCTION(RegisterGametypes, RegisterGametypes_##g_name) + +#define REGISTER_GAMETYPE(hname, sname, g_name, NAME, gteamplay, defaults, gdescription) \ + int MAPINFO_TYPE_##NAME; \ + REGISTER(RegisterGametypes, MAPINFO_TYPE, MAPINFO_TYPES, MAPINFO_TYPE_COUNT, g_name, Gametype, m_id) { \ + CONSTRUCT(Gametype, hname, #sname, #g_name, gteamplay, defaults, gdescription); \ + /* same as `1 << m_id` */ \ + MAPINFO_TYPE_##NAME = MAPINFO_TYPE_ALL + 1; MAPINFO_TYPE_ALL |= MAPINFO_TYPE_##NAME; \ + this.items = MAPINFO_TYPE_##NAME; \ + } +REGISTER_REGISTRY(RegisterGametypes) #define IS_GAMETYPE(NAME) \ - (MapInfo_LoadedGametype == MAPINFO_TYPE_##NAME) + (MapInfo_LoadedGametype == MAPINFO_TYPE_##NAME) REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,false,"timelimit=20 pointlimit=30 leadlimit=0",_("Kill all enemies")); #define g_dm IS_GAMETYPE(DEATHMATCH) diff --git a/qcsrc/common/monsters/all.qh b/qcsrc/common/monsters/all.qh index 30de42cd9..38a83a0f1 100644 --- a/qcsrc/common/monsters/all.qh +++ b/qcsrc/common/monsters/all.qh @@ -5,7 +5,7 @@ void RegisterMonsters(); const int MON_MAXCOUNT = 24; -entity monster_info[MON_MAXCOUNT]; +entity monster_info[MON_MAXCOUNT], monster_info_first, monster_info_last; entity get_monsterinfo(float id); int MON_COUNT; const int MON_FIRST = 1; @@ -24,6 +24,7 @@ const int MON_FIRST = 1; this.model = strzone(strcat("models/monsters/", modelname)); \ } \ REGISTER_INIT(MON, id) +REGISTER_REGISTRY(RegisterMonsters) #include "../util.qh" diff --git a/qcsrc/common/nades.qh b/qcsrc/common/nades.qh index 75495abca..7b50bcc56 100644 --- a/qcsrc/common/nades.qh +++ b/qcsrc/common/nades.qh @@ -25,7 +25,7 @@ const int PROJECTILE_NADE_MONSTER_BURN = 83; void RegisterNades(); const int NADES_MAX = 8; -entity NADES[NADES_MAX]; +entity NADES[NADES_MAX], NADES_first, NADES_last; int NADES_COUNT; #define REGISTER_NADE(id) REGISTER(RegisterNades, NADE_TYPE, NADES, NADES_COUNT, id, Nade, m_id) REGISTER_REGISTRY(RegisterNades) diff --git a/qcsrc/common/registry.qh b/qcsrc/common/registry.qh index 0087c1bf7..3ce8c471e 100644 --- a/qcsrc/common/registry.qh +++ b/qcsrc/common/registry.qh @@ -8,11 +8,15 @@ #define REGISTER(initfunc, ns, array, counter, id, class, fld) \ entity ns##_##id; \ REGISTER_INIT(ns, id) { } \ + .entity enemy; /* internal next pointer */ \ void Register_##ns##_##id() { \ entity this = NEW(class); \ ns##_##id = this; \ this.fld = counter; \ array[counter++] = this; \ + if (!array##_first) array##_first = this; \ + if ( array##_last) array##_last.enemy = this; \ + array##_last = this; \ Register_##ns##_##id##_init(this); \ } \ ACCUMULATE_FUNCTION(initfunc, Register_##ns##_##id) \ diff --git a/qcsrc/menu/menu.qc b/qcsrc/menu/menu.qc index b0146349f..b2a85093c 100644 --- a/qcsrc/menu/menu.qc +++ b/qcsrc/menu/menu.qc @@ -82,7 +82,6 @@ void m_init() // needs to be done so early because of the constants they create static_init(); CALL_ACCUMULATED_FUNCTION(RegisterWeapons); - CALL_ACCUMULATED_FUNCTION(RegisterGametypes); RegisterSLCategories(); diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 1c88f0472..9f9f1f246 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -561,8 +561,6 @@ void spawnfunc___init_dedicated_server(void) // needs to be done so early because of the constants they create static_init(); CALL_ACCUMULATED_FUNCTION(RegisterWeapons); - CALL_ACCUMULATED_FUNCTION(RegisterMonsters); - CALL_ACCUMULATED_FUNCTION(RegisterGametypes); CALL_ACCUMULATED_FUNCTION(RegisterNotifications); CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); CALL_ACCUMULATED_FUNCTION(RegisterBuffs); @@ -612,8 +610,6 @@ void spawnfunc_worldspawn (void) // needs to be done so early because of the constants they create static_init(); CALL_ACCUMULATED_FUNCTION(RegisterWeapons); - CALL_ACCUMULATED_FUNCTION(RegisterMonsters); - CALL_ACCUMULATED_FUNCTION(RegisterGametypes); CALL_ACCUMULATED_FUNCTION(RegisterNotifications); CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); CALL_ACCUMULATED_FUNCTION(RegisterBuffs);