#include <client/miscfunctions.qh>
#include <common/ent_cs.qh>
-#include <common/mapinfo.qh>
// Info messages (#14)
InfoMessage(s);
}
- MUTATOR_CALLHOOK(DrawInfoMessages, pos, mySize);
+ bool mutator_returnvalue = MUTATOR_CALLHOOK(DrawInfoMessages, pos, mySize, img_curr_group);
+ pos = M_ARGV(0, vector);
+ img_curr_group = M_ARGV(2, int);
- if(!warmup_stage && ISGAMETYPE(LMS))
+ if(!mutator_returnvalue)
{
- entity sk;
- sk = playerslots[player_localnum];
- if(sk.(scores(ps_primary)) >= 666)
- s = _("^1Match has already begun");
- else if(sk.(scores(ps_primary)) > 0)
- s = _("^1You have no more lives left");
- else
- s = sprintf(_("^1Press ^3%s^1 to join"), getcommandkey(_("jump"), "+jump"));
- }
- else
s = sprintf(_("^1Press ^3%s^1 to join"), getcommandkey(_("jump"), "+jump"));
- InfoMessage(s);
+ InfoMessage(s);
+ }
}
if (time < STAT(GAMESTARTTIME))
#include <common/ent_cs.qh>
#include <common/scores.qh>
#include <common/gamemodes/_mod.qh>
+#include <common/gamemodes/gamemode/ctf/cl_ctf.qh>
// Mod icons (#10)
void HUD_ModIcons_Export(int fh)
{
// allow saving cvars that aesthetically change the panel into hud skin files
- HUD_Write_Cvar("hud_panel_modicons_ca_layout");
- HUD_Write_Cvar("hud_panel_modicons_dom_layout");
- HUD_Write_Cvar("hud_panel_modicons_freezetag_layout");
-}
-
-void DrawCAItem(vector myPos, vector mySize, float aspect_ratio, int layout, int i)
-{
- TC(int, layout); TC(int, i);
- int stat = -1;
- string pic = "";
- vector color = '0 0 0';
- switch(i)
- {
- case 0: stat = STAT(REDALIVE); pic = "player_red"; color = '1 0 0'; break;
- case 1: stat = STAT(BLUEALIVE); pic = "player_blue"; color = '0 0 1'; break;
- case 2: stat = STAT(YELLOWALIVE); pic = "player_yellow"; color = '1 1 0'; break;
- default:
- case 3: stat = STAT(PINKALIVE); pic = "player_pink"; color = '1 0 1'; break;
- }
-
- if(mySize.x/mySize.y > aspect_ratio)
- {
- i = aspect_ratio * mySize.y;
- myPos.x = myPos.x + (mySize.x - i) / 2;
- mySize.x = i;
- }
- else
- {
- i = 1/aspect_ratio * mySize.x;
- myPos.y = myPos.y + (mySize.y - i) / 2;
- mySize.y = i;
- }
-
- if(layout)
- {
- drawpic_aspect_skin(myPos, pic, vec2(0.5 * mySize.x, mySize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(myPos + eX * 0.5 * mySize.x, ftos(stat), vec2(0.5 * mySize.x, mySize.y), color, panel_fg_alpha, DRAWFLAG_NORMAL);
- }
- else
- drawstring_aspect(myPos, ftos(stat), mySize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
-}
-
-// Clan Arena and Freeze Tag HUD modicons
-void HUD_Mod_CA(vector myPos, vector mySize)
-{
- mod_active = 1; // required in each mod function that always shows something
-
- int layout;
- if(ISGAMETYPE(CA))
- layout = autocvar_hud_panel_modicons_ca_layout;
- else //if(ISGAMETYPE(FREEZETAG))
- layout = autocvar_hud_panel_modicons_freezetag_layout;
- int rows, columns;
- float aspect_ratio;
- aspect_ratio = (layout) ? 2 : 1;
- rows = HUD_GetRowCount(team_count, mySize, aspect_ratio);
- columns = ceil(team_count/rows);
-
- int i;
- float row = 0, column = 0;
- vector pos = '0 0 0', itemSize;
- itemSize = vec2(mySize.x / columns, mySize.y / rows);
- for(i=0; i<team_count; ++i)
- {
- pos.x = myPos.x + column * itemSize.x;
- pos.y = myPos.y + row * itemSize.y;
-
- DrawCAItem(pos, itemSize, aspect_ratio, layout, i);
-
- ++row;
- if(row >= rows)
- {
- row = 0;
- ++column;
- }
- }
-}
-
-// Race/CTS HUD mod icons
-float crecordtime_prev; // last remembered crecordtime
-float crecordtime_change_time; // time when crecordtime last changed
-float srecordtime_prev; // last remembered srecordtime
-float srecordtime_change_time; // time when srecordtime last changed
-
-float race_status_time;
-int race_status_prev;
-string race_status_name_prev;
-
-// Check if the given name already exist in race rankings? In that case, where? (otherwise return 0)
-int race_CheckName(string net_name)
-{
- int rank = 0;
- string zoned_name = strzone(strdecolorize(entcs_GetName(player_localnum)));
- for (int i = RANKINGS_CNT - 1; i >= 0; --i)
- if (strdecolorize(grecordholder[i]) == zoned_name)
- {
- rank = i + 1;
- break;
- }
- strfree(zoned_name);
- return rank;
-}
-void race_showTime(string text, vector pos, vector timeText_ofs, float theTime, vector textSize, float f)
-{
- drawstring_aspect(pos, text, textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(pos + timeText_ofs, TIME_ENCODED_TOSTRING(theTime), textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- if (f < 1) {
- drawstring_aspect_expanding(pos, text, textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
- drawstring_aspect_expanding(pos + timeText_ofs, TIME_ENCODED_TOSTRING(theTime), textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
- }
-}
-
-void HUD_Mod_Race(vector pos, vector mySize)
-{
- entity me = playerslots[player_localnum];
- float score = me.(scores(ps_primary));
-
- if(!(scores_flags(ps_primary) & SFL_TIME) || teamplay) // race/cts record display on HUD
- {
- mod_active = 0; // hide it in this case!
- return; // no records in the actual race
- }
-
- mod_active = 1;
-
- // clientside personal record
- string rr;
- if(ISGAMETYPE(CTS))
- rr = CTS_RECORD;
- else
- rr = RACE_RECORD;
- float t = stof(db_get(ClientProgsDB, strcat(shortmapname, rr, "time")));
-
- if(score && (score < t || !t)) {
- db_put(ClientProgsDB, strcat(shortmapname, rr, "time"), ftos(score));
- if(autocvar_cl_autodemo_delete_keeprecords)
- {
- float f = autocvar_cl_autodemo_delete;
- f &= ~1;
- cvar_set("cl_autodemo_delete", ftos(f)); // don't delete demo with new record!
- }
- }
-
- if(t != crecordtime_prev) {
- crecordtime_prev = t;
- crecordtime_change_time = time;
- }
-
- vector textPos, medalPos;
- float squareSize;
- if(mySize.x > mySize.y) {
- // text on left side
- squareSize = min(mySize.y, mySize.x/2);
- vector ofs = vec2(0.5 * max(0, mySize.x/2 - squareSize), 0.5 * (mySize.y - squareSize));
- textPos = pos + ofs;
- ofs.x += 0.5 * mySize.x;
- medalPos = pos + ofs;
- } else {
- // text on top
- squareSize = min(mySize.x, mySize.y/2);
- vector ofs = vec2(0.5 * (mySize.x - squareSize), 0.5 * max(0, mySize.y/2 - squareSize));
- textPos = pos + ofs;
- ofs.y += 0.5 * mySize.y;
- medalPos = pos + ofs;
- }
- vector textSize = vec2(squareSize, 0.25 * squareSize);
-
- race_showTime(_("Personal best"), textPos, eY * 0.25 * squareSize, t, textSize, time - crecordtime_change_time);
-
- // server record
- t = race_server_record;
- if(t != srecordtime_prev) {
- srecordtime_prev = t;
- srecordtime_change_time = time;
- }
-
- textPos += eY * 0.5 * squareSize;
- race_showTime(_("Server best"), textPos, eY * 0.25 * squareSize, t, textSize, time - srecordtime_change_time);
-
- if (race_status != race_status_prev || race_status_name != race_status_name_prev) {
- race_status_time = time + 5;
- race_status_prev = race_status;
- strcpy(race_status_name_prev, race_status_name);
- }
-
- // race "awards"
- float a = bound(0, race_status_time - time, 1);
- string s = textShortenToWidth(ColorTranslateRGB(race_status_name), squareSize, '1 1 0' * 0.1 * squareSize, stringwidth_colors);
-
- float rank = 0;
- if(race_status > 0)
- rank = race_CheckName(race_status_name);
- string rankname = count_ordinal(rank);
- vector namepos = medalPos + '0 0.8 0' * squareSize;
- vector rankpos = medalPos + '0 0.15 0' * squareSize;
-
- if(race_status == 0)
- drawpic_aspect_skin(medalPos, "race_newfail", '1 1 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- else if(race_status == 1) {
- drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newtime", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- } else if(race_status == 2) {
- if(strdecolorize(race_status_name) == strdecolorize(entcs_GetName(player_localnum)) || !race_myrank || race_myrank < rank)
- drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrankgreen", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- else
- drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrankyellow", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- } else if(race_status == 3) {
- drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrecordserver", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- }
-
- if (race_status_time - time <= 0) {
- race_status_prev = -1;
- race_status = -1;
- strfree(race_status_name);
- strfree(race_status_name_prev);
- }
+ FOREACH(Gametypes, it.m_modicons_export, it.m_modicons_export(fh));
}
void HUD_ModIcons_SetFunc()
#include <client/defs.qh>
#include <client/miscfunctions.qh>
#include <client/main.qh>
+#include <common/gamemodes/_mod.qh>
#include <common/mapinfo.qh>
#include <lib/csqcmodel/cl_player.qh>
{
if(!autocvar_hud_panel_physics) return;
if(spectatee_status == -1 && (autocvar_hud_panel_physics == 1 || autocvar_hud_panel_physics == 3)) return;
- if(autocvar_hud_panel_physics == 3 && !(ISGAMETYPE(RACE) || ISGAMETYPE(CTS))) return;
+ if(autocvar_hud_panel_physics == 3 && !MUTATOR_CALLHOOK(HUD_Physics_showoptional)) return;
}
HUD_Panel_LoadCvars();
#include <client/autocvars.qh>
#include <client/defs.qh>
#include <client/miscfunctions.qh>
+#include <common/gamemodes/_mod.qh>
#include <common/mapinfo.qh>
// Race timer (#8)
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_racetimer) return;
- if(!(ISGAMETYPE(RACE) || ISGAMETYPE(CTS))) return;
+ if(!MUTATOR_CALLHOOK(ShowRaceTimer)) return;
if(spectatee_status == -1) return;
}
#include <client/defs.qh>
#include <client/miscfunctions.qh>
#include <common/ent_cs.qh>
-#include <common/mapinfo.qh>
+#include <common/gamemodes/_mod.qh>
#include <client/mapvoting.qh>
#include <client/resources.qh>
#include <client/teamradar.qh>
IL_EACH(g_radarlinks, true, draw_teamradar_link(it.origin, it.velocity, it.team));
+ bool mutator_returnvalue = MUTATOR_CALLHOOK(TeamRadar_Draw); // TODO: allow players to show on the radar as well!
+
IL_EACH(g_radaricons, it.teamradar_icon, {
if ( hud_panel_radar_mouse )
if ( GetResource(it, RES_HEALTH) >= 0 )
- if ( it.team == myteam + 1 || ISGAMETYPE(RACE) || !teamplay )
+ if ( it.team == myteam + 1 || mutator_returnvalue || !teamplay )
{
vector coord = teamradar_texcoord_to_2dcoord(teamradar_3dcoord_to_texcoord(it.origin));
if(vdist((mousepos - coord), <, 8))
#include <client/miscfunctions.qh>
#include "scoreboard.qh"
#include <common/ent_cs.qh>
+#include <common/gamemodes/_mod.qh>
#include <common/mapinfo.qh>
#include <common/scores.qh>
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_score) return;
- if(spectatee_status == -1 && (ISGAMETYPE(RACE) || ISGAMETYPE(CTS))) return;
+ if(MUTATOR_CALLHOOK(HUD_Score_show)) return;
}
HUD_Panel_LoadCvars();
#include "quickmenu.qh"
#include <common/ent_cs.qh>
#include <common/constants.qh>
+#include <common/gamemodes/_mod.qh>
#include <common/net_linked.qh>
#include <common/mapinfo.qh>
#include <common/minigames/cl_minigames.qh>
float autocvar_hud_panel_scoreboard_accuracy_showdelay = 2;
float autocvar_hud_panel_scoreboard_accuracy_showdelay_minpos = 0.75;
-bool autocvar_hud_panel_scoreboard_ctf_leaderboard = true;
-
bool autocvar_hud_panel_scoreboard_dynamichud = false;
float autocvar_hud_panel_scoreboard_maxheight = 0.6;
return true;
else if (intermission == 2)
return false;
- else if (spectatee_status != -1 && STAT(HEALTH) <= 0 && autocvar_cl_deathscoreboard && !ISGAMETYPE(CTS)
+ else if (spectatee_status != -1 && STAT(HEALTH) <= 0 && autocvar_cl_deathscoreboard && !MUTATOR_CALLHOOK(DrawDeathScoreboard)
&& (!HUD_MinigameMenu_IsOpened() || !active_minigame))
{
return true;
}
-vector Scoreboard_Rankings_Draw(vector pos, entity pl, vector rgb, vector bg_size)
+vector Scoreboard_Rankings_Draw(vector pos, string ranktitle, entity pl, vector rgb, vector bg_size)
{
int i;
RANKINGS_RECEIVED_CNT = 0;
vector hl_rgb = rgb + '0.5 0.5 0.5';
pos.y += hud_fontsize.y;
- drawstring(pos + eX * panel_bg_padding, ((ISGAMETYPE(CTF)) ? _("Capture time rankings") : _("Rankings")), hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring(pos + eX * panel_bg_padding, ranktitle, hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
pos.y += 1.25 * hud_fontsize.y;
if(panel.current_panel_bg != "0")
pos.y += panel_bg_border;
bool have_weapon_stats;
bool Scoreboard_AccuracyStats_WouldDraw(float ypos)
{
- if (ISGAMETYPE(CTS) || ISGAMETYPE(RACE) || ISGAMETYPE(NEXBALL))
+ if (MUTATOR_CALLHOOK(DrawScoreboardAccuracy))
return false;
if (!autocvar_hud_panel_scoreboard_accuracy || warmup_stage || ypos > 0.91 * vid_conheight)
return false;
str = "";
if(tl > 0)
str = strcat(str, sprintf(_("^3%1.0f minutes"), tl));
- if(!ISGAMETYPE(LMS))
+ if(!gametype.m_hidelimits)
{
if(fl > 0)
{
if (Scoreboard_AccuracyStats_WouldDraw(pos.y))
pos = Scoreboard_AccuracyStats_Draw(pos, panel_bg_color, bg_size);
- if(ISGAMETYPE(CTS) || ISGAMETYPE(RACE) || (autocvar_hud_panel_scoreboard_ctf_leaderboard && ISGAMETYPE(CTF) && STAT(CTF_SHOWLEADERBOARD))) {
+ if(MUTATOR_CALLHOOK(ShowRankings)) {
+ string ranktitle = M_ARGV(0, string);
if(race_speedaward) {
drawcolorcodedstring(pos, sprintf(_("Speed award: %d%s ^7(%s^7)"), race_speedaward, race_speedaward_unit, ColorTranslateRGB(race_speedaward_holder)), hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
pos.y += 1.25 * hud_fontsize.y;
drawcolorcodedstring(pos, sprintf(_("All-time fastest: %d%s ^7(%s^7)"), race_speedaward_alltimebest, race_speedaward_alltimebest_unit, ColorTranslateRGB(race_speedaward_alltimebest_holder)), hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
pos.y += 1.25 * hud_fontsize.y;
}
- pos = Scoreboard_Rankings_Draw(pos, playerslots[player_localnum], panel_bg_color, bg_size);
+ pos = Scoreboard_Rankings_Draw(pos, ranktitle, playerslots[player_localnum], panel_bg_color, bg_size);
}
pos = Scoreboard_MapStats_Draw(pos, panel_bg_color, bg_size);
#include <client/autocvars.qh>
#include <client/defs.qh>
+#include <common/gamemodes/_mod.qh>
#include <client/miscfunctions.qh>
#include <common/mapinfo.qh>
void HUD_Vote()
{
- if(autocvar_cl_allow_uid2name == -1 && (ISGAMETYPE(CTS) || ISGAMETYPE(RACE) || (serverflags & SERVERFLAG_PLAYERSTATS)))
+ if(autocvar_cl_allow_uid2name == -1 && (MUTATOR_CALLHOOK(ShowRankings) || (serverflags & SERVERFLAG_PLAYERSTATS)))
{
// this dialog gets overriden by the uid2name menu dialog, if it exists
// TODO remove this client side uid2name dialog in the next release
MUTATOR_HOOKABLE(HUD_Powerups_add, EV_NO_ARGS);
+/** return true to show the physics HUD panel when optional mode is enabled */
+MUTATOR_HOOKABLE(HUD_Physics_showoptional, EV_NO_ARGS);
+
+/** return true to hide the score HUD panel */
+MUTATOR_HOOKABLE(HUD_Score_show, EV_NO_ARGS);
+
/** Return true to not draw any vortex beam */
#define EV_Particles_VortexBeam(i, o) \
/** beam shot origin */ i(vector, MUTATOR_ARGV_0_vector) \
/** Return true to not draw scoreboard */
MUTATOR_HOOKABLE(DrawScoreboard, EV_NO_ARGS);
-/** Called when drawing info messages, allows adding new info messages */
+/** Return true to not draw scoreboard while dead */
+MUTATOR_HOOKABLE(DrawDeathScoreboard, EV_NO_ARGS);
+
+/** Return true to not show accuracy stats in the scoreboard */
+MUTATOR_HOOKABLE(DrawScoreboardAccuracy, EV_NO_ARGS);
+
+/** Called when drawing info messages, allows adding new info messages. Return true to hide the standard join message */
#define EV_DrawInfoMessages(i, o) \
/** pos */ i(vector, MUTATOR_ARGV_0_vector) \
+ /***/ o(vector, MUTATOR_ARGV_0_vector) \
/** mySize */ i(vector, MUTATOR_ARGV_1_vector) \
+ /** img_curr_group */ i(int, MUTATOR_ARGV_2_int) \
+ /***/ o(int, MUTATOR_ARGV_2_int) \
/**/
MUTATOR_HOOKABLE(DrawInfoMessages, EV_DrawInfoMessages);
/** Return true to not draw zoom reticle */
MUTATOR_HOOKABLE(DrawReticle, EV_NO_ARGS);
+
+/** Return true to show leaderboard rankings, needs title argument set */
+#define EV_ShowRankings(i, o) \
+ /** rankings title */ o(string, MUTATOR_ARGV_0_string) \
+ /**/
+MUTATOR_HOOKABLE(ShowRankings, EV_ShowRankings);
+
+/** Called when drawing a player's nameplate, return true to hide it */
+#define EV_ShowNames_Draw(i, o) \
+ /** entity id */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** alpha */ i(float, MUTATOR_ARGV_1_float) \
+ /***/ o(float, MUTATOR_ARGV_1_float) \
+ /**/
+MUTATOR_HOOKABLE(ShowNames_Draw, EV_ShowNames_Draw);
+
+/** Return true to display the race timer HUD panel */
+MUTATOR_HOOKABLE(ShowRaceTimer, EV_NO_ARGS);
+
+/** Return true to force team radar to display entities regardless of their team */
+MUTATOR_HOOKABLE(TeamRadar_Draw, EV_NO_ARGS);
#include <common/ent_cs.qh>
#include <common/constants.qh>
+#include <common/gamemodes/_mod.qh>
#include <common/net_linked.qh>
#include <common/mapinfo.qh>
#include <common/teams.qh>
if (f < 0) f = 0;
a *= f;
}
- if (a < ALPHA_MIN_VISIBLE && ISGAMETYPE(CTS)) return;
+ if (MUTATOR_CALLHOOK(ShowNames_Draw, this, a)) return;
+ a = M_ARGV(1, float);
if (vdist(this.origin - view_origin, >=, max_shot_distance)) return;
float dist = vlen(this.origin - view_origin);
if (autocvar_hud_shownames_maxdistance)
if(autocvar_r_letterbox == 0)
if(autocvar_viewsize < 120)
{
- if(!(ISGAMETYPE(RACE) || ISGAMETYPE(CTS)))
+ if(!MUTATOR_CALLHOOK(DrawScoreboardAccuracy))
Accuracy_LoadLevels();
HUD_Main();
// generated file; do not modify
+#include <common/gamemodes/gamemode/assault/assault.qc>
#ifdef SVQC
#include <common/gamemodes/gamemode/assault/sv_assault.qc>
#endif
// generated file; do not modify
+#include <common/gamemodes/gamemode/assault/assault.qh>
#ifdef SVQC
#include <common/gamemodes/gamemode/assault/sv_assault.qh>
#endif
--- /dev/null
+#include "assault.qh"
--- /dev/null
+#pragma once
+
+#include <common/mapinfo.qh>
+
+CLASS(Assault, Gametype)
+ INIT(Assault)
+ {
+ this.gametype_init(this, _("Assault"),"as","g_assault",GAMETYPE_FLAG_TEAMPLAY,"","timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out"));
+ }
+ METHOD(Assault, m_generate_mapinfo, void(Gametype this, string v))
+ {
+ if(v == "target_assault_roundend")
+ MapInfo_Map_supportedGametypes |= this.m_flags;
+ }
+ METHOD(Assault, m_isTwoBaseMode, bool())
+ {
+ return true;
+ }
+ METHOD(Assault, 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, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
+ }
+ ATTRIB(Assault, m_legacydefaults, string, "20 0");
+ENDCLASS(Assault)
+REGISTER_GAMETYPE(ASSAULT, NEW(Assault));
+#define g_assault IS_GAMETYPE(ASSAULT)
// generated file; do not modify
+#include <common/gamemodes/gamemode/clanarena/clanarena.qc>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/clanarena/cl_clanarena.qc>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/clanarena/sv_clanarena.qc>
#endif
// generated file; do not modify
+#include <common/gamemodes/gamemode/clanarena/clanarena.qh>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/clanarena/cl_clanarena.qh>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/clanarena/sv_clanarena.qh>
#endif
--- /dev/null
+#include "cl_clanarena.qh"
+
+void HUD_Mod_CA_Export(int fh)
+{
+ HUD_Write_Cvar("hud_panel_modicons_ca_layout");
+}
+
+void DrawCAItem(vector myPos, vector mySize, float aspect_ratio, int layout, int i)
+{
+ TC(int, layout); TC(int, i);
+ int stat = -1;
+ string pic = "";
+ vector color = '0 0 0';
+ switch(i)
+ {
+ case 0: stat = STAT(REDALIVE); pic = "player_red"; color = '1 0 0'; break;
+ case 1: stat = STAT(BLUEALIVE); pic = "player_blue"; color = '0 0 1'; break;
+ case 2: stat = STAT(YELLOWALIVE); pic = "player_yellow"; color = '1 1 0'; break;
+ default:
+ case 3: stat = STAT(PINKALIVE); pic = "player_pink"; color = '1 0 1'; break;
+ }
+
+ if(mySize.x/mySize.y > aspect_ratio)
+ {
+ i = aspect_ratio * mySize.y;
+ myPos.x = myPos.x + (mySize.x - i) / 2;
+ mySize.x = i;
+ }
+ else
+ {
+ i = 1/aspect_ratio * mySize.x;
+ myPos.y = myPos.y + (mySize.y - i) / 2;
+ mySize.y = i;
+ }
+
+ if(layout)
+ {
+ drawpic_aspect_skin(myPos, pic, vec2(0.5 * mySize.x, mySize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(myPos + eX * 0.5 * mySize.x, ftos(stat), vec2(0.5 * mySize.x, mySize.y), color, panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
+ else
+ drawstring_aspect(myPos, ftos(stat), mySize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
+}
+
+void HUD_Mod_CA_Draw(vector myPos, vector mySize, int layout)
+{
+ int rows, columns;
+ float aspect_ratio;
+ aspect_ratio = (layout) ? 2 : 1;
+ rows = HUD_GetRowCount(team_count, mySize, aspect_ratio);
+ columns = ceil(team_count/rows);
+
+ int i;
+ float row = 0, column = 0;
+ vector pos = '0 0 0', itemSize;
+ itemSize = vec2(mySize.x / columns, mySize.y / rows);
+ for(i=0; i<team_count; ++i)
+ {
+ pos.x = myPos.x + column * itemSize.x;
+ pos.y = myPos.y + row * itemSize.y;
+
+ DrawCAItem(pos, itemSize, aspect_ratio, layout, i);
+
+ ++row;
+ if(row >= rows)
+ {
+ row = 0;
+ ++column;
+ }
+ }
+}
+
+// Clan Arena and Freeze Tag HUD modicons
+void HUD_Mod_CA(vector myPos, vector mySize)
+{
+ mod_active = 1; // required in each mod function that always shows something
+
+ HUD_Mod_CA_Draw(myPos, mySize, autocvar_hud_panel_modicons_ca_layout);
+}
--- /dev/null
+#pragma once
+
+void HUD_Mod_CA(vector myPos, vector mySize);
+void HUD_Mod_CA_Draw(vector myPos, vector mySize, int layout);
+void HUD_Mod_CA_Export(int fh);
--- /dev/null
+#include "clanarena.qh"
--- /dev/null
+#pragma once
+
+#include <common/mapinfo.qh>
+
+#ifdef CSQC
+void HUD_Mod_CA(vector pos, vector mySize);
+void HUD_Mod_CA_Export(int fh);
+#endif
+CLASS(ClanArena, Gametype)
+ INIT(ClanArena)
+ {
+ this.gametype_init(this, _("Clan Arena"),"ca","g_ca",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=10 teams=2 leadlimit=6",_("Kill all enemy teammates to win the round"));
+ }
+ METHOD(ClanArena, m_parse_mapinfo, bool(string k, string v))
+ {
+ if (!k) {
+ cvar_set("g_ca_teams", cvar_defstring("g_ca_teams"));
+ return true;
+ }
+ switch (k) {
+ case "teams":
+ cvar_set("g_ca_teams", v);
+ return true;
+ }
+ return false;
+ }
+ METHOD(ClanArena, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
+ {
+ if(spawnpoints >= 8 && diameter > 4096)
+ return true;
+ return false;
+ }
+ METHOD(ClanArena, m_setTeams, void(string sa))
+ {
+ cvar_set("g_ca_teams", sa);
+ }
+ METHOD(ClanArena, 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", "g_ca_teams_override", _("The amount of frags needed before the match will end"));
+ }
+#ifdef CSQC
+ ATTRIB(ClanArena, m_modicons, void(vector pos, vector mySize), HUD_Mod_CA);
+ ATTRIB(ClanArena, m_modicons_export, void(int fh), HUD_Mod_CA_Export);
+#endif
+ ATTRIB(ClanArena, m_legacydefaults, string, "10 20 0");
+ENDCLASS(ClanArena)
+REGISTER_GAMETYPE(CA, NEW(ClanArena));
+#define g_ca IS_GAMETYPE(CA)
X(neutral);
#undef X
}
+
+bool autocvar_hud_panel_scoreboard_ctf_leaderboard = true;
+
+REGISTER_MUTATOR(cl_ctf, true);
+
+MUTATOR_HOOKFUNCTION(cl_ctf, ShowRankings)
+{
+ if(autocvar_hud_panel_scoreboard_ctf_leaderboard && ISGAMETYPE(CTF) && STAT(CTF_SHOWLEADERBOARD))
+ {
+ M_ARGV(0, string) = _("Capture time rankings");
+ return true;
+ }
+}
#pragma once
+#include <common/mapinfo.qh>
+
+#ifdef CSQC
+void HUD_Mod_CTF(vector pos, vector mySize);
+void HUD_Mod_CTF_Reset();
+#endif
+CLASS(CaptureTheFlag, Gametype)
+ INIT(CaptureTheFlag)
+ {
+ this.gametype_init(this, _("Capture the Flag"),"ctf","g_ctf",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_PRIORITY,"","timelimit=20 caplimit=10 leadlimit=6",_("Find and bring the enemy flag to your base to capture it, defend your base from the other team"));
+ }
+ METHOD(CaptureTheFlag, m_generate_mapinfo, void(Gametype this, string v))
+ {
+ if(v == "item_flag_team2" || v == "team_CTF_blueflag")
+ MapInfo_Map_supportedGametypes |= this.m_flags;
+ }
+ METHOD(CaptureTheFlag, m_isTwoBaseMode, bool())
+ {
+ return true;
+ }
+ METHOD(CaptureTheFlag, m_setTeams, void(string sa))
+ {
+ cvar_set("fraglimit", sa);
+ }
+ METHOD(CaptureTheFlag, 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, _("Capture limit:"), 1, 20, 1, "capturelimit_override", string_null, _("The amount of captures needed before the match will end"));
+ }
+#ifdef CSQC
+ ATTRIB(CaptureTheFlag, m_modicons, void(vector pos, vector mySize), HUD_Mod_CTF);
+ ATTRIB(CaptureTheFlag, m_modicons_reset, void(), HUD_Mod_CTF_Reset);
+#endif
+ ATTRIB(CaptureTheFlag, m_legacydefaults, string, "300 20 10 0");
+ENDCLASS(CaptureTheFlag)
+REGISTER_GAMETYPE(CTF, NEW(CaptureTheFlag));
+#define g_ctf IS_GAMETYPE(CTF)
+
+#ifdef GAMEQC
const int CTF_RED_FLAG_TAKEN = 1;
const int CTF_RED_FLAG_LOST = 2;
const int CTF_RED_FLAG_CARRYING = 3;
const int CTF_FLAG_NEUTRAL = 2048;
const int CTF_SHIELDED = 4096;
const int CTF_STALEMATE = 8192;
+#endif
// generated file; do not modify
+#include <common/gamemodes/gamemode/cts/cts.qc>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/cts/cl_cts.qc>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/cts/sv_cts.qc>
#endif
// generated file; do not modify
+#include <common/gamemodes/gamemode/cts/cts.qh>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/cts/cl_cts.qh>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/cts/sv_cts.qh>
#endif
--- /dev/null
+#include "cl_cts.qh"
+
+REGISTER_MUTATOR(cl_cts, true);
+
+MUTATOR_HOOKFUNCTION(cl_cts, HUD_Physics_showoptional)
+{
+ return ISGAMETYPE(CTS); // show the optional physics panel
+}
+
+MUTATOR_HOOKFUNCTION(cl_cts, HUD_Score_show)
+{
+ return spectatee_status == -1 && ISGAMETYPE(CTS); // hide the score panel while observing
+}
+
+MUTATOR_HOOKFUNCTION(cl_cts, DrawDeathScoreboard)
+{
+ return ISGAMETYPE(CTS); // no scoreboard shown while dead
+}
+
+MUTATOR_HOOKFUNCTION(cl_cts, DrawScoreboardAccuracy)
+{
+ return ISGAMETYPE(CTS); // accuracy is not a factor in this gamemode
+}
+
+MUTATOR_HOOKFUNCTION(cl_cts, ShowRankings)
+{
+ if(ISGAMETYPE(CTS))
+ {
+ M_ARGV(0, string) = _("Rankings");
+ return true;
+ }
+}
+
+MUTATOR_HOOKFUNCTION(cl_cts, ShowNames_Draw)
+{
+ return (ISGAMETYPE(CTS) && M_ARGV(1, float) < ALPHA_MIN_VISIBLE);
+}
+
+MUTATOR_HOOKFUNCTION(cl_cts, ShowRaceTimer)
+{
+ return ISGAMETYPE(CTS); // show the race timer panel
+}
--- /dev/null
+#pragma once
--- /dev/null
+#include "cts.qh"
--- /dev/null
+#pragma once
+
+#include <common/mapinfo.qh>
+#if defined(CSQC)
+ #include <common/gamemodes/gamemode/race/cl_race.qh>
+#endif
+
+CLASS(RaceCTS, Gametype)
+ INIT(RaceCTS)
+ {
+ this.gametype_init(this, _("Race CTS"),"cts","g_cts",0,"cloaked","timelimit=20",_("Race for fastest time."));
+ }
+ METHOD(RaceCTS, m_generate_mapinfo, void(Gametype this, string v))
+ {
+ if(v == "target_startTimer")
+ MapInfo_Map_supportedGametypes |= this.m_flags;
+ }
+ METHOD(RaceCTS, m_setTeams, void(string sa))
+ {
+ // this is the skill of the map
+ // not parsed by anything yet
+ // for map databases
+ // cvar_set("fraglimit", sa);
+ }
+ METHOD(RaceCTS, 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, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
+ }
+#ifdef CSQC
+ ATTRIB(RaceCTS, m_modicons, void(vector pos, vector mySize), HUD_Mod_Race);
+#endif
+ ATTRIB(RaceCTS, m_legacydefaults, string, "20 0 0");
+ENDCLASS(RaceCTS)
+REGISTER_GAMETYPE(CTS, NEW(RaceCTS));
+#define g_cts IS_GAMETYPE(CTS)
// generated file; do not modify
+#include <common/gamemodes/gamemode/deathmatch/deathmatch.qc>
#ifdef SVQC
#include <common/gamemodes/gamemode/deathmatch/sv_deathmatch.qc>
#endif
// generated file; do not modify
+#include <common/gamemodes/gamemode/deathmatch/deathmatch.qh>
#ifdef SVQC
#include <common/gamemodes/gamemode/deathmatch/sv_deathmatch.qh>
#endif
--- /dev/null
+#include "deathmatch.qh"
--- /dev/null
+#pragma once
+
+#include <common/mapinfo.qh>
+
+CLASS(Deathmatch, Gametype)
+ INIT(Deathmatch)
+ {
+ this.gametype_init(this, _("Deathmatch"),"dm","g_dm",GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_PREFERRED,"","timelimit=15 pointlimit=30 leadlimit=0",_("Score as many frags as you can"));
+ }
+ METHOD(Deathmatch, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
+ {
+ return true;
+ }
+ ATTRIB(Deathmatch, m_legacydefaults, string, "30 20 0");
+ENDCLASS(Deathmatch)
+REGISTER_GAMETYPE(DEATHMATCH, NEW(Deathmatch));
#include <client/hud/panel/modicons.qh>
+void HUD_Mod_Dom_Export(int fh)
+{
+ HUD_Write_Cvar("hud_panel_modicons_dom_layout");
+}
+
int autocvar_hud_panel_modicons_dom_layout;
void DrawDomItem(vector myPos, vector mySize, float aspect_ratio, int layout, int i)
#pragma once
void HUD_Mod_Dom(vector myPos, vector mySize);
+void HUD_Mod_Dom_Export(int fh);
#pragma once
+
+#include <common/mapinfo.qh>
+
+#ifdef CSQC
+void HUD_Mod_Dom(vector pos, vector mySize);
+void HUD_Mod_Dom_Export(int fh);
+#endif
+CLASS(Domination, Gametype)
+ INIT(Domination)
+ {
+ this.gametype_init(this, _("Domination"),"dom","g_domination",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture and defend all the control points to win"));
+ }
+ METHOD(Domination, m_parse_mapinfo, bool(string k, string v))
+ {
+ if (!k) {
+ cvar_set("g_domination_default_teams", cvar_defstring("g_domination_default_teams"));
+ return true;
+ }
+ switch (k) {
+ case "teams":
+ cvar_set("g_domination_default_teams", v);
+ return true;
+ }
+ return false;
+ }
+ METHOD(Domination, m_generate_mapinfo, void(Gametype this, string v))
+ {
+ if(v == "dom_controlpoint")
+ MapInfo_Map_supportedGametypes |= this.m_flags;
+ }
+ METHOD(Domination, 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, _("Point limit:"), 50, 500, 10, "g_domination_point_limit", "g_domination_teams_override", _("The amount of points needed before the match will end"));
+ }
+#ifdef CSQC
+ ATTRIB(Domination, m_modicons, void(vector pos, vector mySize), HUD_Mod_Dom);
+ ATTRIB(Domination, m_modicons_export, void(int fh), HUD_Mod_Dom_Export);
+#endif
+ ATTRIB(Domination, m_legacydefaults, string, "200 20 0");
+ENDCLASS(Domination)
+REGISTER_GAMETYPE(DOMINATION, NEW(Domination));
// generated file; do not modify
+#include <common/gamemodes/gamemode/duel/duel.qc>
#ifdef SVQC
#include <common/gamemodes/gamemode/duel/sv_duel.qc>
#endif
// generated file; do not modify
+#include <common/gamemodes/gamemode/duel/duel.qh>
#ifdef SVQC
#include <common/gamemodes/gamemode/duel/sv_duel.qh>
#endif
--- /dev/null
+#include "duel.qh"
--- /dev/null
+#pragma once
+
+#include <common/gamemodes/gamemode/deathmatch/deathmatch.qh>
+#include <common/mapinfo.qh>
+
+CLASS(Duel, Gametype)
+ INIT(Duel)
+ {
+ this.gametype_init(this, _("Duel"),"duel","g_duel",GAMETYPE_FLAG_USEPOINTS,"","timelimit=10 pointlimit=0 leadlimit=0",_("Fight in a one versus one arena battle to decide the winner"));
+ }
+ METHOD(Duel, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
+ {
+ return (diameter < 16384);
+ }
+ METHOD(Duel, m_isForcedSupported, bool(Gametype this))
+ {
+ if(!cvar("g_duel_not_dm_maps"))
+ {
+ // if this is set, all DM maps support duel too
+ // TODO: we should really check the size of maps, some DM maps do not work for duel!
+ if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags))
+ return true; // TODO: references another gametype (alternatively, we could check which gamemodes are always enabled and append this if any are supported)
+ }
+ return false;
+ }
+ENDCLASS(Duel)
+REGISTER_GAMETYPE(DUEL, NEW(Duel));
+#define g_duel IS_GAMETYPE(DUEL)
// generated file; do not modify
+#include <common/gamemodes/gamemode/freezetag/freezetag.qc>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/freezetag/cl_freezetag.qc>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/freezetag/sv_freezetag.qc>
#endif
// generated file; do not modify
+#include <common/gamemodes/gamemode/freezetag/freezetag.qh>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/freezetag/cl_freezetag.qh>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/freezetag/sv_freezetag.qh>
#endif
--- /dev/null
+#include "cl_freezetag.qh"
+
+#include <common/gamemodes/gamemode/clanarena/cl_clanarena.qh>
+
+void HUD_Mod_FreezeTag_Export(int fh)
+{
+ HUD_Write_Cvar("hud_panel_modicons_freezetag_layout");
+}
+
+void HUD_Mod_FreezeTag(vector myPos, vector mySize)
+{
+ mod_active = 1; // required in each mod function that always shows something
+
+ HUD_Mod_CA_Draw(myPos, mySize, autocvar_hud_panel_modicons_freezetag_layout);
+}
--- /dev/null
+#pragma once
+
+void HUD_Mod_FreezeTag_Export(int fh);
--- /dev/null
+#include "freezetag.qh"
--- /dev/null
+#pragma once
+
+#include <common/mapinfo.qh>
+#if defined(CSQC)
+ #include <common/gamemodes/gamemode/clanarena/cl_clanarena.qh>
+#endif
+
+#ifdef CSQC
+void HUD_Mod_FreezeTag(vector myPos, vector mySize);
+void HUD_Mod_FreezeTag_Export(int fh);
+#endif
+CLASS(FreezeTag, Gametype)
+ INIT(FreezeTag)
+ {
+ this.gametype_init(this, _("Freeze Tag"),"ft","g_freezetag",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=10 teams=2 leadlimit=6",_("Kill enemies to freeze them, stand next to frozen teammates to revive them; freeze all enemies to win"));
+ }
+ METHOD(FreezeTag, m_parse_mapinfo, bool(string k, string v))
+ {
+ if (!k) {
+ cvar_set("g_freezetag_teams", cvar_defstring("g_freezetag_teams"));
+ return true;
+ }
+ switch (k) {
+ case "teams":
+ cvar_set("g_freezetag_teams", v);
+ return true;
+ }
+ return false;
+ }
+ METHOD(FreezeTag, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
+ {
+ if(spawnpoints >= 8 && diameter > 4096)
+ return true;
+ return false;
+ }
+ METHOD(FreezeTag, m_setTeams, void(string sa))
+ {
+ cvar_set("g_freezetag_teams", sa);
+ }
+ METHOD(FreezeTag, 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", "g_freezetag_teams_override", _("The amount of frags needed before the match will end"));
+ }
+#ifdef CSQC
+ ATTRIB(FreezeTag, m_modicons, void(vector pos, vector mySize), HUD_Mod_FreezeTag);
+ ATTRIB(FreezeTag, m_modicons_export, void(int fh), HUD_Mod_FreezeTag_Export);
+#endif
+ ATTRIB(FreezeTag, m_legacydefaults, string, "10 20 0");
+ENDCLASS(FreezeTag)
+REGISTER_GAMETYPE(FREEZETAG, NEW(FreezeTag));
+#define g_freezetag IS_GAMETYPE(FREEZETAG)
// generated file; do not modify
+#include <common/gamemodes/gamemode/invasion/invasion.qc>
#ifdef SVQC
#include <common/gamemodes/gamemode/invasion/sv_invasion.qc>
#endif
// generated file; do not modify
+#include <common/gamemodes/gamemode/invasion/invasion.qh>
#ifdef SVQC
#include <common/gamemodes/gamemode/invasion/sv_invasion.qh>
#endif
--- /dev/null
+#include "invasion.qh"
--- /dev/null
+#pragma once
+
+#include <common/mapinfo.qh>
+
+CLASS(Invasion, Gametype)
+ INIT(Invasion)
+ {
+ this.gametype_init(this, _("Invasion"),"inv","g_invasion",GAMETYPE_FLAG_USEPOINTS,"","pointlimit=50 teams=0 type=0",_("Survive against waves of monsters"));
+ }
+ METHOD(Invasion, m_parse_mapinfo, bool(string k, string v))
+ {
+ switch (k) {
+ case "teams":
+ cvar_set("g_invasion_teams", v);
+ return true;
+ case "type":
+ cvar_set("g_invasion_type", v);
+ return true;
+ }
+ return false;
+ }
+ METHOD(Invasion, m_generate_mapinfo, void(Gametype this, string v))
+ {
+ if(v == "invasion_spawnpoint")
+ MapInfo_Map_supportedGametypes |= this.m_flags;
+ }
+ METHOD(Invasion, 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, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
+ }
+ENDCLASS(Invasion)
+REGISTER_GAMETYPE(INVASION, NEW(Invasion));
#pragma once
+
+#include <common/mapinfo.qh>
+
+#ifdef CSQC
+void HUD_Mod_Keepaway(vector pos, vector mySize);
+#endif
+CLASS(Keepaway, Gametype)
+ INIT(Keepaway)
+ {
+ this.gametype_init(this, _("Keepaway"),"ka","g_keepaway",GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
+ }
+ METHOD(Keepaway, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
+ {
+ return true;
+ }
+#ifdef CSQC
+ ATTRIB(Keepaway, m_modicons, void(vector pos, vector mySize), HUD_Mod_Keepaway);
+#endif
+ENDCLASS(Keepaway)
+REGISTER_GAMETYPE(KEEPAWAY, NEW(Keepaway));
#pragma once
+
+#include <common/mapinfo.qh>
+
+#ifdef CSQC
+void HUD_Mod_KH(vector pos, vector mySize);
+#endif
+CLASS(KeyHunt, Gametype)
+ INIT(KeyHunt)
+ {
+ this.gametype_init(this, _("Key Hunt"),"kh","g_keyhunt",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round"));
+ }
+ METHOD(KeyHunt, m_parse_mapinfo, bool(string k, string v))
+ {
+ if (!k) {
+ cvar_set("g_keyhunt_teams", cvar_defstring("g_keyhunt_teams"));
+ return true;
+ }
+ switch (k) {
+ case "teams":
+ cvar_set("g_keyhunt_teams", v);
+ return true;
+ }
+ return false;
+ }
+ METHOD(KeyHunt, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
+ {
+ if(spawnpoints >= 12 && diameter > 5120)
+ return true;
+ return false;
+ }
+ METHOD(KeyHunt, m_setTeams, void(string sa))
+ {
+ cvar_set("g_keyhunt_teams", sa);
+ }
+ METHOD(KeyHunt, 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, _("Point limit:"), 200, 1500, 50, "g_keyhunt_point_limit", "g_keyhunt_teams_override", _("The amount of points needed before the match will end"));
+ }
+#ifdef CSQC
+ ATTRIB(KeyHunt, m_modicons, void(vector pos, vector mySize), HUD_Mod_KH);
+#endif
+ ATTRIB(KeyHunt, m_legacydefaults, string, "1000 20 3 0");
+ENDCLASS(KeyHunt)
+REGISTER_GAMETYPE(KEYHUNT, NEW(KeyHunt));
// generated file; do not modify
+#include <common/gamemodes/gamemode/lms/lms.qc>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/lms/cl_lms.qc>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/lms/sv_lms.qc>
#endif
// generated file; do not modify
+#include <common/gamemodes/gamemode/lms/lms.qh>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/lms/cl_lms.qh>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/lms/sv_lms.qh>
#endif
--- /dev/null
+#include "cl_lms.qh"
+
+REGISTER_MUTATOR(cl_lms, true);
+
+MUTATOR_HOOKFUNCTION(cl_lms, DrawInfoMessages)
+{
+ if(!warmup_stage && ISGAMETYPE(LMS))
+ {
+ entity sk = playerslots[player_localnum];
+ vector pos = M_ARGV(0, vector);
+ vector mySize = M_ARGV(1, vector);
+ vector fontsize = '0.2 0.2 0' * mySize.y;
+ int img_curr_group = M_ARGV(2, int);
+ if(sk.(scores(ps_primary)) >= 666)
+ {
+ InfoMessage(_("^1Match has already begun"));
+ M_ARGV(0, vector) = pos;
+ M_ARGV(2, int) = img_curr_group;
+ return true;
+ }
+ else if(sk.(scores(ps_primary)) > 0)
+ {
+ InfoMessage(_("^1You have no more lives left"));
+ M_ARGV(0, vector) = pos;
+ M_ARGV(2, int) = img_curr_group;
+ return true;
+ }
+ }
+ return false;
+}
--- /dev/null
+#pragma once
--- /dev/null
+#include "lms.qh"
--- /dev/null
+#pragma once
+
+#include <common/mapinfo.qh>
+
+CLASS(LastManStanding, Gametype)
+ INIT(LastManStanding)
+ {
+ this.gametype_init(this, _("Last Man Standing"),"lms","g_lms",GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_HIDELIMITS,"","timelimit=20 lives=5 leadlimit=0",_("Survive and kill until the enemies have no lives left"));
+ }
+ METHOD(LastManStanding, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
+ {
+ return true;
+ }
+ METHOD(LastManStanding, 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, _("Lives:"), 3, 50, 1, "g_lms_lives_override", string_null, string_null);
+ }
+ ATTRIB(LastManStanding, m_legacydefaults, string, "9 20 0");
+ENDCLASS(LastManStanding)
+REGISTER_GAMETYPE(LMS, NEW(LastManStanding));
return true;
return false;
}
+
+MUTATOR_HOOKFUNCTION(cl_nb, DrawScoreboardAccuracy)
+{
+ return ISGAMETYPE(NEXBALL); // accuracy is not a factor in this gamemode
+}
#pragma once
+
+#include <common/mapinfo.qh>
+
+#ifdef CSQC
+void HUD_Mod_NexBall(vector pos, vector mySize);
+#endif
+CLASS(NexBall, Gametype)
+ INIT(NexBall)
+ {
+ this.gametype_init(this, _("Nexball"),"nb","g_nexball",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=5 leadlimit=0",_("Shoot and kick the ball into the enemies goal, keep your goal clean"));
+ }
+ METHOD(NexBall, m_generate_mapinfo, void(Gametype this, string v))
+ {
+ if(substring(v, 0, 8) == "nexball_" || substring(v, 0, 4) == "ball")
+ MapInfo_Map_supportedGametypes |= this.m_flags;
+ }
+ METHOD(NexBall, m_isTwoBaseMode, bool())
+ {
+ return true;
+ }
+ METHOD(NexBall, 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, _("Goals:"), 1, 50, 1, "g_nexball_goallimit", string_null, _("The amount of goals needed before the match will end"));
+ }
+#ifdef CSQC
+ ATTRIB(NexBall, m_modicons, void(vector pos, vector mySize), HUD_Mod_NexBall);
+#endif
+ ATTRIB(NexBall, m_legacydefaults, string, "5 20 0");
+ENDCLASS(NexBall)
+REGISTER_GAMETYPE(NEXBALL, NEW(NexBall));
+#define g_nexball IS_GAMETYPE(NEXBALL)
#pragma once
+#include <common/weapons/_all.qh>
+
CLASS(BallStealer, PortoLaunch)
/* flags */ ATTRIB(BallStealer, spawnflags, int, WEP_TYPE_OTHER | WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_NOTRUEAIM);
/* impulse */ ATTRIB(BallStealer, impulse, int, 0);
#pragma once
+#include <common/mapinfo.qh>
+
+CLASS(Onslaught, Gametype)
+ INIT(Onslaught)
+ {
+ this.gametype_init(this, _("Onslaught"),"ons","g_onslaught",GAMETYPE_FLAG_TEAMPLAY,"","pointlimit=1 timelimit=20",_("Capture control points to reach and destroy the enemy generator"));
+ }
+ METHOD(Onslaught, m_generate_mapinfo, void(Gametype this, string v))
+ {
+ if(v == "onslaught_generator")
+ MapInfo_Map_supportedGametypes |= this.m_flags;
+ }
+ METHOD(Onslaught, 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, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
+ }
+ ATTRIB(Onslaught, m_legacydefaults, string, "20 0");
+ENDCLASS(Onslaught)
+REGISTER_GAMETYPE(ONSLAUGHT, NEW(Onslaught));
+
#ifdef GAMEQC
REGISTER_NET_LINKED(ENT_CLIENT_GENERATOR)
REGISTER_NET_LINKED(ENT_CLIENT_CONTROLPOINT_ICON)
// generated file; do not modify
+#include <common/gamemodes/gamemode/race/race.qc>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/race/cl_race.qc>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/race/sv_race.qc>
#endif
// generated file; do not modify
+#include <common/gamemodes/gamemode/race/race.qh>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/race/cl_race.qh>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/race/sv_race.qh>
#endif
--- /dev/null
+#include "cl_race.qh"
+
+// Race/CTS HUD mod icons
+float crecordtime_prev; // last remembered crecordtime
+float crecordtime_change_time; // time when crecordtime last changed
+float srecordtime_prev; // last remembered srecordtime
+float srecordtime_change_time; // time when srecordtime last changed
+
+float race_status_time;
+int race_status_prev;
+string race_status_name_prev;
+
+// Check if the given name already exist in race rankings? In that case, where? (otherwise return 0)
+int race_CheckName(string net_name)
+{
+ int rank = 0;
+ string zoned_name = strzone(strdecolorize(entcs_GetName(player_localnum)));
+ for (int i = RANKINGS_CNT - 1; i >= 0; --i)
+ if (strdecolorize(grecordholder[i]) == zoned_name)
+ {
+ rank = i + 1;
+ break;
+ }
+ strfree(zoned_name);
+ return rank;
+}
+
+void race_showTime(string text, vector pos, vector timeText_ofs, float theTime, vector textSize, float f)
+{
+ drawstring_aspect(pos, text, textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(pos + timeText_ofs, TIME_ENCODED_TOSTRING(theTime), textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ if (f < 1) {
+ drawstring_aspect_expanding(pos, text, textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
+ drawstring_aspect_expanding(pos + timeText_ofs, TIME_ENCODED_TOSTRING(theTime), textSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, f);
+ }
+}
+
+void HUD_Mod_Race(vector pos, vector mySize)
+{
+ entity me = playerslots[player_localnum];
+ float score = me.(scores(ps_primary));
+
+ if(!(scores_flags(ps_primary) & SFL_TIME) || teamplay) // race/cts record display on HUD
+ {
+ mod_active = 0; // hide it in this case!
+ return; // no records in the actual race
+ }
+
+ mod_active = 1;
+
+ // clientside personal record
+ string rr;
+ if(ISGAMETYPE(CTS))
+ rr = CTS_RECORD;
+ else
+ rr = RACE_RECORD;
+ float t = stof(db_get(ClientProgsDB, strcat(shortmapname, rr, "time")));
+
+ if(score && (score < t || !t)) {
+ db_put(ClientProgsDB, strcat(shortmapname, rr, "time"), ftos(score));
+ if(autocvar_cl_autodemo_delete_keeprecords)
+ {
+ float f = autocvar_cl_autodemo_delete;
+ f &= ~1;
+ cvar_set("cl_autodemo_delete", ftos(f)); // don't delete demo with new record!
+ }
+ }
+
+ if(t != crecordtime_prev) {
+ crecordtime_prev = t;
+ crecordtime_change_time = time;
+ }
+
+ vector textPos, medalPos;
+ float squareSize;
+ if(mySize.x > mySize.y) {
+ // text on left side
+ squareSize = min(mySize.y, mySize.x/2);
+ vector ofs = vec2(0.5 * max(0, mySize.x/2 - squareSize), 0.5 * (mySize.y - squareSize));
+ textPos = pos + ofs;
+ ofs.x += 0.5 * mySize.x;
+ medalPos = pos + ofs;
+ } else {
+ // text on top
+ squareSize = min(mySize.x, mySize.y/2);
+ vector ofs = vec2(0.5 * (mySize.x - squareSize), 0.5 * max(0, mySize.y/2 - squareSize));
+ textPos = pos + ofs;
+ ofs.y += 0.5 * mySize.y;
+ medalPos = pos + ofs;
+ }
+ vector textSize = vec2(squareSize, 0.25 * squareSize);
+
+ race_showTime(_("Personal best"), textPos, eY * 0.25 * squareSize, t, textSize, time - crecordtime_change_time);
+
+ // server record
+ t = race_server_record;
+ if(t != srecordtime_prev) {
+ srecordtime_prev = t;
+ srecordtime_change_time = time;
+ }
+
+ textPos += eY * 0.5 * squareSize;
+ race_showTime(_("Server best"), textPos, eY * 0.25 * squareSize, t, textSize, time - srecordtime_change_time);
+
+ if (race_status != race_status_prev || race_status_name != race_status_name_prev) {
+ race_status_time = time + 5;
+ race_status_prev = race_status;
+ strcpy(race_status_name_prev, race_status_name);
+ }
+
+ // race "awards"
+ float a = bound(0, race_status_time - time, 1);
+ string s = textShortenToWidth(ColorTranslateRGB(race_status_name), squareSize, '1 1 0' * 0.1 * squareSize, stringwidth_colors);
+
+ float rank = 0;
+ if(race_status > 0)
+ rank = race_CheckName(race_status_name);
+ string rankname = count_ordinal(rank);
+ vector namepos = medalPos + '0 0.8 0' * squareSize;
+ vector rankpos = medalPos + '0 0.15 0' * squareSize;
+
+ if(race_status == 0)
+ drawpic_aspect_skin(medalPos, "race_newfail", '1 1 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ else if(race_status == 1) {
+ drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newtime", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ } else if(race_status == 2) {
+ if(strdecolorize(race_status_name) == strdecolorize(entcs_GetName(player_localnum)) || !race_myrank || race_myrank < rank)
+ drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrankgreen", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ else
+ drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrankyellow", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ } else if(race_status == 3) {
+ drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrecordserver", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ }
+
+ if (race_status_time - time <= 0) {
+ race_status_prev = -1;
+ race_status = -1;
+ strfree(race_status_name);
+ strfree(race_status_name_prev);
+ }
+}
+
+REGISTER_MUTATOR(cl_race, true);
+
+MUTATOR_HOOKFUNCTION(cl_race, HUD_Physics_showoptional)
+{
+ return ISGAMETYPE(RACE); // show the optional physics panel
+}
+
+MUTATOR_HOOKFUNCTION(cl_race, HUD_Score_show)
+{
+ return spectatee_status == -1 && ISGAMETYPE(RACE); // hide the score panel while observing
+}
+
+MUTATOR_HOOKFUNCTION(cl_race, ShowRankings)
+{
+ if(ISGAMETYPE(RACE))
+ {
+ M_ARGV(0, string) = _("Rankings");
+ return true;
+ }
+}
+
+MUTATOR_HOOKFUNCTION(cl_race, DrawScoreboardAccuracy)
+{
+ return ISGAMETYPE(RACE); // accuracy is not a factor in this gamemode
+}
+
+MUTATOR_HOOKFUNCTION(cl_race, ShowRaceTimer)
+{
+ return ISGAMETYPE(RACE); // show the race timer panel
+}
+
+MUTATOR_HOOKFUNCTION(cl_race, TeamRadar_Draw)
+{
+ return ISGAMETYPE(RACE); // show all competitors in a race
+}
--- /dev/null
+#pragma once
+
+void HUD_Mod_Race(vector pos, vector mySize);
--- /dev/null
+#include "race.qh"
--- /dev/null
+#pragma once
+
+#include <common/mapinfo.qh>
+
+#ifdef CSQC
+void HUD_Mod_Race(vector pos, vector mySize);
+#endif
+CLASS(Race, Gametype)
+ INIT(Race)
+ {
+ this.gametype_init(this, _("Race"),"rc","g_race",GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line"));
+ }
+ METHOD(Race, m_parse_mapinfo, bool(string k, string v))
+ {
+ if (!k) {
+ cvar_set("g_race_qualifying_timelimit", cvar_defstring("g_race_qualifying_timelimit"));
+ return true;
+ }
+ switch (k) {
+ case "qualifying_timelimit":
+ cvar_set("g_race_qualifying_timelimit", v);
+ return true;
+ }
+ return false;
+ }
+ METHOD(Race, m_generate_mapinfo, void(Gametype this, string v))
+ {
+ if(v == "trigger_race_checkpoint")
+ MapInfo_Map_supportedGametypes |= this.m_flags;
+ }
+ METHOD(Race, m_isTwoBaseMode, bool())
+ {
+ return true;
+ }
+ METHOD(Race, 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, _("Laps:"), 1, 25, 1, "g_race_laps_limit", string_null, string_null);
+ }
+#ifdef CSQC
+ ATTRIB(Race, m_modicons, void(vector pos, vector mySize), HUD_Mod_Race);
+#endif
+ ATTRIB(Race, m_legacydefaults, string, "20 5 7 15 0");
+ENDCLASS(Race)
+REGISTER_GAMETYPE(RACE, NEW(Race));
+#define g_race IS_GAMETYPE(RACE)
// generated file; do not modify
+#include <common/gamemodes/gamemode/tdm/tdm.qc>
#ifdef SVQC
#include <common/gamemodes/gamemode/tdm/sv_tdm.qc>
#endif
// generated file; do not modify
+#include <common/gamemodes/gamemode/tdm/tdm.qh>
#ifdef SVQC
#include <common/gamemodes/gamemode/tdm/sv_tdm.qh>
#endif
--- /dev/null
+#include "tdm.qh"
--- /dev/null
+#pragma once
+
+#include <common/gamemodes/gamemode/deathmatch/deathmatch.qh>
+#include <common/mapinfo.qh>
+
+CLASS(TeamDeathmatch, Gametype)
+ INIT(TeamDeathmatch)
+ {
+ this.gametype_init(this, _("Team Deathmatch"),"tdm","g_tdm",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_PRIORITY,"","timelimit=15 pointlimit=50 teams=2 leadlimit=0",_("Help your team score the most frags against the enemy team"));
+ }
+ METHOD(TeamDeathmatch, m_parse_mapinfo, bool(string k, string v))
+ {
+ if (!k) {
+ cvar_set("g_tdm_teams", cvar_defstring("g_tdm_teams"));
+ return true;
+ }
+ switch (k) {
+ case "teams":
+ cvar_set("g_tdm_teams", v);
+ return true;
+ }
+ return false;
+ }
+ METHOD(TeamDeathmatch, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
+ {
+ if(spawnpoints >= 8 && diameter > 4096)
+ return true;
+ return false;
+ }
+ METHOD(TeamDeathmatch, m_isForcedSupported, bool(Gametype this))
+ {
+ if(cvar("g_tdm_on_dm_maps"))
+ {
+ // if this is set, all DM maps support TDM too
+ if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags))
+ return true; // TODO: references another gametype (alternatively, we could check which gamemodes are always enabled and append this if any are supported)
+ }
+ return false;
+ }
+ METHOD(TeamDeathmatch, m_setTeams, void(string sa))
+ {
+ cvar_set("g_tdm_teams", sa);
+ }
+ METHOD(TeamDeathmatch, 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, _("Point limit:"), 5, 100, 5, "g_tdm_point_limit", "g_tdm_teams_override", _("The amount of points needed before the match will end"));
+ }
+ ATTRIB(TeamDeathmatch, m_legacydefaults, string, "50 20 2 0");
+ENDCLASS(TeamDeathmatch)
+REGISTER_GAMETYPE(TEAM_DEATHMATCH, NEW(TeamDeathmatch));
+#define g_tdm IS_GAMETYPE(TEAM_DEATHMATCH)
return; // do not call Get_ByName!
}
+#if 0
+ // find the lowest bit in the supported gametypes
+ // unnecessary now that we select one at random
int _t = 1;
while(!(MapInfo_Map_supportedGametypes & 1))
{
_t <<= 1;
MapInfo_Map_supportedGametypes = floor(MapInfo_Map_supportedGametypes >> 1);
}
+#endif
+ RandomSelection_Init();
Gametype t_prev = t;
- FOREACH(Gametypes, it.m_flags == _t, { t = it; break; });
+ FOREACH(Gametypes, MapInfo_Map_supportedGametypes & it.m_flags,
+ {
+ RandomSelection_AddEnt(it, 1, it.m_priority);
+ });
+ if(RandomSelection_chosen_ent)
+ t = RandomSelection_chosen_ent;
// t is now a supported mode!
LOG_WARNF("can't play the selected map in the given game mode (%s). Falling back to a supported mode (%s).", t_prev.mdl, t.mdl);
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
+
int MAPINFO_TYPE_ALL;
.int m_flags;
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);
/** 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! */
returns(this.message, strcat("gametype_", this.mdl));
}
- METHOD(Gametype, gametype_init, void(Gametype this, string hname, string sname, string g_name, bool gteamplay, bool gusepoints, string mutators, string defaults, string gdescription))
+ 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 = gteamplay;
+ this.team = (gflags & GAMETYPE_FLAG_TEAMPLAY);
this.m_mutators = cons(sname, mutators);
this.model2 = defaults;
this.gametype_description = gdescription;
- this.frags = gusepoints;
+ 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);
// same as `1 << m_id`
MAPINFO_TYPE_ALL |= this.items = this.m_flags = (MAPINFO_TYPE_ALL + 1);
REGISTRY(Gametypes, 24)
REGISTER_REGISTRY(Gametypes)
+REGISTRY_SORT(Gametypes);
REGISTRY_CHECK(Gametypes)
REGISTRY_DEFINE_GET(Gametypes, NULL)
#define IS_GAMETYPE(NAME) (MapInfo_LoadedGametype == MAPINFO_TYPE_##NAME)
-CLASS(Deathmatch, Gametype)
- INIT(Deathmatch)
- {
- this.gametype_init(this, _("Deathmatch"),"dm","g_dm",false,true,"","timelimit=15 pointlimit=30 leadlimit=0",_("Score as many frags as you can"));
- }
- METHOD(Deathmatch, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
- {
- return true;
- }
- ATTRIB(Deathmatch, m_legacydefaults, string, "30 20 0");
-ENDCLASS(Deathmatch)
-REGISTER_GAMETYPE(DEATHMATCH, NEW(Deathmatch));
-
-CLASS(LastManStanding, Gametype)
- INIT(LastManStanding)
- {
- this.gametype_init(this, _("Last Man Standing"),"lms","g_lms",false,true,"","timelimit=20 lives=5 leadlimit=0",_("Survive and kill until the enemies have no lives left"));
- }
- METHOD(LastManStanding, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
- {
- return true;
- }
- METHOD(LastManStanding, 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, _("Lives:"), 3, 50, 1, "g_lms_lives_override", string_null, string_null);
- }
- ATTRIB(LastManStanding, m_legacydefaults, string, "9 20 0");
-ENDCLASS(LastManStanding)
-REGISTER_GAMETYPE(LMS, NEW(LastManStanding));
-
-#ifdef CSQC
-void HUD_Mod_Race(vector pos, vector mySize);
-#endif
-CLASS(Race, Gametype)
- INIT(Race)
- {
- this.gametype_init(this, _("Race"),"rc","g_race",false,true,"","timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line"));
- }
- METHOD(Race, m_parse_mapinfo, bool(string k, string v))
- {
- if (!k) {
- cvar_set("g_race_qualifying_timelimit", cvar_defstring("g_race_qualifying_timelimit"));
- return true;
- }
- switch (k) {
- case "qualifying_timelimit":
- cvar_set("g_race_qualifying_timelimit", v);
- return true;
- }
- return false;
- }
- METHOD(Race, m_generate_mapinfo, void(Gametype this, string v))
- {
- if(v == "trigger_race_checkpoint")
- MapInfo_Map_supportedGametypes |= this.m_flags;
- }
- METHOD(Race, m_isTwoBaseMode, bool())
- {
- return true;
- }
- METHOD(Race, 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, _("Laps:"), 1, 25, 1, "g_race_laps_limit", string_null, string_null);
- }
-#ifdef CSQC
- ATTRIB(Race, m_modicons, void(vector pos, vector mySize), HUD_Mod_Race);
-#endif
- ATTRIB(Race, m_legacydefaults, string, "20 5 7 15 0");
-ENDCLASS(Race)
-REGISTER_GAMETYPE(RACE, NEW(Race));
-#define g_race IS_GAMETYPE(RACE)
-
-CLASS(RaceCTS, Gametype)
- INIT(RaceCTS)
- {
- this.gametype_init(this, _("Race CTS"),"cts","g_cts",false,false,"cloaked","timelimit=20",_("Race for fastest time."));
- }
- METHOD(RaceCTS, m_generate_mapinfo, void(Gametype this, string v))
- {
- if(v == "target_startTimer")
- MapInfo_Map_supportedGametypes |= this.m_flags;
- }
- METHOD(RaceCTS, m_setTeams, void(string sa))
- {
- // this is the skill of the map
- // not parsed by anything yet
- // for map databases
- // cvar_set("fraglimit", sa);
- }
- METHOD(RaceCTS, 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, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
- }
-#ifdef CSQC
- ATTRIB(RaceCTS, m_modicons, void(vector pos, vector mySize), HUD_Mod_Race);
-#endif
- ATTRIB(RaceCTS, m_legacydefaults, string, "20 0 0");
-ENDCLASS(RaceCTS)
-REGISTER_GAMETYPE(CTS, NEW(RaceCTS));
-#define g_cts IS_GAMETYPE(CTS)
-
-CLASS(TeamDeathmatch, Gametype)
- INIT(TeamDeathmatch)
- {
- this.gametype_init(this, _("Team Deathmatch"),"tdm","g_tdm",true,true,"","timelimit=15 pointlimit=50 teams=2 leadlimit=0",_("Help your team score the most frags against the enemy team"));
- }
- METHOD(TeamDeathmatch, m_parse_mapinfo, bool(string k, string v))
- {
- if (!k) {
- cvar_set("g_tdm_teams", cvar_defstring("g_tdm_teams"));
- return true;
- }
- switch (k) {
- case "teams":
- cvar_set("g_tdm_teams", v);
- return true;
- }
- return false;
- }
- METHOD(TeamDeathmatch, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
- {
- if(spawnpoints >= 8 && diameter > 4096)
- return true;
- return false;
- }
- METHOD(TeamDeathmatch, m_isForcedSupported, bool(Gametype this))
- {
- if(cvar("g_tdm_on_dm_maps"))
- {
- // if this is set, all DM maps support TDM too
- if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags))
- return true; // TODO: references another gametype (alternatively, we could check which gamemodes are always enabled and append this if any are supported)
- }
- return false;
- }
- METHOD(TeamDeathmatch, m_setTeams, void(string sa))
- {
- cvar_set("g_tdm_teams", sa);
- }
- METHOD(TeamDeathmatch, 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, _("Point limit:"), 5, 100, 5, "g_tdm_point_limit", "g_tdm_teams_override", _("The amount of points needed before the match will end"));
- }
- ATTRIB(TeamDeathmatch, m_legacydefaults, string, "50 20 2 0");
-ENDCLASS(TeamDeathmatch)
-REGISTER_GAMETYPE(TEAM_DEATHMATCH, NEW(TeamDeathmatch));
-#define g_tdm IS_GAMETYPE(TEAM_DEATHMATCH)
-
-#ifdef CSQC
-void HUD_Mod_CTF(vector pos, vector mySize);
-void HUD_Mod_CTF_Reset();
-#endif
-CLASS(CaptureTheFlag, Gametype)
- INIT(CaptureTheFlag)
- {
- this.gametype_init(this, _("Capture the Flag"),"ctf","g_ctf",true,true,"","timelimit=20 caplimit=10 leadlimit=6",_("Find and bring the enemy flag to your base to capture it, defend your base from the other team"));
- }
- METHOD(CaptureTheFlag, m_generate_mapinfo, void(Gametype this, string v))
- {
- if(v == "item_flag_team2" || v == "team_CTF_blueflag")
- MapInfo_Map_supportedGametypes |= this.m_flags;
- }
- METHOD(CaptureTheFlag, m_isTwoBaseMode, bool())
- {
- return true;
- }
- METHOD(CaptureTheFlag, m_setTeams, void(string sa))
- {
- cvar_set("fraglimit", sa);
- }
- METHOD(CaptureTheFlag, 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, _("Capture limit:"), 1, 20, 1, "capturelimit_override", string_null, _("The amount of captures needed before the match will end"));
- }
-#ifdef CSQC
- ATTRIB(CaptureTheFlag, m_modicons, void(vector pos, vector mySize), HUD_Mod_CTF);
- ATTRIB(CaptureTheFlag, m_modicons_reset, void(), HUD_Mod_CTF_Reset);
-#endif
- ATTRIB(CaptureTheFlag, m_legacydefaults, string, "300 20 10 0");
-ENDCLASS(CaptureTheFlag)
-REGISTER_GAMETYPE(CTF, NEW(CaptureTheFlag));
-#define g_ctf IS_GAMETYPE(CTF)
-
-#ifdef CSQC
-void HUD_Mod_CA(vector pos, vector mySize);
-#endif
-CLASS(ClanArena, Gametype)
- INIT(ClanArena)
- {
- this.gametype_init(this, _("Clan Arena"),"ca","g_ca",true,true,"","timelimit=20 pointlimit=10 teams=2 leadlimit=6",_("Kill all enemy teammates to win the round"));
- }
- METHOD(ClanArena, m_parse_mapinfo, bool(string k, string v))
- {
- if (!k) {
- cvar_set("g_ca_teams", cvar_defstring("g_ca_teams"));
- return true;
- }
- switch (k) {
- case "teams":
- cvar_set("g_ca_teams", v);
- return true;
- }
- return false;
- }
- METHOD(ClanArena, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
- {
- if(spawnpoints >= 8 && diameter > 4096)
- return true;
- return false;
- }
- METHOD(ClanArena, m_setTeams, void(string sa))
- {
- cvar_set("g_ca_teams", sa);
- }
- METHOD(ClanArena, 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", "g_ca_teams_override", _("The amount of frags needed before the match will end"));
- }
-#ifdef CSQC
- ATTRIB(ClanArena, m_modicons, void(vector pos, vector mySize), HUD_Mod_CA);
-#endif
- ATTRIB(ClanArena, m_legacydefaults, string, "10 20 0");
-ENDCLASS(ClanArena)
-REGISTER_GAMETYPE(CA, NEW(ClanArena));
-#define g_ca IS_GAMETYPE(CA)
-
-#ifdef CSQC
-void HUD_Mod_Dom(vector pos, vector mySize);
-#endif
-CLASS(Domination, Gametype)
- INIT(Domination)
- {
- this.gametype_init(this, _("Domination"),"dom","g_domination",true,true,"","timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture and defend all the control points to win"));
- }
- METHOD(Domination, m_parse_mapinfo, bool(string k, string v))
- {
- if (!k) {
- cvar_set("g_domination_default_teams", cvar_defstring("g_domination_default_teams"));
- return true;
- }
- switch (k) {
- case "teams":
- cvar_set("g_domination_default_teams", v);
- return true;
- }
- return false;
- }
- METHOD(Domination, m_generate_mapinfo, void(Gametype this, string v))
- {
- if(v == "dom_controlpoint")
- MapInfo_Map_supportedGametypes |= this.m_flags;
- }
- METHOD(Domination, 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, _("Point limit:"), 50, 500, 10, "g_domination_point_limit", "g_domination_teams_override", _("The amount of points needed before the match will end"));
- }
-#ifdef CSQC
- ATTRIB(Domination, m_modicons, void(vector pos, vector mySize), HUD_Mod_Dom);
-#endif
- ATTRIB(Domination, m_legacydefaults, string, "200 20 0");
-ENDCLASS(Domination)
-REGISTER_GAMETYPE(DOMINATION, NEW(Domination));
-
-#ifdef CSQC
-void HUD_Mod_KH(vector pos, vector mySize);
-#endif
-CLASS(KeyHunt, Gametype)
- INIT(KeyHunt)
- {
- this.gametype_init(this, _("Key Hunt"),"kh","g_keyhunt",true,true,"","timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round"));
- }
- METHOD(KeyHunt, m_parse_mapinfo, bool(string k, string v))
- {
- if (!k) {
- cvar_set("g_keyhunt_teams", cvar_defstring("g_keyhunt_teams"));
- return true;
- }
- switch (k) {
- case "teams":
- cvar_set("g_keyhunt_teams", v);
- return true;
- }
- return false;
- }
- METHOD(KeyHunt, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
- {
- if(spawnpoints >= 12 && diameter > 5120)
- return true;
- return false;
- }
- METHOD(KeyHunt, m_setTeams, void(string sa))
- {
- cvar_set("g_keyhunt_teams", sa);
- }
- METHOD(KeyHunt, 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, _("Point limit:"), 200, 1500, 50, "g_keyhunt_point_limit", "g_keyhunt_teams_override", _("The amount of points needed before the match will end"));
- }
-#ifdef CSQC
- ATTRIB(KeyHunt, m_modicons, void(vector pos, vector mySize), HUD_Mod_KH);
-#endif
- ATTRIB(KeyHunt, m_legacydefaults, string, "1000 20 3 0");
-ENDCLASS(KeyHunt)
-REGISTER_GAMETYPE(KEYHUNT, NEW(KeyHunt));
-
-CLASS(Assault, Gametype)
- INIT(Assault)
- {
- this.gametype_init(this, _("Assault"),"as","g_assault",true,false,"","timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out"));
- }
- METHOD(Assault, m_generate_mapinfo, void(Gametype this, string v))
- {
- if(v == "target_assault_roundend")
- MapInfo_Map_supportedGametypes |= this.m_flags;
- }
- METHOD(Assault, m_isTwoBaseMode, bool())
- {
- return true;
- }
- METHOD(Assault, 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, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
- }
- ATTRIB(Assault, m_legacydefaults, string, "20 0");
-ENDCLASS(Assault)
-REGISTER_GAMETYPE(ASSAULT, NEW(Assault));
-#define g_assault IS_GAMETYPE(ASSAULT)
-
-CLASS(Onslaught, Gametype)
- INIT(Onslaught)
- {
- this.gametype_init(this, _("Onslaught"),"ons","g_onslaught",true,false,"","pointlimit=1 timelimit=20",_("Capture control points to reach and destroy the enemy generator"));
- }
- METHOD(Onslaught, m_generate_mapinfo, void(Gametype this, string v))
- {
- if(v == "onslaught_generator")
- MapInfo_Map_supportedGametypes |= this.m_flags;
- }
- METHOD(Onslaught, 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, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
- }
- ATTRIB(Onslaught, m_legacydefaults, string, "20 0");
-ENDCLASS(Onslaught)
-REGISTER_GAMETYPE(ONSLAUGHT, NEW(Onslaught));
-
-#ifdef CSQC
-void HUD_Mod_NexBall(vector pos, vector mySize);
-#endif
-CLASS(NexBall, Gametype)
- INIT(NexBall)
- {
- this.gametype_init(this, _("Nexball"),"nb","g_nexball",true,true,"","timelimit=20 pointlimit=5 leadlimit=0",_("Shoot and kick the ball into the enemies goal, keep your goal clean"));
- }
- METHOD(NexBall, m_generate_mapinfo, void(Gametype this, string v))
- {
- if(substring(v, 0, 8) == "nexball_" || substring(v, 0, 4) == "ball")
- MapInfo_Map_supportedGametypes |= this.m_flags;
- }
- METHOD(NexBall, m_isTwoBaseMode, bool())
- {
- return true;
- }
- METHOD(NexBall, 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, _("Goals:"), 1, 50, 1, "g_nexball_goallimit", string_null, _("The amount of goals needed before the match will end"));
- }
-#ifdef CSQC
- ATTRIB(NexBall, m_modicons, void(vector pos, vector mySize), HUD_Mod_NexBall);
-#endif
- ATTRIB(NexBall, m_legacydefaults, string, "5 20 0");
-ENDCLASS(NexBall)
-REGISTER_GAMETYPE(NEXBALL, NEW(NexBall));
-#define g_nexball IS_GAMETYPE(NEXBALL)
-
-CLASS(FreezeTag, Gametype)
- INIT(FreezeTag)
- {
- this.gametype_init(this, _("Freeze Tag"),"ft","g_freezetag",true,true,"","timelimit=20 pointlimit=10 teams=2 leadlimit=6",_("Kill enemies to freeze them, stand next to frozen teammates to revive them; freeze all enemies to win"));
- }
- METHOD(FreezeTag, m_parse_mapinfo, bool(string k, string v))
- {
- if (!k) {
- cvar_set("g_freezetag_teams", cvar_defstring("g_freezetag_teams"));
- return true;
- }
- switch (k) {
- case "teams":
- cvar_set("g_freezetag_teams", v);
- return true;
- }
- return false;
- }
- METHOD(FreezeTag, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
- {
- if(spawnpoints >= 8 && diameter > 4096)
- return true;
- return false;
- }
- METHOD(FreezeTag, m_setTeams, void(string sa))
- {
- cvar_set("g_freezetag_teams", sa);
- }
- METHOD(FreezeTag, 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", "g_freezetag_teams_override", _("The amount of frags needed before the match will end"));
- }
-#ifdef CSQC
- ATTRIB(FreezeTag, m_modicons, void(vector pos, vector mySize), HUD_Mod_CA);
-#endif
- ATTRIB(FreezeTag, m_legacydefaults, string, "10 20 0");
-ENDCLASS(FreezeTag)
-REGISTER_GAMETYPE(FREEZETAG, NEW(FreezeTag));
-#define g_freezetag IS_GAMETYPE(FREEZETAG)
-
-#ifdef CSQC
-void HUD_Mod_Keepaway(vector pos, vector mySize);
-#endif
-CLASS(Keepaway, Gametype)
- INIT(Keepaway)
- {
- this.gametype_init(this, _("Keepaway"),"ka","g_keepaway",false,true,"","timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
- }
- METHOD(Keepaway, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
- {
- return true;
- }
-#ifdef CSQC
- ATTRIB(Keepaway, m_modicons, void(vector pos, vector mySize), HUD_Mod_Keepaway);
-#endif
-ENDCLASS(Keepaway)
-REGISTER_GAMETYPE(KEEPAWAY, NEW(Keepaway));
-
-CLASS(Invasion, Gametype)
- INIT(Invasion)
- {
- this.gametype_init(this, _("Invasion"),"inv","g_invasion",false,true,"","pointlimit=50 teams=0 type=0",_("Survive against waves of monsters"));
- }
- METHOD(Invasion, m_parse_mapinfo, bool(string k, string v))
- {
- switch (k) {
- case "teams":
- cvar_set("g_invasion_teams", v);
- return true;
- case "type":
- cvar_set("g_invasion_type", v);
- return true;
- }
- return false;
- }
- METHOD(Invasion, m_generate_mapinfo, void(Gametype this, string v))
- {
- if(v == "invasion_spawnpoint")
- MapInfo_Map_supportedGametypes |= this.m_flags;
- }
- METHOD(Invasion, 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, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
- }
-ENDCLASS(Invasion)
-REGISTER_GAMETYPE(INVASION, NEW(Invasion));
-
-CLASS(Duel, Gametype)
- INIT(Duel)
- {
- this.gametype_init(this, _("Duel"),"duel","g_duel",false,true,"","timelimit=10 pointlimit=0 leadlimit=0",_("Fight in a one versus one arena battle to decide the winner"));
- }
- METHOD(Duel, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
- {
- return (diameter < 16384);
- }
- METHOD(Duel, m_isForcedSupported, bool(Gametype this))
- {
- if(!cvar("g_duel_not_dm_maps"))
- {
- // if this is set, all DM maps support duel too
- // TODO: we should really check the size of maps, some DM maps do not work for duel!
- if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags))
- return true; // TODO: references another gametype (alternatively, we could check which gamemodes are always enabled and append this if any are supported)
- }
- return false;
- }
-ENDCLASS(Duel)
-REGISTER_GAMETYPE(DUEL, NEW(Duel));
-#define g_duel IS_GAMETYPE(DUEL)
-
const int MAPINFO_FEATURE_WEAPONS = 1; // not defined for instagib-only maps
const int MAPINFO_FEATURE_VEHICLES = 2;
const int MAPINFO_FEATURE_TURRETS = 4;
#include "../deathtypes/all.qh"
#include "../turrets/sv_turrets.qh"
#include "../vehicles/all.qh"
- #include "../mapinfo.qh"
+ #include <common/gamemodes/_mod.qh>
#include <server/anticheat.qh>
#endif
#pragma once
#include "items.qh"
+#include <common/gamemodes/_mod.qh>
float autocvar_g_instagib_invis_alpha;
int autocvar_g_instagib_extralives;
#include "notifications/all.qh"
#include "scores.qh"
#include <common/deathtypes/all.qh>
+ #include <common/gamemodes/_mod.qh>
#elif defined(MENUQC)
#elif defined(SVQC)
#include "constants.qh"
#include <server/mutators/_mod.qh>
#include "notifications/all.qh"
#include <common/deathtypes/all.qh>
+ #include <common/gamemodes/_mod.qh>
#include "scores.qh"
#include "mapinfo.qh"
#endif
#include "dialog_singleplayer.qh"
-#include <common/mapinfo.qh>
+#include <common/gamemodes/_mod.qh>
#include "bigbutton.qh"
#include "radiobutton.qh"
#include "textlabel.qh"
#include "gametypelist.qh"
#include "dialog_multiplayer_create.qh"
+#include <common/gamemodes/_mod.qh>
#include <common/mapinfo.qh>
entity makeXonoticGametypeList()
#include "../menu.qh"
#include <common/campaign_common.qh>
#include <common/constants.qh>
-#include <common/mapinfo.qh>
+#include <common/gamemodes/_mod.qh>
#include <common/util.qh>
#include <common/command/_mod.qh>
#include <common/constants.qh>
#include <common/debug.qh>
+#include <common/gamemodes/_mod.qh>
#include <common/mapobjects/trigger/jumppads.qh>
#include <common/net_linked.qh>
#include <common/physics/player.qh>
#include "../race.qh"
#include <common/constants.qh>
+#include <common/gamemodes/_mod.qh>
#include <common/net_linked.qh>
-#include <common/mapinfo.qh>
#include <common/util.qh>
#include <common/monsters/_mod.qh>
#include <server/miscfunctions.qh>
#include <server/items.qh>
#include <server/resources.qh>
+#include <common/gamemodes/_mod.qh>
#include <common/t_items.qh>
#include <common/mapobjects/triggers.qh>
#include <common/mapobjects/trigger/counter.qh>
#include "../common/playerstats.qh"
#include "../common/teams.qh"
#include "../common/util.qh"
+#include <common/gamemodes/_mod.qh>
#include <common/gamemodes/rules.qh>
#include <common/weapons/_all.qh>
#include "../lib/csqcmodel/sv_model.qh"
#include "../common/constants.qh"
#include <common/net_linked.qh>
#include "../common/deathtypes/all.qh"
+#include <common/gamemodes/_mod.qh>
#include "../common/gamemodes/sv_rules.qh"
#include "../common/mapinfo.qh"
#include "../common/monsters/_mod.qh"
#include "weapons/tracing.qh"
#include "weapons/weaponsystem.qh"
+#include <common/gamemodes/_mod.qh>
+
#include <common/state.qh>
#include "../common/minigames/sv_minigames.qh"
#include "command/getreplies.qh"
#include "../common/deathtypes/all.qh"
#include "../common/notifications/all.qh"
-#include "../common/mapinfo.qh"
+#include <common/gamemodes/_mod.qh>
#include <common/gamemodes/rules.qh>
#include <common/net_linked.qh>
#include <common/state.qh>
#include "../common/constants.qh"
#include <common/net_linked.qh>
#include "../common/teams.qh"
-#include <common/mapinfo.qh>
+#include <common/gamemodes/_mod.qh>
#include "../common/mapobjects/subs.qh"
#include "../common/mapobjects/target/spawnpoint.qh"
#include "../common/util.qh"