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