2 CLASS(NexuizServerList) EXTENDS(NexuizListBox)
3 METHOD(NexuizServerList, configureNexuizServerList, void(entity))
4 ATTRIB(NexuizServerList, rowsPerItem, float, 1)
5 METHOD(NexuizServerList, draw, void(entity))
6 METHOD(NexuizServerList, drawListBoxItem, void(entity, float, vector, float))
7 METHOD(NexuizServerList, clickListBoxItem, void(entity, float, vector))
8 METHOD(NexuizServerList, resizeNotify, void(entity, vector, vector, vector, vector))
10 ATTRIB(NexuizServerList, realFontSize, vector, '0 0 0')
11 ATTRIB(NexuizServerList, realUpperMargin, float, 0)
12 ATTRIB(NexuizServerList, columnPingOrigin, float, 0)
13 ATTRIB(NexuizServerList, columnPingSize, float, 0)
14 ATTRIB(NexuizServerList, columnNameOrigin, float, 0)
15 ATTRIB(NexuizServerList, columnNameSize, float, 0)
16 ATTRIB(NexuizServerList, columnMapOrigin, float, 0)
17 ATTRIB(NexuizServerList, columnMapSize, float, 0)
18 ATTRIB(NexuizServerList, columnPlayersOrigin, float, 0)
19 ATTRIB(NexuizServerList, columnPlayersSize, float, 0)
21 ATTRIB(NexuizServerList, selectedServer, string, string_null) // to restore selected server when needed
22 METHOD(NexuizServerList, setSelected, void(entity, float))
23 METHOD(NexuizServerList, setSortOrder, void(entity, float, float))
24 ATTRIB(NexuizServerList, filterShowEmpty, float, 1)
25 ATTRIB(NexuizServerList, filterShowFull, float, 1)
26 ATTRIB(NexuizServerList, nextRefreshTime, float, 0)
27 METHOD(NexuizServerList, refreshServerList, void(entity, float)) // refresh mode: 0 = just reparametrize, 1 = send new requests, 2 = clear
28 ATTRIB(NexuizServerList, needsRefresh, float, 1)
29 METHOD(NexuizServerList, focusEnter, void(entity))
30 METHOD(NexuizServerList, positionSortButton, void(entity, entity, float, float, string, void(entity, entity)))
31 ATTRIB(NexuizServerList, sortButton1, entity, NULL)
32 ATTRIB(NexuizServerList, sortButton2, entity, NULL)
33 ATTRIB(NexuizServerList, sortButton3, entity, NULL)
34 ATTRIB(NexuizServerList, sortButton4, entity, NULL)
35 ATTRIB(NexuizServerList, connectButton, entity, NULL)
36 ATTRIB(NexuizServerList, currentSortOrder, float, 0)
37 ATTRIB(NexuizServerList, currentSortField, float, -1)
38 ATTRIB(NexuizServerList, lastClickedServer, float, -1)
39 ATTRIB(NexuizServerList, lastClickedTime, float, 0)
40 ENDCLASS(NexuizServerList)
41 entity makeNexuizServerList();
42 void ServerList_Connect_Click(entity btn, entity me);
43 void ServerList_ShowEmpty_Click(entity box, entity me);
44 void ServerList_ShowFull_Click(entity box, entity me);
48 float SLIST_FIELD_CNAME;
49 float SLIST_FIELD_PING;
50 float SLIST_FIELD_GAME;
51 float SLIST_FIELD_MOD;
52 float SLIST_FIELD_MAP;
53 float SLIST_FIELD_NAME;
54 float SLIST_FIELD_MAXPLAYERS;
55 float SLIST_FIELD_NUMPLAYERS;
56 float SLIST_FIELD_NUMHUMANS;
57 float SLIST_FIELD_NUMBOTS;
58 float SLIST_FIELD_PROTOCOL;
59 float SLIST_FIELD_FREESLOTS;
60 void ServerList_UpdateFieldIDs()
62 SLIST_FIELD_CNAME = gethostcacheindexforkey( "cname" );
63 SLIST_FIELD_PING = gethostcacheindexforkey( "ping" );
64 SLIST_FIELD_GAME = gethostcacheindexforkey( "game" );
65 SLIST_FIELD_MOD = gethostcacheindexforkey( "mod" );
66 SLIST_FIELD_MAP = gethostcacheindexforkey( "map" );
67 SLIST_FIELD_NAME = gethostcacheindexforkey( "name" );
68 SLIST_FIELD_MAXPLAYERS = gethostcacheindexforkey( "maxplayers" );
69 SLIST_FIELD_NUMPLAYERS = gethostcacheindexforkey( "numplayers" );
70 SLIST_FIELD_NUMHUMANS = gethostcacheindexforkey( "numhumans" );
71 SLIST_FIELD_NUMBOTS = gethostcacheindexforkey( "numbots" );
72 SLIST_FIELD_PROTOCOL = gethostcacheindexforkey( "protocol" );
73 SLIST_FIELD_FREESLOTS = gethostcacheindexforkey( "freeslots" );
76 entity makeNexuizServerList()
79 me = spawnNexuizServerList();
80 me.configureNexuizServerList(me);
83 void configureNexuizServerListNexuizServerList(entity me)
85 me.configureNexuizListBox(me);
87 ServerList_UpdateFieldIDs();
91 void setSelectedNexuizServerList(entity me, float i)
94 save = me.selectedItem;
95 setSelectedListBox(me, i);
97 if(me.selectedItem == save)
102 if(gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT) != me.nItems)
103 return; // sorry, it would be wrong
104 if(me.selectedServer)
105 strunzone(me.selectedServer);
106 me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem));
108 void refreshServerListNexuizServerList(entity me, float mode)
110 // 0: just reparametrize
111 // 1: also ask for new servers
113 print("refresh of type ", ftos(mode), "\n");
114 /* if(mode == 2) // borken
117 localcmd("net_slist\n");
118 me.needsRefresh = 1; // net_slist kills sort order, so we need to restore it later
124 resethostcachemasks();
125 if(!me.filterShowFull)
126 sethostcachemasknumber(m++, SLIST_FIELD_FREESLOTS, 1, SLIST_TEST_GREATEREQUAL);
127 if(!me.filterShowEmpty)
128 sethostcachemasknumber(m++, SLIST_FIELD_NUMHUMANS, 1, SLIST_TEST_GREATEREQUAL);
129 sethostcachesort(me.currentSortField, me.currentSortOrder < 0);
135 void focusEnterNexuizServerList(entity me)
137 if(time < me.nextRefreshTime)
139 print("sorry, no refresh yet\n");
142 me.nextRefreshTime = time + 10;
143 me.refreshServerList(me, 1);
145 void drawNexuizServerList(entity me)
149 if(me.currentSortField == -1)
151 me.setSortOrder(me, SLIST_FIELD_PING, +1);
152 me.refreshServerList(me, 2);
154 else if(me.needsRefresh == 1)
156 me.needsRefresh = 2; // delay by one frame to make sure "slist" has been executed
158 else if(me.needsRefresh == 2)
161 me.refreshServerList(me, 0);
164 me.nItems = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT);
165 me.connectButton.disabled = (me.nItems == 0);
168 if(me.selectedServer)
170 for(i = 0; i < me.nItems; ++i)
171 if(gethostcachestring(SLIST_FIELD_CNAME, i) == me.selectedServer)
173 if(i != me.selectedItem)
175 me.lastClickedServer = -1;
185 if(me.selectedItem >= me.nItems)
186 me.selectedItem = me.nItems - 1;
187 if(me.selectedServer)
188 strunzone(me.selectedServer);
189 me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem));
194 void ServerList_PingSort_Click(entity btn, entity me)
196 me.setSortOrder(me, SLIST_FIELD_PING, +1);
198 void ServerList_NameSort_Click(entity btn, entity me)
200 me.setSortOrder(me, SLIST_FIELD_NAME, -1); // why?
202 void ServerList_MapSort_Click(entity btn, entity me)
204 me.setSortOrder(me, SLIST_FIELD_MAP, -1); // why?
206 void ServerList_PlayerSort_Click(entity btn, entity me)
208 me.setSortOrder(me, SLIST_FIELD_NUMHUMANS, -1);
210 void ServerList_ShowEmpty_Click(entity box, entity me)
212 box.checked = me.filterShowEmpty = !me.filterShowEmpty;
213 me.refreshServerList(me, 0);
215 void ServerList_ShowFull_Click(entity box, entity me)
217 box.checked = me.filterShowFull = !me.filterShowFull;
218 me.refreshServerList(me, 0);
220 void setSortOrderNexuizServerList(entity me, float field, float direction)
222 if(me.currentSortField == field)
223 direction = -me.currentSortOrder;
224 me.currentSortOrder = direction;
225 me.currentSortField = field;
226 me.sortButton1.forcePressed = (field == SLIST_FIELD_PING);
227 me.sortButton2.forcePressed = (field == SLIST_FIELD_NAME);
228 me.sortButton3.forcePressed = (field == SLIST_FIELD_MAP);
229 me.sortButton4.forcePressed = (field == SLIST_FIELD_NUMHUMANS);
231 if(me.selectedServer)
232 strunzone(me.selectedServer);
233 me.selectedServer = string_null;
234 me.refreshServerList(me, 0);
236 void positionSortButtonNexuizServerList(entity me, entity btn, float theOrigin, float theSize, string theTitle, void(entity, entity) theFunc)
238 vector originInLBSpace, sizeInLBSpace;
239 originInLBSpace = eY * (-me.itemHeight);
240 sizeInLBSpace = eY * me.itemHeight + eX * (1 - me.controlWidth);
242 vector originInDialogSpace, sizeInDialogSpace;
243 originInDialogSpace = boxToGlobal(originInLBSpace, me.Container_origin, me.Container_size);
244 sizeInDialogSpace = boxToGlobalSize(sizeInLBSpace, me.Container_size);
246 btn.Container_origin_x = originInDialogSpace_x + sizeInDialogSpace_x * theOrigin;
247 btn.Container_size_x = sizeInDialogSpace_x * theSize;
248 btn.setText(btn, theTitle);
249 btn.onClick = theFunc;
250 btn.onClickEntity = me;
253 void resizeNotifyNexuizServerList(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
255 resizeNotifyNexuizListBox(me, relOrigin, relSize, absOrigin, absSize);
257 me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight);
258 me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth));
259 me.realUpperMargin = 0.5 * (1 - me.realFontSize_y);
261 me.columnPingOrigin = 0;
262 me.columnPingSize = me.realFontSize_x * 4;
263 me.columnMapSize = me.realFontSize_x * 12;
264 me.columnPlayersSize = me.realFontSize_x * 6;
265 me.columnNameSize = 1 - me.columnPlayersSize - me.columnMapSize - me.columnPingSize - 3 * me.realFontSize_x;
266 me.columnNameOrigin = me.columnPingOrigin + me.columnPingSize + me.realFontSize_x;
267 me.columnMapOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x;
268 me.columnPlayersOrigin = me.columnMapOrigin + me.columnMapSize + me.realFontSize_x;
270 me.positionSortButton(me, me.sortButton1, me.columnPingOrigin, me.columnPingSize, "Ping", ServerList_PingSort_Click);
271 me.positionSortButton(me, me.sortButton2, me.columnNameOrigin, me.columnNameSize, "Host name", ServerList_NameSort_Click);
272 me.positionSortButton(me, me.sortButton3, me.columnMapOrigin, me.columnMapSize, "Map", ServerList_MapSort_Click);
273 me.positionSortButton(me, me.sortButton4, me.columnPlayersOrigin, me.columnPlayersSize, "Players", ServerList_PlayerSort_Click);
276 f = me.currentSortField;
277 me.currentSortField = -1;
278 me.setSortOrder(me, f, me.currentSortOrder); // force resetting the sort order
280 void ServerList_Connect_Click(entity btn, entity me)
283 localcmd("connect ", me.selectedServer, "\n");
285 void clickListBoxItemNexuizServerList(entity me, float i, vector where)
287 if(i == me.lastClickedServer)
288 if(time < me.lastClickedTime + 0.3)
291 ServerList_Connect_Click(NULL, me);
293 me.lastClickedServer = i;
294 me.lastClickedTime = time;
296 void drawListBoxItemNexuizServerList(entity me, float i, vector absSize, float isSelected)
298 // layout: Ping, Server name, Map name, NP, TP, MP
305 draw_Fill('0 0 0', '1 1 0', '0 0 1', 0.5);
307 if(gethostcachenumber(SLIST_FIELD_NUMPLAYERS, i) >= gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i))
309 else if not(gethostcachenumber(SLIST_FIELD_NUMHUMANS, i))
314 p = gethostcachenumber(SLIST_FIELD_PING, i);
316 theColor = eX * (p / 50) + eY;
318 theColor = eX + eY * ((150 - p) / 100);
322 theAlpha *= 0.1 + 0.9 * (650 - p) / 500;
331 draw_Text(me.realUpperMargin * eY + (me.columnPingSize - draw_TextWidth(s, 0) * me.realFontSize_x) * eX, s, me.realFontSize, theColor, theAlpha, 0);
332 s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_NAME, i), me.columnNameSize / me.realFontSize_x, 0);
333 draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, theColor, theAlpha, 0);
334 s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_MAP, i), me.columnMapSize / me.realFontSize_x, 0);
335 draw_Text(me.realUpperMargin * eY + (me.columnMapOrigin + (me.columnMapSize - draw_TextWidth(s, 0) * me.realFontSize_x) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);
336 s = strcat(ftos(gethostcachenumber(SLIST_FIELD_NUMHUMANS, i)), "/", ftos(gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i)));
337 draw_Text(me.realUpperMargin * eY + (me.columnPlayersOrigin + (me.columnPlayersSize - draw_TextWidth(s, 0) * me.realFontSize_x) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha, 0);