Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
maplist.qc
Go to the documentation of this file.
1#include "maplist.qh"
2
3#include <common/mapinfo.qh>
5#include "mainwindow.qh"
6#include "inputbox.qh"
7
8.bool disabled;
9
14
16{
17 entity me;
18 me = NEW(XonoticMapList);
19 me.configureXonoticMapList(me);
20 return me;
21}
22
24{
25 me.stringFilterBox = e;
26 return e;
27}
28
30{
31 me.configureXonoticListBox(me);
32 me.refilter(me);
33}
34
36{
37 me.refilter(me);
38}
39
40
42{
43 return stof(substring(me.g_maplistCache, i, 1));
44}
46{
47 string a, b, c, s, bspname;
48 float n;
49 s = me.g_maplistCache;
50 if (!s)
51 return;
52 b = substring(s, i, 1);
53 if(b == "0")
54 b = "1";
55 else if(b == "1")
56 b = "0";
57 else
58 return; // nothing happens
59 a = substring(s, 0, i);
60 c = substring(s, i+1, strlen(s) - (i+1));
61 strunzone(s);
62 me.g_maplistCache = strzone(strcat(a, b, c));
63 // TODO also update the actual cvar
64 if (!((bspname = MapInfo_BSPName_ByID(i))))
65 return;
66 if(b == "1")
67 cvar_set("g_maplist", strcat(bspname, " ", cvar_string("g_maplist")));
68 else
69 {
70 s = "";
71 n = tokenize_console(cvar_string("g_maplist"));
72 for(i = 0; i < n; ++i)
73 if(argv(i) != bspname)
74 s = strcat(s, " ", argv(i));
75 cvar_set("g_maplist", substring(s, 1, strlen(s) - 1));
76 }
77}
78
80{
81 if(me.startButton)
82 me.startButton.disabled = ((me.selectedItem < 0) || (me.selectedItem >= me.nItems)
83 || ((gamestatus & (GAME_ISSERVER | GAME_CONNECTED)) && cvar("g_campaign")));
84 SUPER(XonoticMapList).draw(me);
85}
86
87void XonoticMapList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
88{
89 me.itemAbsSize = '0 0 0';
90 SUPER(XonoticMapList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
91
92 me.itemAbsSize.y = absSize.y * me.itemHeight;
93 me.itemAbsSize.x = absSize.x * (1 - me.controlWidth);
94 me.realFontSize.y = me.fontSize / me.itemAbsSize.y;
95 me.realFontSize.x = me.fontSize / me.itemAbsSize.x;
96 me.realUpperMargin1 = 0.5 * (1 - 2.5 * me.realFontSize.y);
97 me.realUpperMargin2 = me.realUpperMargin1 + 1.5 * me.realFontSize.y;
98
99 me.columnPreviewOrigin = 0;
100 me.columnPreviewSize = me.itemAbsSize.y / me.itemAbsSize.x * 4 / 3;
101 me.columnNameOrigin = me.columnPreviewOrigin + me.columnPreviewSize + me.realFontSize.x;
102 me.columnNameSize = 1 - me.columnPreviewSize - 2 * me.realFontSize.x;
103
104 me.checkMarkSize = (eX * (me.itemAbsSize.y / me.itemAbsSize.x) + eY) * 0.5;
105 me.checkMarkOrigin = eY + eX * (me.columnPreviewOrigin + me.columnPreviewSize) - me.checkMarkSize;
106}
107
109{
110 if(where.x <= me.columnPreviewOrigin + me.columnPreviewSize)
111 if(where.x >= 0)
112 {
114 me.g_maplistCacheToggle(me, i);
115 }
116}
117
119{
120 if(where.x >= me.columnNameOrigin)
121 if(where.x <= 1)
122 {
123 // pop up map info screen
125 main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, i, me);
126 DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size.x) + eY * ((me.itemHeight * i - me.scrollPos) * me.size.y), eY * me.itemAbsSize.y + eX * (me.itemAbsSize.x * me.columnNameSize));
127 }
128}
129
130void XonoticMapList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
131{
132 // layout: Ping, Map name, Map name, NP, TP, MP
133 string s;
134 float theAlpha;
135 float included;
136
137 if(!MapInfo_Get_ByID(i))
138 return;
139
140 included = me.g_maplistCacheQuery(me, i);
141 if(included || isSelected)
142 theAlpha = SKINALPHA_MAPLIST_INCLUDEDFG;
143 else
144 theAlpha = SKINALPHA_MAPLIST_NOTINCLUDEDFG;
145
146 if(isSelected)
147 draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
148 else
149 {
150 if(included)
151 draw_Fill('0 0 0', '1 1 0', SKINCOLOR_MAPLIST_INCLUDEDBG, SKINALPHA_MAPLIST_INCLUDEDBG);
152 if(isFocused)
153 {
154 me.focusedItemAlpha = getFadedAlpha(me.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
155 draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
156 }
157 }
158
159 if(draw_PictureSize(strcat("/maps/", MapInfo_Map_bspname)) == '0 0 0')
160 {
161 if(draw_PictureSize(strcat("/levelshots/", MapInfo_Map_bspname)) == '0 0 0')
162 draw_Picture(me.columnPreviewOrigin * eX, "nopreview_map", me.columnPreviewSize * eX + eY, '1 1 1', theAlpha);
163 else
164 draw_Picture(me.columnPreviewOrigin * eX, strcat("/levelshots/", MapInfo_Map_bspname), me.columnPreviewSize * eX + eY, '1 1 1', theAlpha);
165 }
166 else
167 draw_Picture(me.columnPreviewOrigin * eX, strcat("/maps/", MapInfo_Map_bspname), me.columnPreviewSize * eX + eY, '1 1 1', theAlpha);
168
169 if(included)
170 draw_Picture(me.checkMarkOrigin, "checkmark", me.checkMarkSize, '1 1 1', 1);
171 s = draw_TextShortenToWidth(strdecolorize(MapInfo_Map_titlestring), me.columnNameSize, 0, me.realFontSize);
172 draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_MAPLIST_TITLE, theAlpha, 0);
173 s = draw_TextShortenToWidth(strdecolorize(MapInfo_Map_author), me.columnNameSize, 0, me.realFontSize);
174 draw_Text(me.realUpperMargin2 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_MAPLIST_AUTHOR, theAlpha, 0);
175
177}
178
180{
181 float i, j, n;
182 string s;
184 int f = MapInfo_CurrentFeatures();
186 if (me.stringFilter)
187 MapInfo_FilterString(me.stringFilter);
188 me.nItems = MapInfo_count;
189
190 for(i = 0; i < MapInfo_count; ++i)
191 {
192 if(draw_PreloadPicture(strcat("/maps/", MapInfo_BSPName_ByID(i))) == "")
194 }
195 s = "0";
196 for(i = 1; i < MapInfo_count; i *= 2)
197 s = strcat(s, s);
198 n = tokenize_console(cvar_string("g_maplist"));
199 for(i = 0; i < n; ++i)
200 {
201 j = MapInfo_FindName(argv(i));
202 if(j >= 0)
203 {
204 // double check that the two mapnames are "identical", not just share the same prefix
205 if (strlen(MapInfo_BSPName_ByID(j)) == strlen(argv(i)))
206 s = strcat(
207 substring(s, 0, j),
208 "1",
209 substring(s, j+1, MapInfo_count - (j+1))
210 );
211 }
212 }
213 strcpy(me.g_maplistCache, s);
214 if(gt != me.lastGametype || f != me.lastFeatures)
215 {
216 me.lastGametype = gt;
217 me.lastFeatures = f;
218 me.setSelected(me, 0);
219 }
220}
221
223{
224 me.refilter(me);
225}
226
228{
229 strfree(me.stringFilter);
230 if(box.text != "")
231 me.stringFilter = strzone(box.text);
232
233 me.refilter(me);
234}
235
237{
238 float i, n;
239 n = strlen(me.g_maplistCache);
240 for (i = 0 ; i < n; ++i)
241 {
242 if (!me.g_maplistCacheQuery(me, i))
243 me.g_maplistCacheToggle(me, i);
244 }
245 me.refilter(me);
246}
247
249{
250 float i, n;
251 n = strlen(me.g_maplistCache);
252 for (i = 0 ; i < n; ++i)
253 {
254 if (me.g_maplistCacheQuery(me, i))
255 me.g_maplistCacheToggle(me, i);
256 }
257 me.refilter(me);
258}
259
261{
262 float i;
263 string s;
265 s = "";
266 for(i = 0; i < MapInfo_count; ++i)
267 s = cons(s, MapInfo_BSPName_ByID(i));
268 cvar_set("g_maplist", s);
269 me.refilter(me);
270}
271
273{
274 cvar_set("g_maplist", "");
275 me.refilter(me);
276}
277
279{
280 string m;
281 float i;
282
283 i = me.selectedItem;
284
285 if(btn.parent.instanceOfXonoticMapInfoDialog)
286 {
287 i = btn.parent.currentMapIndex;
288 Dialog_Close(btn, btn.parent);
289 }
290
291 if(i >= me.nItems || i < 0)
292 return;
293
295 if (!m)
296 {
297 LOG_INFO(_("Huh? Can't play this (m is NULL). Refiltering so this won't happen again."));
298 me.refilter(me);
299 return;
300 }
301 if(MapInfo_CheckMap(m))
302 {
303 localcmd("\nmenu_loadmap_prepare\n");
304 if(cvar("menu_use_default_hostname"))
305 localcmd("hostname \"", sprintf(_("%s's Xonotic Server"), strdecolorize(cvar_string("_cl_name"))), "\"\n");
306 MapInfo_LoadMap(m, 1);
307 }
308 else
309 {
310 LOG_INFO(_("Huh? Can't play this (invalid gametype). Refiltering so this won't happen again."));
311 me.refilter(me);
312 return;
313 }
314}
315
316float XonoticMapList_keyDown(entity me, float scan, float ascii, float shift)
317{
318 string ch, save;
319 if(me.nItems <= 0)
320 return SUPER(XonoticMapList).keyDown(me, scan, ascii, shift);
321 if(scan == K_MOUSE2 || scan == K_SPACE || scan == K_ENTER || scan == K_KP_ENTER)
322 {
323 // pop up map info screen
325 main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, me.selectedItem, me);
326 DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size.x) + eY * ((me.itemHeight * me.selectedItem - me.scrollPos) * me.size.y), eY * me.itemAbsSize.y + eX * (me.itemAbsSize.x * me.columnNameSize));
327 }
328 else if(scan == K_MOUSE3 || scan == K_INS || scan == K_KP_INS || ((shift & S_CTRL) && scan == K_MOUSE1))
329 {
331 me.g_maplistCacheToggle(me, me.selectedItem);
332 }
333 else if(ascii == '+')
334 {
335 if (!me.g_maplistCacheQuery(me, me.selectedItem))
336 {
338 me.g_maplistCacheToggle(me, me.selectedItem);
339 }
340 }
341 else if(ascii == '-')
342 {
343 if(me.g_maplistCacheQuery(me, me.selectedItem))
344 {
346 me.g_maplistCacheToggle(me, me.selectedItem);
347 }
348 }
349 else if(scan == K_BACKSPACE)
350 {
351 if(time < me.typeToSearchTime)
352 {
353 save = substring(me.typeToSearchString, 0, strlen(me.typeToSearchString) - 1);
354 strcpy(me.typeToSearchString, save);
355 me.typeToSearchTime = time + 0.5;
356 if(strlen(me.typeToSearchString))
357 {
358 MapInfo_FindName(me.typeToSearchString);
360 me.setSelected(me, MapInfo_FindName_firstResult);
361 }
362 }
363 }
364 else if(ascii >= 32 && ascii != 127)
365 {
366 ch = chr(ascii);
367 if(time > me.typeToSearchTime)
368 save = ch;
369 else
370 save = strcat(me.typeToSearchString, ch);
371 strcpy(me.typeToSearchString, save);
372 me.typeToSearchTime = time + 0.5;
373 MapInfo_FindName(me.typeToSearchString);
375 me.setSelected(me, MapInfo_FindName_firstResult);
376 }
377 else if((shift & S_CTRL) && scan == 'f') // ctrl-f (as in "F"ind)
378 {
379 me.parent.setFocus(me.parent, me.stringFilterBox);
380 }
381 else if((shift & S_CTRL) && scan == 'u') // ctrl-u (remove stringFilter line)
382 {
383 me.stringFilterBox.setText(me.stringFilterBox, "");
384 MapList_StringFilterBox_Change(me.stringFilterBox, me);
385 }
386 else
387 return SUPER(XonoticMapList).keyDown(me, scan, ascii, shift);
388 return 1;
389}
390
391float MapList_StringFilterBox_keyDown(entity me, float scan, float ascii, float shift)
392{
393 // in this section, note that onChangeEntity has the ref to mapListBox
394 // we make use of that, instead of extending a class to add one more attrib
395 switch(scan)
396 {
397 case K_KP_ENTER:
398 case K_ENTER:
399 // move the focus to the mapListBox
400 me.onChangeEntity.parent.setFocus(me.onChangeEntity.parent, me.onChangeEntity);
401 return 1;
402 case K_KP_UPARROW:
403 case K_UPARROW:
404 case K_KP_DOWNARROW:
405 case K_DOWNARROW:
406 // pass the event to the mapListBox (to scroll up and down)
407 return me.onChangeEntity.keyDown(me.onChangeEntity, scan, ascii, shift);
408 }
409 return SUPER(XonoticInputBox).keyDown(me, scan, ascii, shift);
410}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
bool disabled
float time
#define strlen
#define tokenize_console
const int S_CTRL
Definition hud.qh:130
float K_UPARROW
Definition keycodes.qc:15
float K_BACKSPACE
Definition keycodes.qc:14
float K_DOWNARROW
Definition keycodes.qc:16
float K_MOUSE1
Definition keycodes.qc:129
float K_KP_UPARROW
Definition keycodes.qc:64
float K_MOUSE3
Definition keycodes.qc:131
float K_SPACE
Definition keycodes.qc:10
float K_ENTER
Definition keycodes.qc:8
float K_KP_DOWNARROW
Definition keycodes.qc:53
float K_MOUSE2
Definition keycodes.qc:130
float K_KP_ENTER
Definition keycodes.qc:74
float K_INS
Definition keycodes.qc:37
float K_KP_INS
Definition keycodes.qc:49
#define main
Definition _all.inc:202
#define LOG_INFO(...)
Definition log.qh:65
float MapInfo_CheckMap(string s)
Definition mapinfo.qc:1510
float MapInfo_FilterGametype(Gametype pGametype, int pFeatures, int pFlagsRequired, int pFlagsForbidden, bool pAbortOnGenerate)
Definition mapinfo.qc:177
float MapInfo_FindName(string s)
Definition mapinfo.qc:1426
bool MapInfo_Get_ByID(int i)
Definition mapinfo.qc:275
void MapInfo_Shutdown()
Definition mapinfo.qc:1651
int MapInfo_RequiredFlags()
Definition mapinfo.qc:1679
string MapInfo_BSPName_ByID(float i)
Definition mapinfo.qc:250
float _MapInfo_FilterGametype(vector pGametype, int pFeatures, int pFlagsRequired, int pFlagsForbidden, bool pAbortOnGenerate)
Definition mapinfo.qc:181
void MapInfo_FilterString(string sf)
Definition mapinfo.qc:213
void MapInfo_LoadMap(string s, float reinit)
Definition mapinfo.qc:1523
Gametype MapInfo_CurrentGametype()
Definition mapinfo.qc:1490
int MapInfo_ForbiddenFlags()
Definition mapinfo.qc:1664
int MapInfo_CurrentFeatures()
Definition mapinfo.qc:1480
void MapInfo_ClearTemps()
Definition mapinfo.qc:1639
vector MAPINFO_TYPE_ALL
Definition mapinfo.qh:27
float MapInfo_FindName_firstResult
Definition mapinfo.qh:196
float MapInfo_count
Definition mapinfo.qh:166
string MapInfo_Map_bspname
Definition mapinfo.qh:6
string MapInfo_Map_author
Definition mapinfo.qh:10
string MapInfo_Map_titlestring
Definition mapinfo.qh:8
void XonoticMapList_doubleClickListBoxItem(entity me, float i, vector where)
Definition maplist.qc:118
void XonoticMapList_g_maplistCacheToggle(entity me, float i)
Definition maplist.qc:45
void XonoticMapList_configureXonoticMapList(entity me)
Definition maplist.qc:29
void MapList_StringFilterBox_Change(entity box, entity me)
Definition maplist.qc:227
void XonoticMapList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
Definition maplist.qc:87
float MapList_StringFilterBox_keyDown(entity me, float scan, float ascii, float shift)
Definition maplist.qc:391
float XonoticMapList_g_maplistCacheQuery(entity me, float i)
Definition maplist.qc:41
void XonoticMapList_loadCvars(entity me)
Definition maplist.qc:35
void MapList_Remove_All(entity btn, entity me)
Definition maplist.qc:272
void XonoticMapList_destroy(entity me)
Definition maplist.qc:10
entity makeXonoticMapList()
Definition maplist.qc:15
void MapList_Add_Shown(entity btn, entity me)
Definition maplist.qc:236
void XonoticMapList_refilter(entity me)
Definition maplist.qc:179
entity MapList_Set_StringFilterBox(entity me, entity e)
Definition maplist.qc:23
float XonoticMapList_keyDown(entity me, float scan, float ascii, float shift)
Definition maplist.qc:316
void XonoticMapList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
Definition maplist.qc:130
void XonoticMapList_draw(entity me)
Definition maplist.qc:79
void MapList_Add_All(entity btn, entity me)
Definition maplist.qc:260
void XonoticMapList_refilterCallback(entity me, entity cb)
Definition maplist.qc:222
void XonoticMapList_clickListBoxItem(entity me, float i, vector where)
Definition maplist.qc:108
void MapList_Remove_Shown(entity btn, entity me)
Definition maplist.qc:248
void MapList_LoadMap(entity btn, entity me)
Definition maplist.qc:278
string draw_TextShortenToWidth(string theText, float maxWidth, float ICanHasKallerz, vector SizeThxBye)
Definition draw.qc:377
void draw_Picture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha)
Definition draw.qc:72
void draw_Text(vector theOrigin, string theText, vector theSize, vector theColor, float theAlpha, float ICanHasKallerz)
Definition draw.qc:282
vector draw_PictureSize(string pic)
Definition draw.qc:80
float draw_TextWidth(string theText, float ICanHasKallerz, vector SizeThxBye)
Definition draw.qc:304
void draw_Fill(vector theOrigin, vector theSize, vector theColor, float theAlpha)
Definition draw.qc:97
string draw_PreloadPicture(string pic)
Definition draw.qc:60
void Dialog_Close(entity button, entity me)
Definition dialog.qc:7
float getFadedAlpha(float currentAlpha, float startAlpha, float targetAlpha)
Definition util.qc:816
void m_play_click_sound(string soundfile)
Definition menu.qc:1106
const string MENU_SOUND_OPEN
Definition menu.qh:53
const string MENU_SOUND_SELECT
Definition menu.qh:54
const int GAME_ISSERVER
Definition menu.qh:11
const int GAME_CONNECTED
Definition menu.qh:12
int gamestatus
Definition menu.qh:16
void localcmd(string command,...)
void cvar_set(string name, string value)
string chr(float ascii)
float stof(string val,...)
string substring(string s, float start, float length)
float cvar(string name)
const string cvar_string(string name)
void strunzone(string s)
string strzone(string s)
string argv(float n)
void DialogOpenButton_Click_withCoords(entity button, entity tab, vector theOrigin, vector theSize)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
#define NEW(cname,...)
Definition oo.qh:117
#define SUPER(cname)
Definition oo.qh:231
#define NULL
Definition post.qh:14
vector
Definition self.qh:92
#define strfree(this)
Definition string.qh:59
#define strcpy(this, s)
Definition string.qh:52
ERASEABLE string cons(string a, string b)
Definition string.qh:276
const vector eY
Definition vector.qh:45
const vector eX
Definition vector.qh:44