]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/menu-div0test/nexuiz/serverlist.c
use if not( instead of if(!, thanks to Spike
[divverent/nexuiz.git] / qcsrc / menu-div0test / nexuiz / serverlist.c
1 #ifdef INTERFACE
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))
9
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)
20
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         METHOD(NexuizServerList, positionSortButton, void(entity, entity, float, float, string, void(entity, entity)))
25         ATTRIB(NexuizServerList, sortButton1, entity, NULL)
26         ATTRIB(NexuizServerList, sortButton2, entity, NULL)
27         ATTRIB(NexuizServerList, sortButton3, entity, NULL)
28         ATTRIB(NexuizServerList, sortButton4, entity, NULL)
29         ATTRIB(NexuizServerList, connectButton, entity, NULL)
30         ATTRIB(NexuizServerList, currentSortOrder, float, 0)
31         ATTRIB(NexuizServerList, currentSortField, float, 0)
32         ATTRIB(NexuizServerList, lastClickedServer, float, -1)
33         ATTRIB(NexuizServerList, lastClickedTime, float, 0)
34 ENDCLASS(NexuizServerList)
35 entity makeNexuizServerList();
36 void ServerList_Connect_Click(entity btn, entity me);
37 void ServerList_Refresh_Click(entity btn, entity me);
38 #endif
39
40 #ifdef IMPLEMENTATION
41 float SLIST_FIELD_CNAME;
42 float SLIST_FIELD_PING;
43 float SLIST_FIELD_GAME;
44 float SLIST_FIELD_MOD;
45 float SLIST_FIELD_MAP;
46 float SLIST_FIELD_NAME;
47 float SLIST_FIELD_MAXPLAYERS;
48 float SLIST_FIELD_NUMPLAYERS;
49 float SLIST_FIELD_NUMHUMANS;
50 float SLIST_FIELD_NUMBOTS;
51 float SLIST_FIELD_PROTOCOL;
52 float SLIST_FIELD_FREESLOTS;
53 void ServerList_UpdateFieldIDs()
54 {
55         SLIST_FIELD_CNAME = gethostcacheindexforkey( "cname" );
56         SLIST_FIELD_PING = gethostcacheindexforkey( "ping" );
57         SLIST_FIELD_GAME = gethostcacheindexforkey( "game" );
58         SLIST_FIELD_MOD = gethostcacheindexforkey( "mod" );
59         SLIST_FIELD_MAP = gethostcacheindexforkey( "map" );
60         SLIST_FIELD_NAME = gethostcacheindexforkey( "name" );
61         SLIST_FIELD_MAXPLAYERS = gethostcacheindexforkey( "maxplayers" );
62         SLIST_FIELD_NUMPLAYERS = gethostcacheindexforkey( "numplayers" );
63         SLIST_FIELD_NUMHUMANS = gethostcacheindexforkey( "numhumans" );
64         SLIST_FIELD_NUMBOTS = gethostcacheindexforkey( "numbots" );
65         SLIST_FIELD_PROTOCOL = gethostcacheindexforkey( "protocol" );
66         SLIST_FIELD_FREESLOTS = gethostcacheindexforkey( "freeslots" );
67 }
68
69 entity makeNexuizServerList()
70 {
71         entity me;
72         me = spawnNexuizServerList();
73         me.configureNexuizServerList(me);
74         return me;
75 }
76 void configureNexuizServerListNexuizServerList(entity me)
77 {
78         me.configureNexuizListBox(me);
79
80         ServerList_UpdateFieldIDs();
81         resethostcachemasks();
82         me.currentSortField = -1;
83
84         me.nItems = 0;
85 }
86 void setSelectedNexuizServerList(entity me, float i)
87 {
88         float save;
89         save = me.selectedItem;
90         setSelectedListBox(me, i);
91         /*
92         if(me.selectedItem == save)
93                 return;
94         */
95         if(me.nItems == 0)
96                 return;
97         if(gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT) != me.nItems)
98                 return; // sorry, it would be wrong
99         if(me.selectedServer)
100                 strunzone(me.selectedServer);
101         me.selectedServer = strzone(gethostcachestring(SLIST_FIELD_CNAME, me.selectedItem));
102 }
103 void drawNexuizServerList(entity me)
104 {
105         float i;
106
107         if(me.currentSortField == -1)
108         {
109                 refreshhostcache();
110                 me.setSortOrder(me, SLIST_FIELD_PING, +1);
111         }
112
113         me.nItems = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT);
114         me.connectButton.disabled = (me.nItems == 0);
115         for(i = 0; i < me.nItems; ++i)
116                 if(gethostcachestring(SLIST_FIELD_CNAME, i) == me.selectedServer)
117                 {
118                         if(i != me.selectedItem)
119                         {
120                                 me.lastClickedServer = -1;
121                                 me.selectedItem = i;
122                         }
123                         break;
124                 }
125         drawListBox(me);
126 }
127 void ServerList_PingSort_Click(entity btn, entity me)
128 {
129         me.setSortOrder(me, SLIST_FIELD_PING, +1);
130 }
131 void ServerList_NameSort_Click(entity btn, entity me)
132 {
133         me.setSortOrder(me, SLIST_FIELD_NAME, -1); // why?
134 }
135 void ServerList_MapSort_Click(entity btn, entity me)
136 {
137         me.setSortOrder(me, SLIST_FIELD_MAP, -1); // why?
138 }
139 void ServerList_PlayerSort_Click(entity btn, entity me)
140 {
141         me.setSortOrder(me, SLIST_FIELD_NUMHUMANS, -1);
142 }
143 void setSortOrderNexuizServerList(entity me, float field, float direction)
144 {
145         if(me.currentSortField == field)
146                 direction = -me.currentSortOrder;
147         me.currentSortOrder = direction;
148         me.currentSortField = field;
149         sethostcachesort(field, direction < 0);
150         resorthostcache();
151         me.sortButton1.forcePressed = (field == SLIST_FIELD_PING);
152         me.sortButton2.forcePressed = (field == SLIST_FIELD_NAME);
153         me.sortButton3.forcePressed = (field == SLIST_FIELD_MAP);
154         me.sortButton4.forcePressed = (field == SLIST_FIELD_NUMHUMANS);
155         me.selectedItem = 0;
156         if(me.selectedServer)
157                 strunzone(me.selectedServer);
158         me.selectedServer = string_null;
159 }
160 void positionSortButtonNexuizServerList(entity me, entity btn, float theOrigin, float theSize, string theTitle, void(entity, entity) theFunc)
161 {
162         vector originInLBSpace, sizeInLBSpace;
163         originInLBSpace = eY * (-me.itemHeight);
164         sizeInLBSpace = eY * me.itemHeight + eX * (1 - me.controlWidth);
165
166         vector originInDialogSpace, sizeInDialogSpace;
167         originInDialogSpace = boxToGlobal(originInLBSpace, me.Container_origin, me.Container_size);
168         sizeInDialogSpace = boxToGlobalSize(sizeInLBSpace, me.Container_size);
169
170         btn.Container_origin_x = originInDialogSpace_x + sizeInDialogSpace_x * theOrigin;
171         btn.Container_size_x   =                         sizeInDialogSpace_x * theSize;
172         btn.setText(btn, theTitle);
173         btn.onClick = theFunc;
174         btn.onClickEntity = me;
175         btn.resized = 1;
176 }
177 void resizeNotifyNexuizServerList(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
178 {
179         resizeNotifyNexuizListBox(me, relOrigin, relSize, absOrigin, absSize);
180
181         me.realFontSize_y = me.fontSize / (absSize_y * me.itemHeight);
182         me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth));
183         me.realUpperMargin = 0.5 * (1 - me.realFontSize_y);
184
185         me.columnPingOrigin = 0;
186         me.columnPingSize = me.realFontSize_x * 4;
187         me.columnMapSize = me.realFontSize_x * 12;
188         me.columnPlayersSize = me.realFontSize_x * 6;
189         me.columnNameSize = 1 - me.columnPlayersSize - me.columnMapSize - me.columnPingSize - 3 * me.realFontSize_x;
190         me.columnNameOrigin = me.columnPingOrigin + me.columnPingSize + me.realFontSize_x;
191         me.columnMapOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x;
192         me.columnPlayersOrigin = me.columnMapOrigin + me.columnMapSize + me.realFontSize_x;
193
194         me.positionSortButton(me, me.sortButton1, me.columnPingOrigin, me.columnPingSize, "Ping", ServerList_PingSort_Click);
195         me.positionSortButton(me, me.sortButton2, me.columnNameOrigin, me.columnNameSize, "Host name", ServerList_NameSort_Click);
196         me.positionSortButton(me, me.sortButton3, me.columnMapOrigin, me.columnMapSize, "Map", ServerList_MapSort_Click);
197         me.positionSortButton(me, me.sortButton4, me.columnPlayersOrigin, me.columnPlayersSize, "Players", ServerList_PlayerSort_Click);
198
199         float f;
200         f = me.currentSortField;
201         me.currentSortField = -1;
202         me.setSortOrder(me, f, me.currentSortOrder); // force resetting the sort order
203 }
204 void ServerList_Connect_Click(entity btn, entity me)
205 {
206         if(me.nItems > 0)
207                 localcmd("connect ", me.selectedServer, "\n");
208 }
209 void ServerList_Refresh_Click(entity btn, entity me)
210 {
211         refreshhostcache();
212 }
213 void clickListBoxItemNexuizServerList(entity me, float i, vector where)
214 {
215         if(i == me.lastClickedServer)
216                 if(time < me.lastClickedTime + 0.3)
217                 {
218                         // DOUBLE CLICK!
219                         ServerList_Connect_Click(NULL, me);
220                 }
221         me.lastClickedServer = i;
222         me.lastClickedTime = time;
223 }
224 void drawListBoxItemNexuizServerList(entity me, float i, vector absSize, float isSelected)
225 {
226         // layout: Ping, Server name, Map name, NP, TP, MP
227         string s;
228         float p;
229         vector theColor;
230         float theAlpha;
231
232         if(isSelected)
233                 draw_Fill('0 0 0', '1 1 0', '0 0 1', 0.5);
234
235         if(gethostcachenumber(SLIST_FIELD_NUMPLAYERS, i) >= gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i))
236                 theAlpha = 0.2;
237         else if not(gethostcachenumber(SLIST_FIELD_NUMHUMANS, i))
238                 theAlpha = 0.5;
239         else
240                 theAlpha = 1;
241         
242         p = gethostcachenumber(SLIST_FIELD_PING, i);
243         if(p < 50)
244                 theColor = eX * (p / 50) + eY;
245         else if(p < 150)
246                 theColor = eX + eY * ((150 - p) / 100);
247         else if(p < 650)
248         {
249                 theColor = eX;
250                 theAlpha *= 0.1 + 0.9 * (650 - p) / 500;
251         }
252         else
253         {
254                 theColor = eX;
255                 theAlpha *= 0.1;
256         }
257         
258         s = ftos(p);
259         draw_Text(me.realUpperMargin * eY + (me.columnPingSize - draw_TextWidth(s) * me.realFontSize_x) * eX, s, me.realFontSize, theColor, theAlpha);
260         s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_NAME, i), me.columnNameSize / me.realFontSize_x);
261         draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, theColor, theAlpha);
262         s = draw_TextShortenToWidth(gethostcachestring(SLIST_FIELD_MAP, i), me.columnMapSize / me.realFontSize_x);
263         draw_Text(me.realUpperMargin * eY + (me.columnMapOrigin + (me.columnMapSize - draw_TextWidth(s) * me.realFontSize_x) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha);
264         s = strcat(ftos(gethostcachenumber(SLIST_FIELD_NUMHUMANS, i)), "/", ftos(gethostcachenumber(SLIST_FIELD_MAXPLAYERS, i)));
265         draw_Text(me.realUpperMargin * eY + (me.columnPlayersOrigin + (me.columnPlayersSize - draw_TextWidth(s) * me.realFontSize_x) * 0.5) * eX, s, me.realFontSize, theColor, theAlpha);
266 }
267 #endif