From 578d8400ce4fef99b6f31155e2ce29840e2e5780 Mon Sep 17 00:00:00 2001 From: BuddyFriendGuy Date: Wed, 3 Jun 2015 03:28:05 -0400 Subject: [PATCH] create private tab under server; private list is yet TODO --- qcsrc/menu/classes.inc | 5 +- qcsrc/menu/xonotic/dialog_multiplayer.qc | 2 +- qcsrc/menu/xonotic/dialog_multiplayer_join.qc | 82 +- .../dialog_multiplayer_join_private.qc | 82 + .../xonotic/dialog_multiplayer_join_public.qc | 81 + ...log_multiplayer_join_public_serverinfo.qc} | 0 qcsrc/menu/xonotic/privateserverlist.qc | 1324 +++++++++++++++++ qcsrc/menu/xonotic/serverlist.qc | 2 + 8 files changed, 1512 insertions(+), 66 deletions(-) create mode 100644 qcsrc/menu/xonotic/dialog_multiplayer_join_private.qc create mode 100644 qcsrc/menu/xonotic/dialog_multiplayer_join_public.qc rename qcsrc/menu/xonotic/{dialog_multiplayer_join_serverinfo.qc => dialog_multiplayer_join_public_serverinfo.qc} (100%) create mode 100644 qcsrc/menu/xonotic/privateserverlist.qc diff --git a/qcsrc/menu/classes.inc b/qcsrc/menu/classes.inc index 68b90d586..39a502bd1 100644 --- a/qcsrc/menu/classes.inc +++ b/qcsrc/menu/classes.inc @@ -65,7 +65,9 @@ #include "xonotic/dialog_multiplayer_create_mapinfo.qc" #include "xonotic/dialog_multiplayer_create_mutators.qc" #include "xonotic/dialog_multiplayer_join.qc" -#include "xonotic/dialog_multiplayer_join_serverinfo.qc" +#include "xonotic/dialog_multiplayer_join_public.qc" +#include "xonotic/dialog_multiplayer_join_public_serverinfo.qc" +#include "xonotic/dialog_multiplayer_join_private.qc" #include "xonotic/dialog_multiplayer_media.qc" #include "xonotic/dialog_multiplayer_media_demo.qc" #include "xonotic/dialog_multiplayer_media_demo_startconfirm.qc" @@ -110,6 +112,7 @@ #include "xonotic/playerlist.qc" #include "xonotic/playermodel.qc" #include "xonotic/playlist.qc" +#include "xonotic/privateserverlist.qc" #include "xonotic/radiobutton.qc" #include "xonotic/rootdialog.qc" #include "xonotic/screenshotimage.qc" diff --git a/qcsrc/menu/xonotic/dialog_multiplayer.qc b/qcsrc/menu/xonotic/dialog_multiplayer.qc index 6aedde7fd..47f5e5742 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer.qc @@ -17,7 +17,7 @@ void XonoticMultiplayerDialog_fill(entity me) entity mc, e; mc = makeXonoticTabController(me.rows - 1); me.TR(me); - me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Servers"), makeXonoticServerListTab())); + me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Servers"), makeXonoticJoinTab())); me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Create"), makeXonoticServerCreateTab())); //me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Demos"), makeXonoticDemoBrowserTab())); //me.TD(me, 1, 1, e = mc.makeTabButton(mc, _("Screenshots"), makeXonoticScreenshotBrowserTab())); diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join.qc b/qcsrc/menu/xonotic/dialog_multiplayer_join.qc index 2b2354c53..df7a7c531 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_join.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_join.qc @@ -1,81 +1,35 @@ #ifndef DIALOG_MULTIPLAYER_JOIN_H #define DIALOG_MULTIPLAYER_JOIN_H #include "tab.qc" -CLASS(XonoticServerListTab, XonoticTab) - METHOD(XonoticServerListTab, fill, void(entity)) - ATTRIB(XonoticServerListTab, title, string, _("Join")) - ATTRIB(XonoticServerListTab, intendedWidth, float, 0.9) - ATTRIB(XonoticServerListTab, rows, float, 23) - ATTRIB(XonoticServerListTab, columns, float, 6.5) -ENDCLASS(XonoticServerListTab) -entity makeXonoticServerListTab(); +CLASS(XonoticJoinTab, XonoticTab) + METHOD(XonoticJoinTab, fill, void(entity)) + ATTRIB(XonoticJoinTab, title, string, _("Join")) + ATTRIB(XonoticJoinTab, intendedWidth, float, 0.9) + ATTRIB(XonoticJoinTab, rows, float, 23) + ATTRIB(XonoticJoinTab, columns, float, 3) + ATTRIB(XonoticJoinTab, name, string, "Join") +ENDCLASS(XonoticJoinTab) +entity makeXonoticJoinTab(); #endif #ifdef IMPLEMENTATION - -entity makeXonoticServerListTab() +entity makeXonoticJoinTab() { entity me; - me = NEW(XonoticServerListTab); + me = NEW(XonoticJoinTab); me.configureDialog(me); return me; } -void XonoticServerListTab_fill(entity me) +void XonoticJoinTab_fill(entity me) { - entity e, slist; - - slist = makeXonoticServerList(); + entity mc, e; + mc = makeXonoticTabController(me.rows - 2); me.gotoRC(me, 0.5, 0); - me.TD(me, 1, 0.6, e = makeXonoticTextLabel(1, _("Filter:"))); - me.TD(me, 1, 2.8, e = makeXonoticInputBox(0, string_null)); - e.onChange = ServerList_Filter_Change; - e.onChangeEntity = slist; - slist.controlledTextbox = e; - - me.gotoRC(me, 0.5, 3.6); - me.TD(me, 1, 0.9, e = makeXonoticCheckBox(0, "menu_slist_categories", ZCTX(_("SRVS^Categories")))); - e.onClickEntity = slist; - e.onClick = ServerList_Categories_Click; - me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "menu_slist_showempty", ZCTX(_("SRVS^Empty")))); - slist.filterShowEmpty = e.checked; - e.onClickEntity = slist; - e.onClick = ServerList_ShowEmpty_Click; - me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "menu_slist_showfull", ZCTX(_("SRVS^Full")))); - slist.filterShowFull = e.checked; - e.onClickEntity = slist; - e.onClick = ServerList_ShowFull_Click; - me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "net_slist_pause", _("Pause"))); - - me.gotoRC(me, 2, 0); - me.TD(me, 1, 1, slist.sortButton1 = makeXonoticButton(string_null, '0 0 0')); - me.TD(me, 1, 1, slist.sortButton2 = makeXonoticButton(string_null, '0 0 0')); - me.TD(me, 1, 1, slist.sortButton3 = makeXonoticButton(string_null, '0 0 0')); - me.TD(me, 1, 1, slist.sortButton4 = makeXonoticButton(string_null, '0 0 0')); - me.TD(me, 1, 1, slist.sortButton5 = makeXonoticButton(string_null, '0 0 0')); - me.TR(me); - me.TD(me, me.rows - 5, me.columns, slist); + me.TD(me, 1, 1.5, e = mc.makeTabButton(mc, _("Public"), makeXonoticServerListTab())); + me.TD(me, 1, 1.5, e = mc.makeTabButton(mc, _("Private"), makeXonoticPrivateServerListTab())); - me.gotoRC(me, me.rows - 2, 0); - me.TD(me, 1, 0.6, e = makeXonoticTextLabel(0, _("Address:"))); - me.TD(me, 1, 2.9, e = makeXonoticInputBox(0, string_null)); - e.onEnter = ServerList_Connect_Click; - e.onEnterEntity = slist; - e.onChange = ServerList_Update_favoriteButton; - e.onChangeEntity = slist; - slist.ipAddressBox = e; - me.TD(me, 1, 1.5, e = makeXonoticButton("", '0 0 0')); - e.onClick = ServerList_Favorite_Click; - e.onClickEntity = slist; - slist.favoriteButton = e; - me.TD(me, 1, 1.5, e = makeXonoticButton(_("Info..."), '0 0 0')); - e.onClick = ServerList_Info_Click; - e.onClickEntity = slist; - slist.infoButton = e; - me.TR(me); - me.TD(me, 1, me.columns, e = makeXonoticButton(_("Join!"), '0 0 0')); - e.onClick = ServerList_Connect_Click; - e.onClickEntity = slist; - slist.connectButton = e; + me.gotoRC(me, 3, 0); + me.TD(me, me.rows - 2, me.columns, mc); } #endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join_private.qc b/qcsrc/menu/xonotic/dialog_multiplayer_join_private.qc new file mode 100644 index 000000000..c88464264 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_join_private.qc @@ -0,0 +1,82 @@ +#ifndef DIALOG_MULTIPLAYER_JOIN_PRIVATE_H +#define DIALOG_MULTIPLAYER_JOIN_PRIVATE_H +#include "tab.qc" +CLASS(XonoticPrivateServerListTab, XonoticTab) + METHOD(XonoticPrivateServerListTab, fill, void(entity)) + ATTRIB(XonoticPrivateServerListTab, title, string, _("Private")) + ATTRIB(XonoticPrivateServerListTab, intendedWidth, float, 0.9) + ATTRIB(XonoticPrivateServerListTab, rows, float, 21) + ATTRIB(XonoticPrivateServerListTab, columns, float, 6.5) +ENDCLASS(XonoticPrivateServerListTab) +entity makeXonoticPrivateServerListTab(); +#endif + +#ifdef IMPLEMENTATION + +entity makeXonoticPrivateServerListTab() +{ + entity me; + me = NEW(XonoticPrivateServerListTab); + me.configureDialog(me); + return me; +} +void XonoticPrivateServerListTab_fill(entity me) +{ + //entity e, slist; + entity e; + + //slist = makeXonoticPrivateServerList(); + + me.gotoRC(me, 0.5, 0); + me.TD(me, 1, 0.6, e = makeXonoticTextLabel(1, _("Filter:"))); + me.TD(me, 1, 2.8, e = makeXonoticInputBox(0, string_null)); + //e.onChange = PrivateServerList_Filter_Change; + //e.onChangeEntity = slist; + //slist.controlledTextbox = e; + + me.gotoRC(me, 0.5, 3.6); + me.TD(me, 1, 0.9, e = makeXonoticCheckBox(0, "menu_slist_categories", ZCTX(_("SRVS^Categories")))); + //e.onClickEntity = slist; + //e.onClick = PrivateServerList_Categories_Click; + me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "menu_slist_showempty", ZCTX(_("SRVS^Empty")))); + //slist.filterShowEmpty = e.checked; + //e.onClickEntity = slist; + //e.onClick = PrivateServerList_ShowEmpty_Click; + me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "menu_slist_showfull", ZCTX(_("SRVS^Full")))); + //slist.filterShowFull = e.checked; + //e.onClickEntity = slist; + //e.onClick = PrivateServerList_ShowFull_Click; + me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "net_slist_pause", _("Pause"))); + + me.gotoRC(me, 2, 0); + //me.TD(me, 1, 1, slist.sortButton1 = makeXonoticButton(string_null, '0 0 0')); + //me.TD(me, 1, 1, slist.sortButton2 = makeXonoticButton(string_null, '0 0 0')); + //me.TD(me, 1, 1, slist.sortButton3 = makeXonoticButton(string_null, '0 0 0')); + //me.TD(me, 1, 1, slist.sortButton4 = makeXonoticButton(string_null, '0 0 0')); + //me.TD(me, 1, 1, slist.sortButton5 = makeXonoticButton(string_null, '0 0 0')); + me.TR(me); + //me.TD(me, me.rows - 5, me.columns, slist); + + me.gotoRC(me, me.rows - 2, 0); + me.TD(me, 1, 0.6, e = makeXonoticTextLabel(0, _("Address:"))); + me.TD(me, 1, 2.9, e = makeXonoticInputBox(0, string_null)); + //e.onEnter = PrivateServerList_Connect_Click; + //e.onEnterEntity = slist; + //e.onChange = PrivateServerList_Update_favoriteButton; + //e.onChangeEntity = slist; + //slist.ipAddressBox = e; + me.TD(me, 1, 1.5, e = makeXonoticButton("", '0 0 0')); + //e.onClick = PrivateServerList_Favorite_Click; + //e.onClickEntity = slist; + //slist.favoriteButton = e; + me.TD(me, 1, 1.5, e = makeXonoticButton(_("Info..."), '0 0 0')); + //e.onClick = PrivateServerList_Info_Click; + //e.onClickEntity = slist; + //slist.infoButton = e; + me.TR(me); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("Join!"), '0 0 0')); + //e.onClick = PrivateServerList_Connect_Click; + //e.onClickEntity = slist; + //slist.connectButton = e; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join_public.qc b/qcsrc/menu/xonotic/dialog_multiplayer_join_public.qc new file mode 100644 index 000000000..8996bf3f0 --- /dev/null +++ b/qcsrc/menu/xonotic/dialog_multiplayer_join_public.qc @@ -0,0 +1,81 @@ +#ifndef DIALOG_MULTIPLAYER_JOIN_PUBLIC_H +#define DIALOG_MULTIPLAYER_JOIN_PUBLIC_H +#include "tab.qc" +CLASS(XonoticServerListTab, XonoticTab) + METHOD(XonoticServerListTab, fill, void(entity)) + ATTRIB(XonoticServerListTab, title, string, _("Public")) + ATTRIB(XonoticServerListTab, intendedWidth, float, 0.9) + ATTRIB(XonoticServerListTab, rows, float, 21) + ATTRIB(XonoticServerListTab, columns, float, 6.5) +ENDCLASS(XonoticServerListTab) +entity makeXonoticServerListTab(); +#endif + +#ifdef IMPLEMENTATION + +entity makeXonoticServerListTab() +{ + entity me; + me = NEW(XonoticServerListTab); + me.configureDialog(me); + return me; +} +void XonoticServerListTab_fill(entity me) +{ + entity e, slist; + + slist = makeXonoticServerList(); + + me.gotoRC(me, 0.5, 0); + me.TD(me, 1, 0.6, e = makeXonoticTextLabel(1, _("Filter:"))); + me.TD(me, 1, 2.8, e = makeXonoticInputBox(0, string_null)); + e.onChange = ServerList_Filter_Change; + e.onChangeEntity = slist; + slist.controlledTextbox = e; + + me.gotoRC(me, 0.5, 3.6); + me.TD(me, 1, 0.9, e = makeXonoticCheckBox(0, "menu_slist_categories", ZCTX(_("SRVS^Categories")))); + e.onClickEntity = slist; + e.onClick = ServerList_Categories_Click; + me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "menu_slist_showempty", ZCTX(_("SRVS^Empty")))); + slist.filterShowEmpty = e.checked; + e.onClickEntity = slist; + e.onClick = ServerList_ShowEmpty_Click; + me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "menu_slist_showfull", ZCTX(_("SRVS^Full")))); + slist.filterShowFull = e.checked; + e.onClickEntity = slist; + e.onClick = ServerList_ShowFull_Click; + me.TD(me, 1, 0.6, e = makeXonoticCheckBox(0, "net_slist_pause", _("Pause"))); + + me.gotoRC(me, 2, 0); + me.TD(me, 1, 1, slist.sortButton1 = makeXonoticButton(string_null, '0 0 0')); + me.TD(me, 1, 1, slist.sortButton2 = makeXonoticButton(string_null, '0 0 0')); + me.TD(me, 1, 1, slist.sortButton3 = makeXonoticButton(string_null, '0 0 0')); + me.TD(me, 1, 1, slist.sortButton4 = makeXonoticButton(string_null, '0 0 0')); + me.TD(me, 1, 1, slist.sortButton5 = makeXonoticButton(string_null, '0 0 0')); + me.TR(me); + me.TD(me, me.rows - 5, me.columns, slist); + + me.gotoRC(me, me.rows - 2, 0); + me.TD(me, 1, 0.6, e = makeXonoticTextLabel(0, _("Address:"))); + me.TD(me, 1, 2.9, e = makeXonoticInputBox(0, string_null)); + e.onEnter = ServerList_Connect_Click; + e.onEnterEntity = slist; + e.onChange = ServerList_Update_favoriteButton; + e.onChangeEntity = slist; + slist.ipAddressBox = e; + me.TD(me, 1, 1.5, e = makeXonoticButton("", '0 0 0')); + e.onClick = ServerList_Favorite_Click; + e.onClickEntity = slist; + slist.favoriteButton = e; + me.TD(me, 1, 1.5, e = makeXonoticButton(_("Info..."), '0 0 0')); + e.onClick = ServerList_Info_Click; + e.onClickEntity = slist; + slist.infoButton = e; + me.TR(me); + me.TD(me, 1, me.columns, e = makeXonoticButton(_("Join!"), '0 0 0')); + e.onClick = ServerList_Connect_Click; + e.onClickEntity = slist; + slist.connectButton = e; +} +#endif diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc b/qcsrc/menu/xonotic/dialog_multiplayer_join_public_serverinfo.qc similarity index 100% rename from qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc rename to qcsrc/menu/xonotic/dialog_multiplayer_join_public_serverinfo.qc diff --git a/qcsrc/menu/xonotic/privateserverlist.qc b/qcsrc/menu/xonotic/privateserverlist.qc new file mode 100644 index 000000000..c68597df9 --- /dev/null +++ b/qcsrc/menu/xonotic/privateserverlist.qc @@ -0,0 +1,1324 @@ +//#ifndef SERVERLIST_H +//#define SERVERLIST_H +//#include "listbox.qc" +//CLASS(XonoticPrivateServerList, XonoticListBox) +// METHOD(XonoticPrivateServerList, configureXonoticPrivateServerList, void(entity)) +// ATTRIB(XonoticPrivateServerList, rowsPerItem, float, 1) +// METHOD(XonoticPrivateServerList, draw, void(entity)) +// METHOD(XonoticPrivateServerList, drawListBoxItem, void(entity, float, vector, float)) +// METHOD(XonoticPrivateServerList, doubleClickListBoxItem, void(entity, float, vector)) +// METHOD(XonoticPrivateServerList, resizeNotify, void(entity, vector, vector, vector, vector)) +// METHOD(XonoticPrivateServerList, keyDown, float(entity, float, float, float)) +// METHOD(XonoticPrivateServerList, toggleFavorite, void(entity, string)) +// +// ATTRIB(XonoticPrivateServerList, iconsSizeFactor, float, 0.85) +// +// ATTRIB(XonoticPrivateServerList, realFontSize, vector, '0 0 0') +// ATTRIB(XonoticPrivateServerList, realUpperMargin, float, 0) +// ATTRIB(XonoticPrivateServerList, columnIconsOrigin, float, 0) +// ATTRIB(XonoticPrivateServerList, columnIconsSize, float, 0) +// ATTRIB(XonoticPrivateServerList, columnPingOrigin, float, 0) +// ATTRIB(XonoticPrivateServerList, columnPingSize, float, 0) +// ATTRIB(XonoticPrivateServerList, columnNameOrigin, float, 0) +// ATTRIB(XonoticPrivateServerList, columnNameSize, float, 0) +// ATTRIB(XonoticPrivateServerList, columnMapOrigin, float, 0) +// ATTRIB(XonoticPrivateServerList, columnMapSize, float, 0) +// ATTRIB(XonoticPrivateServerList, columnTypeOrigin, float, 0) +// ATTRIB(XonoticPrivateServerList, columnTypeSize, float, 0) +// ATTRIB(XonoticPrivateServerList, columnPlayersOrigin, float, 0) +// ATTRIB(XonoticPrivateServerList, columnPlayersSize, float, 0) +// +// ATTRIB(XonoticPrivateServerList, selectedServer, string, string_null) // to restore selected server when needed +// METHOD(XonoticPrivateServerList, setSelected, void(entity, float)) +// METHOD(XonoticPrivateServerList, setSortOrder, void(entity, float, float)) +// ATTRIB(XonoticPrivateServerList, filterShowEmpty, float, 1) +// ATTRIB(XonoticPrivateServerList, filterShowFull, float, 1) +// ATTRIB(XonoticPrivateServerList, filterString, string, string_null) +// ATTRIB(XonoticPrivateServerList, controlledTextbox, entity, NULL) +// ATTRIB(XonoticPrivateServerList, ipAddressBox, entity, NULL) +// ATTRIB(XonoticPrivateServerList, favoriteButton, entity, NULL) +// ATTRIB(XonoticPrivateServerList, nextRefreshTime, float, 0) +// METHOD(XonoticPrivateServerList, refreshPrivateServerList, void(entity, float)) // refresh mode: REFRESHSERVERLIST_* +// ATTRIB(XonoticPrivateServerList, needsRefresh, float, 1) +// METHOD(XonoticPrivateServerList, focusEnter, void(entity)) +// METHOD(XonoticPrivateServerList, positionSortButton, void(entity, entity, float, float, string, void(entity, entity))) +// ATTRIB(XonoticPrivateServerList, sortButton1, entity, NULL) +// ATTRIB(XonoticPrivateServerList, sortButton2, entity, NULL) +// ATTRIB(XonoticPrivateServerList, sortButton3, entity, NULL) +// ATTRIB(XonoticPrivateServerList, sortButton4, entity, NULL) +// ATTRIB(XonoticPrivateServerList, sortButton5, entity, NULL) +// ATTRIB(XonoticPrivateServerList, connectButton, entity, NULL) +// ATTRIB(XonoticPrivateServerList, infoButton, entity, NULL) +// ATTRIB(XonoticPrivateServerList, currentSortOrder, float, 0) +// ATTRIB(XonoticPrivateServerList, currentSortField, float, -1) +// +// ATTRIB(XonoticPrivateServerList, ipAddressBoxFocused, float, -1) +// +// ATTRIB(XonoticPrivateServerList, seenIPv4, float, 0) +// ATTRIB(XonoticPrivateServerList, seenIPv6, float, 0) +// ATTRIB(XonoticPrivateServerList, categoriesHeight, float, 1.25) +// +// METHOD(XonoticPrivateServerList, getTotalHeight, float(entity)) +// METHOD(XonoticPrivateServerList, getItemAtPos, float(entity, float)) +// METHOD(XonoticPrivateServerList, getItemStart, float(entity, float)) +// METHOD(XonoticPrivateServerList, getItemHeight, float(entity, float)) +//ENDCLASS(XonoticPrivateServerList) +//entity makeXonoticPrivateServerList(); +// +//#ifndef IMPLEMENTATION +//float autocvar_menu_slist_categories; +//float autocvar_menu_slist_categories_onlyifmultiple; +//float autocvar_menu_slist_purethreshold; +//float autocvar_menu_slist_modimpurity; +//float autocvar_menu_slist_recommendations; +//float autocvar_menu_slist_recommendations_maxping; +//float autocvar_menu_slist_recommendations_minfreeslots; +//float autocvar_menu_slist_recommendations_minhumans; +//float autocvar_menu_slist_recommendations_purethreshold; +// +//// server cache fields +//#define SLIST_FIELDS \ +// SLIST_FIELD(CNAME, "cname") \ +// SLIST_FIELD(PING, "ping") \ +// SLIST_FIELD(GAME, "game") \ +// SLIST_FIELD(MOD, "mod") \ +// SLIST_FIELD(MAP, "map") \ +// SLIST_FIELD(NAME, "name") \ +// SLIST_FIELD(MAXPLAYERS, "maxplayers") \ +// SLIST_FIELD(NUMPLAYERS, "numplayers") \ +// SLIST_FIELD(NUMHUMANS, "numhumans") \ +// SLIST_FIELD(NUMBOTS, "numbots") \ +// SLIST_FIELD(PROTOCOL, "protocol") \ +// SLIST_FIELD(FREESLOTS, "freeslots") \ +// SLIST_FIELD(PLAYERS, "players") \ +// SLIST_FIELD(QCSTATUS, "qcstatus") \ +// SLIST_FIELD(CATEGORY, "category") \ +// SLIST_FIELD(ISFAVORITE, "isfavorite") +// +//#define SLIST_FIELD(suffix,name) float SLIST_FIELD_##suffix; +//SLIST_FIELDS +//#undef SLIST_FIELD +// +//const float REFRESHSERVERLIST_RESORT = 0; // sort the server list again to update for changes to e.g. favorite status, categories +//const float REFRESHSERVERLIST_REFILTER = 1; // ..., also update filter and sort criteria +//const float REFRESHSERVERLIST_ASK = 2; // ..., also suggest querying servers now +//const float REFRESHSERVERLIST_RESET = 3; // ..., also clear the list first +// +//// function declarations +//float IsServerInList(string list, string srv); +//#define IsFavorite(srv) IsServerInList(cvar_string("net_slist_favorites"), srv) +//#define IsPromoted(srv) IsServerInList(_Nex_ExtResponseSystem_PromotedServers, srv) +//#define IsRecommended(srv) IsServerInList(_Nex_ExtResponseSystem_RecommendedServers, srv) +// +//entity RetrieveCategoryEnt(float catnum); +// +//float CheckCategoryOverride(float cat); +//float CheckCategoryForEntry(float entry); +//float m_gethostcachecategory(float entry) { return CheckCategoryOverride(CheckCategoryForEntry(entry)); } +// +//void RegisterSLCategories(); +// +//void PrivateServerList_Connect_Click(entity btn, entity me); +//void PrivateServerList_Categories_Click(entity box, entity me); +//void PrivateServerList_ShowEmpty_Click(entity box, entity me); +//void PrivateServerList_ShowFull_Click(entity box, entity me); +//void PrivateServerList_Filter_Change(entity box, entity me); +//void PrivateServerList_Favorite_Click(entity btn, entity me); +//void PrivateServerList_Info_Click(entity btn, entity me); +//void PrivateServerList_Update_favoriteButton(entity btn, entity me); +// +//// fields for category entities +//const int MAX_CATEGORIES = 9; +//const int CATEGORY_FIRST = 1; +//entity categories[MAX_CATEGORIES]; +//int category_ent_count; +//.string cat_name; +//.string cat_string; +//.string cat_enoverride_string; +//.string cat_dioverride_string; +//.float cat_enoverride; +//.float cat_dioverride; +// +//// fields for drawing categories +//int category_name[MAX_CATEGORIES]; +//int category_item[MAX_CATEGORIES]; +//int category_draw_count; +// +//#define SLIST_CATEGORIES \ +// SLIST_CATEGORY(CAT_FAVORITED, "", "", ZCTX(_("SLCAT^Favorites"))) \ +// SLIST_CATEGORY(CAT_RECOMMENDED, "", "", ZCTX(_("SLCAT^Recommended"))) \ +// SLIST_CATEGORY(CAT_NORMAL, "", "CAT_SERVERS", ZCTX(_("SLCAT^Normal Servers"))) \ +// SLIST_CATEGORY(CAT_SERVERS, "CAT_NORMAL", "CAT_SERVERS", ZCTX(_("SLCAT^Servers"))) \ +// SLIST_CATEGORY(CAT_XPM, "CAT_NORMAL", "CAT_SERVERS", ZCTX(_("SLCAT^Competitive Mode"))) \ +// SLIST_CATEGORY(CAT_MODIFIED, "", "CAT_SERVERS", ZCTX(_("SLCAT^Modified Servers"))) \ +// SLIST_CATEGORY(CAT_OVERKILL, "", "CAT_SERVERS", ZCTX(_("SLCAT^Overkill Mode"))) \ +// SLIST_CATEGORY(CAT_INSTAGIB, "", "CAT_SERVERS", ZCTX(_("SLCAT^InstaGib Mode"))) \ +// SLIST_CATEGORY(CAT_DEFRAG, "", "CAT_SERVERS", ZCTX(_("SLCAT^Defrag Mode"))) +// +//#define SLIST_CATEGORY_AUTOCVAR(name) autocvar_menu_slist_categories_##name##_override +//#define SLIST_CATEGORY(name,enoverride,dioverride,str) \ +// int name; \ +// string SLIST_CATEGORY_AUTOCVAR(name) = enoverride; +//SLIST_CATEGORIES +//#undef SLIST_CATEGORY +// +//#endif +//#endif +//#ifdef IMPLEMENTATION +// +//void RegisterSLCategories() +//{ +// entity cat; +// #define SLIST_CATEGORY(name,enoverride,dioverride,str) \ +// SET_FIELD_COUNT(name, CATEGORY_FIRST, category_ent_count) \ +// CHECK_MAX_COUNT(name, MAX_CATEGORIES, category_ent_count, "SLIST_CATEGORY") \ +// cat = spawn(); \ +// categories[name - 1] = cat; \ +// cat.classname = "slist_category"; \ +// cat.cat_name = strzone(#name); \ +// cat.cat_enoverride_string = strzone(SLIST_CATEGORY_AUTOCVAR(name)); \ +// cat.cat_dioverride_string = strzone(dioverride); \ +// cat.cat_string = strzone(str); +// SLIST_CATEGORIES +// #undef SLIST_CATEGORY +// +// int i, x, catnum; +// string s; +// +// #define PROCESS_OVERRIDE(override_string,override_field) \ +// for(i = 0; i < category_ent_count; ++i) \ +// { \ +// s = categories[i].override_string; \ +// if((s != "") && (s != categories[i].cat_name)) \ +// { \ +// catnum = 0; \ +// for(x = 0; x < category_ent_count; ++x) \ +// { if(categories[x].cat_name == s) { \ +// catnum = (x+1); \ +// break; \ +// } } \ +// if(catnum) \ +// { \ +// strunzone(categories[i].override_string); \ +// categories[i].override_field = catnum; \ +// continue; \ +// } \ +// else \ +// { \ +// printf( \ +// "RegisterSLCategories(): Improper override '%s' for category '%s'!\n", \ +// s, \ +// categories[i].cat_name \ +// ); \ +// } \ +// } \ +// strunzone(categories[i].override_string); \ +// categories[i].override_field = 0; \ +// } +// PROCESS_OVERRIDE(cat_enoverride_string, cat_enoverride) +// PROCESS_OVERRIDE(cat_dioverride_string, cat_dioverride) +// #undef PROCESS_OVERRIDE +//} +// +//// Supporting Functions +//entity RetrieveCategoryEnt(int catnum) +//{ +// if((catnum > 0) && (catnum <= category_ent_count)) +// { +// return categories[catnum - 1]; +// } +// else +// { +// error(sprintf("RetrieveCategoryEnt(%d): Improper category number!\n", catnum)); +// return world; +// } +//} +// +//bool IsServerInList(string list, string srv) +//{ +// string p; +// int i, n; +// if(srv == "") +// return false; +// srv = netaddress_resolve(srv, 26000); +// if(srv == "") +// return false; +// p = crypto_getidfp(srv); +// n = tokenize_console(list); +// for(i = 0; i < n; ++i) +// { +// if(substring(argv(i), 0, 1) != "[" && strlen(argv(i)) == 44 && strstrofs(argv(i), ".", 0) < 0) +// { +// if(p) +// if(argv(i) == p) +// return true; +// } +// else +// { +// if(srv == netaddress_resolve(argv(i), 26000)) +// return true; +// } +// } +// return false; +//} +// +//int CheckCategoryOverride(int cat) +//{ +// entity catent = RetrieveCategoryEnt(cat); +// if(catent) +// { +// int override = (autocvar_menu_slist_categories ? catent.cat_enoverride : catent.cat_dioverride); +// if(override) { return override; } +// else { return cat; } +// } +// else +// { +// error(sprintf("CheckCategoryOverride(%d): Improper category number!\n", cat)); +// return cat; +// } +//} +// +//int CheckCategoryForEntry(int entry) +//{ +// string s, k, v, modtype = ""; +// int j, m, impure = 0, freeslots = 0, sflags = 0; +// s = gethostcachestring(SLIST_FIELD_QCSTATUS, entry); +// m = tokenizebyseparator(s, ":"); +// +// for(j = 2; j < m; ++j) +// { +// if(argv(j) == "") { break; } +// k = substring(argv(j), 0, 1); +// v = substring(argv(j), 1, -1); +// switch(k) +// { +// case "P": { impure = stof(v); break; } +// case "S": { freeslots = stof(v); break; } +// case "F": { sflags = stof(v); break; } +// case "M": { modtype = strtolower(v); break; } +// } +// } +// +// if(modtype != "xonotic") { impure += autocvar_menu_slist_modimpurity; } +// +// // check if this server is favorited +// if(gethostcachenumber(SLIST_FIELD_ISFAVORITE, entry)) { return CAT_FAVORITED; } +// +// // now check if it's recommended +// if(autocvar_menu_slist_recommendations) +// { +// string cname = gethostcachestring(SLIST_FIELD_CNAME, entry); +// +// if(IsPromoted(cname)) { return CAT_RECOMMENDED; } +// else +// { +// float recommended = 0; +// if(autocvar_menu_slist_recommendations & 1) +// { +// if(IsRecommended(cname)) { ++recommended; } +// else { --recommended; } +// } +// if(autocvar_menu_slist_recommendations & 2) +// { +// if( +// ///// check for minimum free slots +// (freeslots >= autocvar_menu_slist_recommendations_minfreeslots) +// +// && // check for purity requirement +// ( +// (autocvar_menu_slist_recommendations_purethreshold < 0) +// || +// (impure <= autocvar_menu_slist_recommendations_purethreshold) +// ) +// +// && // check for minimum amount of humans +// ( +// gethostcachenumber(SLIST_FIELD_NUMHUMANS, entry) +// >= +// autocvar_menu_slist_recommendations_minhumans +// ) +// +// && // check for maximum latency +// ( +// gethostcachenumber(SLIST_FIELD_PING, entry) +// <= +// autocvar_menu_slist_recommendations_maxping +// ) +// ) +// { ++recommended; } +// else +// { --recommended; } +// } +// if(recommended > 0) { return CAT_RECOMMENDED; } +// } +// } +// +// // if not favorited or recommended, check modname +// if(modtype != "xonotic") +// { +// switch(modtype) +// { +// // old servers which don't report their mod name are considered modified now +// case "": { return CAT_MODIFIED; } +// +// case "xpm": { return CAT_XPM; } +// case "minstagib": +// case "instagib": { return CAT_INSTAGIB; } +// case "overkill": { return CAT_OVERKILL; } +// //case "nix": { return CAT_NIX; } +// //case "newtoys": { return CAT_NEWTOYS; } +// +// // "cts" is allowed as compat, xdf is replacement +// case "cts": +// case "xdf": { return CAT_DEFRAG; } +// +// default: { dprintf("Found strange mod type: %s\n", modtype); return CAT_MODIFIED; } +// } +// } +// +// // must be normal or impure server +// return ((impure > autocvar_menu_slist_purethreshold) ? CAT_MODIFIED : CAT_NORMAL); +//} +// +//void XonoticPrivateServerList_toggleFavorite(entity me, string srv) +//{ +// string s, s0, s1, s2, srv_resolved, p; +// int i, n; +// bool f = false; +// srv_resolved = netaddress_resolve(srv, 26000); +// p = crypto_getidfp(srv_resolved); +// s = cvar_string("net_slist_favorites"); +// n = tokenize_console(s); +// for(i = 0; i < n; ++i) +// { +// if(substring(argv(i), 0, 1) != "[" && strlen(argv(i)) == 44 && strstrofs(argv(i), ".", 0) < 0) +// { +// if(p) +// if(argv(i) != p) +// continue; +// } +// else +// { +// if(srv_resolved != netaddress_resolve(argv(i), 26000)) +// continue; +// } +// s0 = s1 = s2 = ""; +// if(i > 0) +// s0 = substring(s, 0, argv_end_index(i - 1)); +// if(i < n-1) +// s2 = substring(s, argv_start_index(i + 1), -1); +// if(s0 != "" && s2 != "") +// s1 = " "; +// cvar_set("net_slist_favorites", strcat(s0, s1, s2)); +// s = cvar_string("net_slist_favorites"); +// n = tokenize_console(s); +// f = true; +// --i; +// } +// +// if(!f) +// { +// s1 = ""; +// if(s != "") +// s1 = " "; +// if(p) +// cvar_set("net_slist_favorites", strcat(s, s1, p)); +// else +// cvar_set("net_slist_favorites", strcat(s, s1, srv)); +// } +// +// me.refreshPrivateServerList(me, REFRESHSERVERLIST_RESORT); +//} +// +//void PrivateServerList_Update_favoriteButton(entity btn, entity me) +//{ +// me.favoriteButton.setText(me.favoriteButton, +// (IsFavorite(me.ipAddressBox.text) ? +// _("Remove") : _("Favorite") +// ) +// ); +//} +// +//entity makeXonoticPrivateServerList() +//{ +// entity me; +// me = NEW(XonoticPrivateServerList); +// me.configureXonoticPrivateServerList(me); +// return me; +//} +//void XonoticPrivateServerList_configureXonoticPrivateServerList(entity me) +//{ +// me.configureXonoticListBox(me); +// +// // update field ID's +// #define SLIST_FIELD(suffix,name) SLIST_FIELD_##suffix = gethostcacheindexforkey(name); +// SLIST_FIELDS +// #undef SLIST_FIELD +// +// // clear list +// me.nItems = 0; +//} +//void XonoticPrivateServerList_setSelected(entity me, int i) +//{ +// //int save = me.selectedItem; +// SUPER(XonoticPrivateServerList).setSelected(me, i); +// /* +// if(me.selectedItem == save) +// return; +// */ +// if(me.nItems == 0) +// return; +// if(gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT) != me.nItems) +// return; // sorry, it would be wrong +// +// if(me.selectedServer) +// strunzone(me.selectedServer); +// me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem)); +// +// me.ipAddressBox.setText(me.ipAddressBox, me.selectedServer); +// me.ipAddressBox.cursorPos = strlen(me.selectedServer); +// me.ipAddressBoxFocused = -1; +//} +//void XonoticPrivateServerList_refreshPrivateServerList(entity me, int mode) +//{ +// //print("refresh of type ", ftos(mode), "\n"); +// +// if(mode >= REFRESHSERVERLIST_REFILTER) +// { +// float m; +// int i, n; +// int listflags = 0; +// string s, typestr, modstr; +// +// s = me.filterString; +// +// m = strstrofs(s, ":", 0); +// if(m >= 0) +// { +// typestr = substring(s, 0, m); +// s = substring(s, m + 1, strlen(s) - m - 1); +// while(substring(s, 0, 1) == " ") +// s = substring(s, 1, strlen(s) - 1); +// } +// else +// typestr = ""; +// +// modstr = cvar_string("menu_slist_modfilter"); +// +// m = SLIST_MASK_AND - 1; +// resethostcachemasks(); +// +// // ping: reject negative ping (no idea why this happens in the first place, engine bug) +// sethostcachemasknumber(++m, SLIST_FIELD_PING, 0, SLIST_TEST_GREATEREQUAL); +// +// // show full button +// if(!me.filterShowFull) +// { +// sethostcachemasknumber(++m, SLIST_FIELD_FREESLOTS, 1, SLIST_TEST_GREATEREQUAL); // legacy +// sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, ":S0:", SLIST_TEST_NOTCONTAIN); // g_maxplayers support +// } +// +// // show empty button +// if(!me.filterShowEmpty) +// sethostcachemasknumber(++m, SLIST_FIELD_NUMHUMANS, 1, SLIST_TEST_GREATEREQUAL); +// +// // gametype filtering +// if(typestr != "") +// sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(typestr, ":"), SLIST_TEST_STARTSWITH); +// +// // mod filtering +// if(modstr != "") +// { +// if(substring(modstr, 0, 1) == "!") +// sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(substring(modstr, 1, strlen(modstr) - 1)), SLIST_TEST_NOTEQUAL); +// else +// sethostcachemaskstring(++m, SLIST_FIELD_MOD, resolvemod(modstr), SLIST_TEST_EQUAL); +// } +// +// // server banning +// n = tokenizebyseparator(_Nex_ExtResponseSystem_BannedServers, " "); +// for(i = 0; i < n; ++i) +// if(argv(i) != "") +// sethostcachemaskstring(++m, SLIST_FIELD_CNAME, argv(i), SLIST_TEST_NOTSTARTSWITH); +// +// m = SLIST_MASK_OR - 1; +// if(s != "") +// { +// sethostcachemaskstring(++m, SLIST_FIELD_NAME, s, SLIST_TEST_CONTAINS); +// sethostcachemaskstring(++m, SLIST_FIELD_MAP, s, SLIST_TEST_CONTAINS); +// sethostcachemaskstring(++m, SLIST_FIELD_PLAYERS, s, SLIST_TEST_CONTAINS); +// sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(s, ":"), SLIST_TEST_STARTSWITH); +// } +// +// // sorting flags +// //listflags |= SLSF_FAVORITES; +// listflags |= SLSF_CATEGORIES; +// if(me.currentSortOrder < 0) { listflags |= SLSF_DESCENDING; } +// sethostcachesort(me.currentSortField, listflags); +// } +// +// resorthostcache(); +// if(mode >= REFRESHSERVERLIST_ASK) +// refreshhostcache(mode >= REFRESHSERVERLIST_RESET); +//} +//void XonoticPrivateServerList_focusEnter(entity me) +//{ +// SUPER(XonoticPrivateServerList).focusEnter(me); +// if(time < me.nextRefreshTime) +// { +// //print("sorry, no refresh yet\n"); +// return; +// } +// me.nextRefreshTime = time + 10; +// me.refreshPrivateServerList(me, REFRESHSERVERLIST_ASK); +//} +// +//void XonoticPrivateServerList_draw(entity me) +//{ +// int i; +// bool found = false, owned; +// +// if(_Nex_ExtResponseSystem_BannedServersNeedsRefresh) +// { +// if(!me.needsRefresh) +// me.needsRefresh = 2; +// _Nex_ExtResponseSystem_BannedServersNeedsRefresh = 0; +// } +// +// if(_Nex_ExtResponseSystem_PromotedServersNeedsRefresh) +// { +// if(!me.needsRefresh) +// me.needsRefresh = 3; +// _Nex_ExtResponseSystem_PromotedServersNeedsRefresh = 0; +// } +// +// if(_Nex_ExtResponseSystem_RecommendedServersNeedsRefresh) +// { +// if(!me.needsRefresh) +// me.needsRefresh = 3; +// _Nex_ExtResponseSystem_RecommendedServersNeedsRefresh = 0; +// } +// +// if(me.currentSortField == -1) +// { +// me.setSortOrder(me, SLIST_FIELD_PING, +1); +// me.refreshPrivateServerList(me, REFRESHSERVERLIST_RESET); +// } +// else if(me.needsRefresh == 1) +// { +// me.needsRefresh = 2; // delay by one frame to make sure "slist" has been executed +// } +// else if(me.needsRefresh == 2) +// { +// me.needsRefresh = 0; +// me.refreshPrivateServerList(me, REFRESHSERVERLIST_REFILTER); +// } +// else if(me.needsRefresh == 3) +// { +// me.needsRefresh = 0; +// me.refreshPrivateServerList(me, REFRESHSERVERLIST_RESORT); +// } +// +// owned = ((me.selectedServer == me.ipAddressBox.text) && (me.ipAddressBox.text != "")); +// +// for(i = 0; i < category_draw_count; ++i) { category_name[i] = -1; category_item[i] = -1; } +// category_draw_count = 0; +// +// if(autocvar_menu_slist_categories >= 0) // if less than 0, don't even draw a category heading for favorites +// { +// float itemcount = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT); +// me.nItems = itemcount; +// +// //float visible = floor(me.scrollPos / me.itemHeight); +// // ^ unfortunately no such optimization can be made-- we must process through the +// // entire list, otherwise there is no way to know which item is first in its category. +// +// // binary search method suggested by div +// float x; +// float begin = 0; +// for(x = 1; x <= category_ent_count; ++x) { +// float first = begin; +// float last = (itemcount - 1); +// if (first > last) { +// // List is empty. +// break; +// } +// float catf = gethostcachenumber(SLIST_FIELD_CATEGORY, first); +// float catl = gethostcachenumber(SLIST_FIELD_CATEGORY, last); +// if (catf > x) { +// // The first one is already > x. +// // Therefore, category x does not exist. +// // Higher numbered categories do exist though. +// } else if (catl < x) { +// // The last one is < x. +// // Thus this category - and any following - +// // don't exist. +// break; +// } else if (catf == x) { +// // Starts at first. This breaks the loop +// // invariant in the binary search and thus has +// // to be handled separately. +// if(gethostcachenumber(SLIST_FIELD_CATEGORY, first) != x) +// error("Category mismatch I"); +// if(first > 0) +// if(gethostcachenumber(SLIST_FIELD_CATEGORY, first - 1) == x) +// error("Category mismatch II"); +// category_name[category_draw_count] = x; +// category_item[category_draw_count] = first; +// ++category_draw_count; +// begin = first + 1; +// } else { +// // At this point, catf <= x < catl, thus +// // catf < catl, thus first < last. +// // INVARIANTS: +// // last - first >= 1 +// // catf == gethostcachenumber(SLIST_FIELD_CATEGORY(first) +// // catl == gethostcachenumber(SLIST_FIELD_CATEGORY(last) +// // catf < x +// // catl >= x +// while (last - first > 1) { +// float middle = floor((first + last) / 2); +// // By loop condition, middle != first && middle != last. +// float cat = gethostcachenumber(SLIST_FIELD_CATEGORY, middle); +// if (cat >= x) { +// last = middle; +// catl = cat; +// } else { +// first = middle; +// catf = cat; +// } +// } +// if (catl == x) { +// if(gethostcachenumber(SLIST_FIELD_CATEGORY, last) != x) +// error("Category mismatch III"); +// if(last > 0) +// if(gethostcachenumber(SLIST_FIELD_CATEGORY, last - 1) == x) +// error("Category mismatch IV"); +// category_name[category_draw_count] = x; +// category_item[category_draw_count] = last; +// ++category_draw_count; +// begin = last + 1; // already scanned through these, skip 'em +// } +// else +// begin = last; // already scanned through these, skip 'em +// } +// } +// if(autocvar_menu_slist_categories_onlyifmultiple && (category_draw_count == 1)) +// { +// category_name[0] = -1; +// category_item[0] = -1; +// category_draw_count = 0; +// me.nItems = itemcount; +// } +// } +// else { me.nItems = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT); } +// +// me.connectButton.disabled = ((me.nItems == 0) && (me.ipAddressBox.text == "")); +// me.infoButton.disabled = ((me.nItems == 0) || !owned); +// me.favoriteButton.disabled = ((me.nItems == 0) && (me.ipAddressBox.text == "")); +// +// if(me.selectedServer) +// { +// for(i = 0; i < me.nItems; ++i) +// { +// if(gethostcachestring(SLIST_FIELD_CNAME, i) == me.selectedServer) +// { +// me.selectedItem = i; +// found = true; +// break; +// } +// } +// } +// if(!found) +// { +// if(me.nItems > 0) +// { +// if(me.selectedItem >= me.nItems) +// me.selectedItem = me.nItems - 1; +// if(me.selectedServer) +// strunzone(me.selectedServer); +// me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem)); +// } +// } +// +// if(owned) +// { +// if(me.selectedServer != me.ipAddressBox.text) +// { +// me.ipAddressBox.setText(me.ipAddressBox, me.selectedServer); +// me.ipAddressBox.cursorPos = strlen(me.selectedServer); +// me.ipAddressBoxFocused = -1; +// } +// } +// +// if(me.ipAddressBoxFocused != me.ipAddressBox.focused) +// { +// if(me.ipAddressBox.focused || me.ipAddressBoxFocused < 0) +// PrivateServerList_Update_favoriteButton(NULL, me); +// me.ipAddressBoxFocused = me.ipAddressBox.focused; +// } +// +// SUPER(XonoticPrivateServerList).draw(me); +//} +//void PrivateServerList_PingSort_Click(entity btn, entity me) +//{ +// me.setSortOrder(me, SLIST_FIELD_PING, +1); +//} +//void PrivateServerList_NameSort_Click(entity btn, entity me) +//{ +// me.setSortOrder(me, SLIST_FIELD_NAME, -1); // why? +//} +//void PrivateServerList_MapSort_Click(entity btn, entity me) +//{ +// me.setSortOrder(me, SLIST_FIELD_MAP, -1); // why? +//} +//void PrivateServerList_PlayerSort_Click(entity btn, entity me) +//{ +// me.setSortOrder(me, SLIST_FIELD_NUMHUMANS, -1); +//} +//void PrivateServerList_TypeSort_Click(entity btn, entity me) +//{ +// string s, t; +// float i, m; +// s = me.filterString; +// m = strstrofs(s, ":", 0); +// if(m >= 0) +// { +// s = substring(s, 0, m); +// while(substring(s, m+1, 1) == " ") // skip spaces +// ++m; +// } +// else +// s = ""; +// +// for(i = 1; ; i *= 2) // 20 modes ought to be enough for anyone +// { +// t = MapInfo_Type_ToString(i); +// if(i > 1) +// if(t == "") // it repeats (default case) +// { +// // no type was found +// // choose the first one +// s = MapInfo_Type_ToString(1); +// break; +// } +// if(s == t) +// { +// // the type was found +// // choose the next one +// s = MapInfo_Type_ToString(i * 2); +// if(s == "") +// s = MapInfo_Type_ToString(1); +// break; +// } +// } +// +// if(s != "") +// s = strcat(s, ":"); +// s = strcat(s, substring(me.filterString, m+1, strlen(me.filterString) - m - 1)); +// +// me.controlledTextbox.setText(me.controlledTextbox, s); +// me.controlledTextbox.keyDown(me.controlledTextbox, K_END, 0, 0); +// me.controlledTextbox.keyUp(me.controlledTextbox, K_END, 0, 0); +// //PrivateServerList_Filter_Change(me.controlledTextbox, me); +//} +//void PrivateServerList_Filter_Change(entity box, entity me) +//{ +// if(me.filterString) +// strunzone(me.filterString); +// if(box.text != "") +// me.filterString = strzone(box.text); +// else +// me.filterString = string_null; +// me.refreshPrivateServerList(me, REFRESHSERVERLIST_REFILTER); +// +// me.ipAddressBox.setText(me.ipAddressBox, ""); +// me.ipAddressBox.cursorPos = 0; +// me.ipAddressBoxFocused = -1; +//} +//void PrivateServerList_Categories_Click(entity box, entity me) +//{ +// box.setChecked(box, autocvar_menu_slist_categories = !autocvar_menu_slist_categories); +// me.refreshPrivateServerList(me, REFRESHSERVERLIST_RESORT); +// +// me.ipAddressBox.setText(me.ipAddressBox, ""); +// me.ipAddressBox.cursorPos = 0; +// me.ipAddressBoxFocused = -1; +//} +//void PrivateServerList_ShowEmpty_Click(entity box, entity me) +//{ +// box.setChecked(box, me.filterShowEmpty = !me.filterShowEmpty); +// me.refreshPrivateServerList(me, REFRESHSERVERLIST_REFILTER); +// +// me.ipAddressBox.setText(me.ipAddressBox, ""); +// me.ipAddressBox.cursorPos = 0; +// me.ipAddressBoxFocused = -1; +//} +//void PrivateServerList_ShowFull_Click(entity box, entity me) +//{ +// box.setChecked(box, me.filterShowFull = !me.filterShowFull); +// me.refreshPrivateServerList(me, REFRESHSERVERLIST_REFILTER); +// +// me.ipAddressBox.setText(me.ipAddressBox, ""); +// me.ipAddressBox.cursorPos = 0; +// me.ipAddressBoxFocused = -1; +//} +//void XonoticPrivateServerList_setSortOrder(entity me, int fld, int direction) +//{ +// if(me.currentSortField == fld) +// direction = -me.currentSortOrder; +// me.currentSortOrder = direction; +// me.currentSortField = fld; +// me.sortButton1.forcePressed = (fld == SLIST_FIELD_PING); +// me.sortButton2.forcePressed = (fld == SLIST_FIELD_NAME); +// me.sortButton3.forcePressed = (fld == SLIST_FIELD_MAP); +// me.sortButton4.forcePressed = 0; +// me.sortButton5.forcePressed = (fld == SLIST_FIELD_NUMHUMANS); +// me.selectedItem = 0; +// if(me.selectedServer) +// strunzone(me.selectedServer); +// me.selectedServer = string_null; +// me.refreshPrivateServerList(me, REFRESHSERVERLIST_REFILTER); +//} +//void XonoticPrivateServerList_positionSortButton(entity me, entity btn, float theOrigin, float theSize, string theTitle, void(entity, entity) theFunc) +//{ +// vector originInLBSpace, sizeInLBSpace; +// originInLBSpace = eY * (-me.itemHeight); +// sizeInLBSpace = eY * me.itemHeight + eX * (1 - me.controlWidth); +// +// vector originInDialogSpace, sizeInDialogSpace; +// originInDialogSpace = boxToGlobal(originInLBSpace, me.Container_origin, me.Container_size); +// sizeInDialogSpace = boxToGlobalSize(sizeInLBSpace, me.Container_size); +// +// btn.Container_origin_x = originInDialogSpace.x + sizeInDialogSpace.x * theOrigin; +// btn.Container_size_x = sizeInDialogSpace.x * theSize; +// btn.setText(btn, theTitle); +// btn.onClick = theFunc; +// btn.onClickEntity = me; +// btn.resized = 1; +//} +//void XonoticPrivateServerList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +//{ +// SUPER(XonoticPrivateServerList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize); +// +// me.realFontSize_y = me.fontSize / (absSize.y * me.itemHeight); +// me.realFontSize_x = me.fontSize / (absSize.x * (1 - me.controlWidth)); +// me.realUpperMargin = 0.5 * (1 - me.realFontSize.y); +// +// me.columnIconsOrigin = 0; +// me.columnIconsSize = me.realFontSize.x * 4 * me.iconsSizeFactor; +// me.columnPingSize = me.realFontSize.x * 3; +// me.columnMapSize = me.realFontSize.x * 10; +// me.columnTypeSize = me.realFontSize.x * 4; +// me.columnPlayersSize = me.realFontSize.x * 5; +// me.columnNameSize = 1 - me.columnPlayersSize - me.columnMapSize - me.columnPingSize - me.columnIconsSize - me.columnTypeSize - 5 * me.realFontSize.x; +// me.columnPingOrigin = me.columnIconsOrigin + me.columnIconsSize + me.realFontSize.x; +// me.columnNameOrigin = me.columnPingOrigin + me.columnPingSize + me.realFontSize.x; +// me.columnMapOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize.x; +// me.columnTypeOrigin = me.columnMapOrigin + me.columnMapSize + me.realFontSize.x; +// me.columnPlayersOrigin = me.columnTypeOrigin + me.columnTypeSize + me.realFontSize.x; +// +// me.positionSortButton(me, me.sortButton1, me.columnPingOrigin, me.columnPingSize, _("Ping"), PrivateServerList_PingSort_Click); +// me.positionSortButton(me, me.sortButton2, me.columnNameOrigin, me.columnNameSize, _("Host name"), PrivateServerList_NameSort_Click); +// me.positionSortButton(me, me.sortButton3, me.columnMapOrigin, me.columnMapSize, _("Map"), PrivateServerList_MapSort_Click); +// me.positionSortButton(me, me.sortButton4, me.columnTypeOrigin, me.columnTypeSize, _("Type"), PrivateServerList_TypeSort_Click); +// me.positionSortButton(me, me.sortButton5, me.columnPlayersOrigin, me.columnPlayersSize, _("Players"), PrivateServerList_PlayerSort_Click); +// +// int f = me.currentSortField; +// if(f >= 0) +// { +// me.currentSortField = -1; +// me.setSortOrder(me, f, me.currentSortOrder); // force resetting the sort order +// } +//} +//void PrivateServerList_Connect_Click(entity btn, entity me) +//{ +// localcmd(sprintf("connect %s\n", +// ((me.ipAddressBox.text != "") ? +// me.ipAddressBox.text : me.selectedServer +// ) +// )); +//} +//void PrivateServerList_Favorite_Click(entity btn, entity me) +//{ +// string ipstr; +// ipstr = netaddress_resolve(me.ipAddressBox.text, 26000); +// if(ipstr != "") +// { +// m_play_click_sound(MENU_SOUND_SELECT); +// me.toggleFavorite(me, me.ipAddressBox.text); +// me.ipAddressBoxFocused = -1; +// } +//} +//void PrivateServerList_Info_Click(entity btn, entity me) +//{ +// if (me.nItems != 0) +// main.serverInfoDialog.loadServerInfo(main.serverInfoDialog, me.selectedItem); +// +// vector org = boxToGlobal(eY * (me.selectedItem * me.itemHeight - me.scrollPos), me.origin, me.size); +// vector sz = boxToGlobalSize(eY * me.itemHeight + eX * (1 - me.controlWidth), me.size); +// DialogOpenButton_Click_withCoords(me, main.serverInfoDialog, org, sz); +//} +//void XonoticPrivateServerList_doubleClickListBoxItem(entity me, int i, vector where) +//{ +// PrivateServerList_Connect_Click(NULL, me); +//} +//void XonoticPrivateServerList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected) +//{ +// // layout: Ping, Server name, Map name, NP, TP, MP +// float p; +// int q; +// bool isv4, isv6; +// vector theColor; +// float theAlpha; +// bool pure = false; +// int freeslots = -1, sflags = -1, j, m; +// string s, typestr, versionstr, k, v, modname; +// +// //printf("time: %f, i: %d, item: %d, nitems: %d\n", time, i, item, me.nItems); +// +// vector oldscale = draw_scale; +// vector oldshift = draw_shift; +//#ifndef SET_YRANGE +//#define SET_YRANGE(start,end) \ +// draw_scale = boxToGlobalSize(eX * 1 + eY * (end - start), oldscale); \ +// draw_shift = boxToGlobal(eY * start, oldshift, oldscale); +//#endif +// +// for (j = 0; j < category_draw_count; ++j) { +// // Matches exactly the headings with increased height. +// if (i == category_item[j]) +// break; +// } +// +// if (j < category_draw_count) +// { +// entity catent = RetrieveCategoryEnt(category_name[j]); +// if(catent) +// { +// SET_YRANGE( +// (me.categoriesHeight - 1) / (me.categoriesHeight + 1), +// me.categoriesHeight / (me.categoriesHeight + 1) +// ); +// draw_Text( +// eY * me.realUpperMargin +// + +//#if 0 +// eX * (me.columnNameOrigin + (me.columnNameSize - draw_TextWidth(catent.cat_string, 0, me.realFontSize)) * 0.5), +// catent.cat_string, +//#else +// eX * (me.columnNameOrigin), +// strcat(catent.cat_string, ":"), +//#endif +// me.realFontSize, +// SKINCOLOR_SERVERLIST_CATEGORY, +// SKINALPHA_SERVERLIST_CATEGORY, +// 0 +// ); +// SET_YRANGE(me.categoriesHeight / (me.categoriesHeight + 1), 1); +// } +// } +// +// if(isSelected) +// draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED); +// +// s = gethostcachestring(SLIST_FIELD_QCSTATUS, i); +// m = tokenizebyseparator(s, ":"); +// typestr = ""; +// if(m >= 2) +// { +// typestr = argv(0); +// versionstr = argv(1); +// } +// freeslots = -1; +// modname = ""; +// for(j = 2; j < m; ++j) +// { +// if(argv(j) == "") +// break; +// k = substring(argv(j), 0, 1); +// v = substring(argv(j), 1, -1); +// if(k == "P") +// pure = stob(v); +// else if(k == "S") +// freeslots = stof(v); +// else if(k == "F") +// sflags = stoi(v); +// else if(k == "M") +// modname = v; +// } +// +//#ifdef COMPAT_NO_MOD_IS_XONOTIC +// if(modname == "") +// modname = "Xonotic"; +//#endif +// +// /* +// SLIST_FIELD_MOD = gethostcacheindexforkey("mod"); +// s = gethostcachestring(SLIST_FIELD_MOD, i); +// if(s != "data") +// if(modname == "Xonotic") +// modname = s; +// */ +// +// // list the mods here on which the pure server check actually works +// if(modname != "Xonotic") +// if(modname != "InstaGib" || modname != "MinstaGib") +// if(modname != "CTS") +// if(modname != "NIX") +// if(modname != "NewToys") +// pure = false; +// +// if(gethostcachenumber(SLIST_FIELD_FREESLOTS, i) <= 0) +// theAlpha = SKINALPHA_SERVERLIST_FULL; +// else if(freeslots == 0) +// theAlpha = SKINALPHA_SERVERLIST_FULL; // g_maxplayers support +// else if (!gethostcachenumber(SLIST_FIELD_NUMHUMANS, i)) +// theAlpha = SKINALPHA_SERVERLIST_EMPTY; +// else +// theAlpha = 1; +// +// p = gethostcachenumber(SLIST_FIELD_PING, i); +// const int PING_LOW = 75; +// const int PING_MED = 200; +// const int PING_HIGH = 500; +// if(p < PING_LOW) +// theColor = SKINCOLOR_SERVERLIST_LOWPING + (SKINCOLOR_SERVERLIST_MEDPING - SKINCOLOR_SERVERLIST_LOWPING) * (p / PING_LOW); +// else if(p < PING_MED) +// theColor = SKINCOLOR_SERVERLIST_MEDPING + (SKINCOLOR_SERVERLIST_HIGHPING - SKINCOLOR_SERVERLIST_MEDPING) * ((p - PING_LOW) / (PING_MED - PING_LOW)); +// else if(p < PING_HIGH) +// { +// theColor = SKINCOLOR_SERVERLIST_HIGHPING; +// theAlpha *= 1 + (SKINALPHA_SERVERLIST_HIGHPING - 1) * ((p - PING_MED) / (PING_HIGH - PING_MED)); +// } +// else +// { +// theColor = eX; +// theAlpha *= SKINALPHA_SERVERLIST_HIGHPING; +// } +// +// if(gethostcachenumber(SLIST_FIELD_ISFAVORITE, i)) +// { +// theColor = theColor * (1 - SKINALPHA_SERVERLIST_FAVORITE) + SKINCOLOR_SERVERLIST_FAVORITE * SKINALPHA_SERVERLIST_FAVORITE; +// theAlpha = theAlpha * (1 - SKINALPHA_SERVERLIST_FAVORITE) + SKINALPHA_SERVERLIST_FAVORITE; +// } +// +// s = gethostcachestring(SLIST_FIELD_CNAME, i); +// +// isv4 = isv6 = false; +// if(substring(s, 0, 1) == "[") +// { +// isv6 = true; +// me.seenIPv6 += 1; +// } +// else if(strstrofs("0123456789", substring(s, 0, 1), 0) >= 0) +// { +// isv4 = true; +// me.seenIPv4 += 1; +// } +// +// q = stof(substring(crypto_getencryptlevel(s), 0, 1)); +// if((q <= 0 && cvar("crypto_aeslevel") >= 3) || (q >= 3 && cvar("crypto_aeslevel") <= 0)) +// { +// theColor = SKINCOLOR_SERVERLIST_IMPOSSIBLE; +// theAlpha = SKINALPHA_SERVERLIST_IMPOSSIBLE; +// } +// +// if(q == 1) +// { +// if(cvar("crypto_aeslevel") >= 2) +// q |= 4; +// } +// if(q == 2) +// { +// if(cvar("crypto_aeslevel") >= 1) +// q |= 4; +// } +// if(q == 3) +// q = 5; +// else if(q >= 3) +// q -= 2; +// // possible status: +// // 0: crypto off +// // 1: AES possible +// // 2: AES recommended but not available +// // 3: AES possible and will be used +// // 4: AES recommended and will be used +// // 5: AES required +// +// // -------------- +// // RENDER ICONS +// // -------------- +// vector iconSize = '0 0 0'; +// iconSize_y = me.realFontSize.y * me.iconsSizeFactor; +// iconSize_x = me.realFontSize.x * me.iconsSizeFactor; +// +// vector iconPos = '0 0 0'; +// iconPos_x = (me.columnIconsSize - 3 * iconSize.x) * 0.5; +// iconPos_y = (1 - iconSize.y) * 0.5; +// +// string n; +// +// if (!(me.seenIPv4 && me.seenIPv6)) +// { +// iconPos.x += iconSize.x * 0.5; +// } +// else if(me.seenIPv4 && me.seenIPv6) +// { +// n = string_null; +// if(isv6) +// draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_ipv6"), 0); // PRECACHE_PIC_MIPMAP +// else if(isv4) +// draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_ipv4"), 0); // PRECACHE_PIC_MIPMAP +// if(n) +// draw_Picture(iconPos, n, iconSize, '1 1 1', 1); +// iconPos.x += iconSize.x; +// } +// +// if(q > 0) +// { +// draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_aeslevel", ftos(q)), 0); // PRECACHE_PIC_MIPMAP +// draw_Picture(iconPos, n, iconSize, '1 1 1', 1); +// } +// iconPos.x += iconSize.x; +// +// if(modname == "Xonotic") +// { +// if(pure == 0) +// { +// draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_pure1"), PRECACHE_PIC_MIPMAP); +// draw_Picture(iconPos, n, iconSize, '1 1 1', 1); +// } +// } +// else +// { +// draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_mod_", modname), PRECACHE_PIC_MIPMAP); +// if(draw_PictureSize(n) == '0 0 0') +// draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_mod_"), PRECACHE_PIC_MIPMAP); +// if(pure == 0) +// draw_Picture(iconPos, n, iconSize, '1 1 1', 1); +// else +// draw_Picture(iconPos, n, iconSize, '1 1 1', SKINALPHA_SERVERLIST_ICON_NONPURE); +// } +// iconPos.x += iconSize.x; +// +// if(sflags >= 0 && (sflags & SERVERFLAG_PLAYERSTATS)) +// { +// draw_PreloadPictureWithFlags(n = strcat(SKINGFX_SERVERLIST_ICON, "_stats1"), 0); // PRECACHE_PIC_MIPMAP +// draw_Picture(iconPos, n, iconSize, '1 1 1', 1); +// } +// iconPos.x += iconSize.x; +// +// // -------------- +// // RENDER TEXT +// // -------------- +// +// // ping +// s = ftos(p); +// draw_Text(me.realUpperMargin * eY + (me.columnPingOrigin + me.columnPingSize - draw_TextWidth(s, 0, me.realFontSize)) * eX, s, me.realFontSize, theColor, theAlpha, 0); +// +// // server name +// s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_NAME, i), me.columnNameSize, 0, me.realFontSize); +// draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0); +// +// // server map +// s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_MAP, i), me.columnMapSize, 0, me.realFontSize); +// draw_Text(me.realUpperMargin * eY + (me.columnMapOrigin + (me.columnMapSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0); +// +// // server gametype +// s = draw_TextShortenToWidth(typestr, me.columnTypeSize, 0, me.realFontSize); +// draw_Text(me.realUpperMargin * eY + (me.columnTypeOrigin + (me.columnTypeSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0); +// +// // server playercount +// s = strcat(ftos(gethostcachenumber(SLIST_FIELD_NUMHUMANS, i)), "/", ftos(gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i))); +// draw_Text(me.realUpperMargin * eY + (me.columnPlayersOrigin + (me.columnPlayersSize - draw_TextWidth(s, 0, me.realFontSize)) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0); +//} +// +//bool XonoticPrivateServerList_keyDown(entity me, int scan, bool ascii, bool shift) +//{ +// vector org, sz; +// +// org = boxToGlobal(eY * (me.selectedItem * me.itemHeight - me.scrollPos), me.origin, me.size); +// sz = boxToGlobalSize(eY * me.itemHeight + eX * (1 - me.controlWidth), me.size); +// +// if(scan == K_ENTER || scan == K_KP_ENTER) +// { +// PrivateServerList_Connect_Click(NULL, me); +// return true; +// } +// else if(scan == K_MOUSE2 || scan == K_SPACE) +// { +// if(me.nItems != 0) +// { +// m_play_click_sound(MENU_SOUND_OPEN); +// main.serverInfoDialog.loadServerInfo(main.serverInfoDialog, me.selectedItem); +// DialogOpenButton_Click_withCoords(me, main.serverInfoDialog, org, sz); +// return true; +// } +// return false; +// } +// else if(scan == K_INS || scan == K_MOUSE3 || scan == K_KP_INS) +// { +// if(me.nItems != 0) +// { +// me.toggleFavorite(me, me.selectedServer); +// me.ipAddressBoxFocused = -1; +// return true; +// } +// return false; +// } +// else if(SUPER(XonoticPrivateServerList).keyDown(me, scan, ascii, shift)) +// return true; +// else if(!me.controlledTextbox) +// return false; +// else +// return me.controlledTextbox.keyDown(me.controlledTextbox, scan, ascii, shift); +//} +// +//float XonoticPrivateServerList_getTotalHeight(entity me) +//{ +// float num_normal_rows = me.nItems; +// int num_headers = category_draw_count; +// return me.itemHeight * (num_normal_rows + me.categoriesHeight * num_headers); +//} +//int XonoticPrivateServerList_getItemAtPos(entity me, float pos) +//{ +// pos = pos / me.itemHeight; +// int i; +// for (i = category_draw_count - 1; i >= 0; --i) { +// int itemidx = category_item[i]; +// float itempos = i * me.categoriesHeight + category_item[i]; +// if (pos >= itempos + me.categoriesHeight + 1) +// return itemidx + 1 + floor(pos - (itempos + me.categoriesHeight + 1)); +// if (pos >= itempos) +// return itemidx; +// } +// // No category matches? Note that category 0 is... 0. Therefore no headings exist at all. +// return floor(pos); +//} +//float XonoticPrivateServerList_getItemStart(entity me, int item) +//{ +// int i; +// for (i = category_draw_count - 1; i >= 0; --i) { +// int itemidx = category_item[i]; +// float itempos = i * me.categoriesHeight + category_item[i]; +// if (item >= itemidx + 1) +// return (itempos + me.categoriesHeight + 1 + item - (itemidx + 1)) * me.itemHeight; +// if (item >= itemidx) +// return itempos * me.itemHeight; +// } +// // No category matches? Note that category 0 is... 0. Therefore no headings exist at all. +// return item * me.itemHeight; +//} +//float XonoticPrivateServerList_getItemHeight(entity me, int item) +//{ +// int i; +// for (i = 0; i < category_draw_count; ++i) { +// // Matches exactly the headings with increased height. +// if (item == category_item[i]) +// return me.itemHeight * (me.categoriesHeight + 1); +// } +// return me.itemHeight; +//} +// +//#endif diff --git a/qcsrc/menu/xonotic/serverlist.qc b/qcsrc/menu/xonotic/serverlist.qc index 3f9648be6..a2996a115 100644 --- a/qcsrc/menu/xonotic/serverlist.qc +++ b/qcsrc/menu/xonotic/serverlist.qc @@ -979,9 +979,11 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is vector oldscale = draw_scale; vector oldshift = draw_shift; +#ifndef SET_YRANGE #define SET_YRANGE(start,end) \ draw_scale = boxToGlobalSize(eX * 1 + eY * (end - start), oldscale); \ draw_shift = boxToGlobal(eY * start, oldshift, oldscale); +#endif for (j = 0; j < category_draw_count; ++j) { // Matches exactly the headings with increased height. -- 2.39.2