1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4
5 This file is part of Quake III Arena source code.
6
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 ===========================================================================
21 */
22 //
23 /*
24 =======================================================================
25
26 REMOVE BOTS MENU
27
28 =======================================================================
29 */
30
31
32 #include "ui_local.h"
33
34
35 #define ART_BACKGROUND "menu/art/addbotframe"
36 #define ART_BACK0 "menu/art/back_0"
37 #define ART_BACK1 "menu/art/back_1"
38 #define ART_DELETE0 "menu/art/delete_0"
39 #define ART_DELETE1 "menu/art/delete_1"
40 #define ART_ARROWS "menu/art/arrows_vert_0"
41 #define ART_ARROWUP "menu/art/arrows_vert_top"
42 #define ART_ARROWDOWN "menu/art/arrows_vert_bot"
43
44 #define ID_UP 10
45 #define ID_DOWN 11
46 #define ID_DELETE 12
47 #define ID_BACK 13
48 #define ID_BOTNAME0 20
49 #define ID_BOTNAME1 21
50 #define ID_BOTNAME2 22
51 #define ID_BOTNAME3 23
52 #define ID_BOTNAME4 24
53 #define ID_BOTNAME5 25
54 #define ID_BOTNAME6 26
55
56
57 typedef struct {
58 menuframework_s menu;
59
60 menutext_s banner;
61 menubitmap_s background;
62
63 menubitmap_s arrows;
64 menubitmap_s up;
65 menubitmap_s down;
66
67 menutext_s bots[7];
68
69 menubitmap_s delete;
70 menubitmap_s back;
71
72 int numBots;
73 int baseBotNum;
74 int selectedBotNum;
75 char botnames[7][32];
76 int botClientNums[MAX_BOTS];
77 } removeBotsMenuInfo_t;
78
79 static removeBotsMenuInfo_t removeBotsMenuInfo;
80
81
82 /*
83 =================
84 UI_RemoveBotsMenu_SetBotNames
85 =================
86 */
UI_RemoveBotsMenu_SetBotNames(void)87 static void UI_RemoveBotsMenu_SetBotNames( void ) {
88 int n;
89 char info[MAX_INFO_STRING];
90
91 for ( n = 0; (n < 7) && (removeBotsMenuInfo.baseBotNum + n < removeBotsMenuInfo.numBots); n++ ) {
92 trap_GetConfigString( CS_PLAYERS + removeBotsMenuInfo.botClientNums[removeBotsMenuInfo.baseBotNum + n], info, MAX_INFO_STRING );
93 Q_strncpyz( removeBotsMenuInfo.botnames[n], Info_ValueForKey( info, "n" ), sizeof(removeBotsMenuInfo.botnames[n]) );
94 Q_CleanStr( removeBotsMenuInfo.botnames[n] );
95 }
96
97 }
98
99
100 /*
101 =================
102 UI_RemoveBotsMenu_DeleteEvent
103 =================
104 */
UI_RemoveBotsMenu_DeleteEvent(void * ptr,int event)105 static void UI_RemoveBotsMenu_DeleteEvent( void* ptr, int event ) {
106 if (event != QM_ACTIVATED) {
107 return;
108 }
109
110 trap_Cmd_ExecuteText( EXEC_APPEND, va("clientkick %i\n", removeBotsMenuInfo.botClientNums[removeBotsMenuInfo.baseBotNum + removeBotsMenuInfo.selectedBotNum]) );
111 }
112
113
114 /*
115 =================
116 UI_RemoveBotsMenu_BotEvent
117 =================
118 */
UI_RemoveBotsMenu_BotEvent(void * ptr,int event)119 static void UI_RemoveBotsMenu_BotEvent( void* ptr, int event ) {
120 if (event != QM_ACTIVATED) {
121 return;
122 }
123
124 removeBotsMenuInfo.bots[removeBotsMenuInfo.selectedBotNum].color = color_orange;
125 removeBotsMenuInfo.selectedBotNum = ((menucommon_s*)ptr)->id - ID_BOTNAME0;
126 removeBotsMenuInfo.bots[removeBotsMenuInfo.selectedBotNum].color = color_white;
127 }
128
129
130 /*
131 =================
132 UI_RemoveAddBotsMenu_BackEvent
133 =================
134 */
UI_RemoveBotsMenu_BackEvent(void * ptr,int event)135 static void UI_RemoveBotsMenu_BackEvent( void* ptr, int event ) {
136 if (event != QM_ACTIVATED) {
137 return;
138 }
139 UI_PopMenu();
140 }
141
142
143 /*
144 =================
145 UI_RemoveBotsMenu_UpEvent
146 =================
147 */
UI_RemoveBotsMenu_UpEvent(void * ptr,int event)148 static void UI_RemoveBotsMenu_UpEvent( void* ptr, int event ) {
149 if (event != QM_ACTIVATED) {
150 return;
151 }
152
153 if( removeBotsMenuInfo.baseBotNum > 0 ) {
154 removeBotsMenuInfo.baseBotNum--;
155 UI_RemoveBotsMenu_SetBotNames();
156 }
157 }
158
159
160 /*
161 =================
162 UI_RemoveBotsMenu_DownEvent
163 =================
164 */
UI_RemoveBotsMenu_DownEvent(void * ptr,int event)165 static void UI_RemoveBotsMenu_DownEvent( void* ptr, int event ) {
166 if (event != QM_ACTIVATED) {
167 return;
168 }
169
170 if( removeBotsMenuInfo.baseBotNum + 7 < removeBotsMenuInfo.numBots ) {
171 removeBotsMenuInfo.baseBotNum++;
172 UI_RemoveBotsMenu_SetBotNames();
173 }
174 }
175
176
177 /*
178 =================
179 UI_RemoveBotsMenu_GetBots
180 =================
181 */
UI_RemoveBotsMenu_GetBots(void)182 static void UI_RemoveBotsMenu_GetBots( void ) {
183 int numPlayers;
184 int isBot;
185 int n;
186 char info[MAX_INFO_STRING];
187
188 trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
189 numPlayers = atoi( Info_ValueForKey( info, "sv_maxclients" ) );
190 removeBotsMenuInfo.numBots = 0;
191
192 for( n = 0; n < numPlayers; n++ ) {
193 trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING );
194
195 isBot = atoi( Info_ValueForKey( info, "skill" ) );
196 if( !isBot ) {
197 continue;
198 }
199
200 removeBotsMenuInfo.botClientNums[removeBotsMenuInfo.numBots] = n;
201 removeBotsMenuInfo.numBots++;
202 }
203 }
204
205
206 /*
207 =================
208 UI_RemoveBots_Cache
209 =================
210 */
UI_RemoveBots_Cache(void)211 void UI_RemoveBots_Cache( void ) {
212 trap_R_RegisterShaderNoMip( ART_BACKGROUND );
213 trap_R_RegisterShaderNoMip( ART_BACK0 );
214 trap_R_RegisterShaderNoMip( ART_BACK1 );
215 trap_R_RegisterShaderNoMip( ART_DELETE0 );
216 trap_R_RegisterShaderNoMip( ART_DELETE1 );
217 }
218
219
220 /*
221 =================
222 UI_RemoveBotsMenu_Init
223 =================
224 */
UI_RemoveBotsMenu_Init(void)225 static void UI_RemoveBotsMenu_Init( void ) {
226 int n;
227 int count;
228 int y;
229
230 memset( &removeBotsMenuInfo, 0 ,sizeof(removeBotsMenuInfo) );
231 removeBotsMenuInfo.menu.fullscreen = qfalse;
232 removeBotsMenuInfo.menu.wrapAround = qtrue;
233
234 UI_RemoveBots_Cache();
235
236 UI_RemoveBotsMenu_GetBots();
237 UI_RemoveBotsMenu_SetBotNames();
238 count = removeBotsMenuInfo.numBots < 7 ? removeBotsMenuInfo.numBots : 7;
239
240 removeBotsMenuInfo.banner.generic.type = MTYPE_BTEXT;
241 removeBotsMenuInfo.banner.generic.x = 320;
242 removeBotsMenuInfo.banner.generic.y = 16;
243 removeBotsMenuInfo.banner.string = "REMOVE BOTS";
244 removeBotsMenuInfo.banner.color = color_white;
245 removeBotsMenuInfo.banner.style = UI_CENTER;
246
247 removeBotsMenuInfo.background.generic.type = MTYPE_BITMAP;
248 removeBotsMenuInfo.background.generic.name = ART_BACKGROUND;
249 removeBotsMenuInfo.background.generic.flags = QMF_INACTIVE;
250 removeBotsMenuInfo.background.generic.x = 320-233;
251 removeBotsMenuInfo.background.generic.y = 240-166;
252 removeBotsMenuInfo.background.width = 466;
253 removeBotsMenuInfo.background.height = 332;
254
255 removeBotsMenuInfo.arrows.generic.type = MTYPE_BITMAP;
256 removeBotsMenuInfo.arrows.generic.name = ART_ARROWS;
257 removeBotsMenuInfo.arrows.generic.flags = QMF_INACTIVE;
258 removeBotsMenuInfo.arrows.generic.x = 200;
259 removeBotsMenuInfo.arrows.generic.y = 128;
260 removeBotsMenuInfo.arrows.width = 64;
261 removeBotsMenuInfo.arrows.height = 128;
262
263 removeBotsMenuInfo.up.generic.type = MTYPE_BITMAP;
264 removeBotsMenuInfo.up.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
265 removeBotsMenuInfo.up.generic.x = 200;
266 removeBotsMenuInfo.up.generic.y = 128;
267 removeBotsMenuInfo.up.generic.id = ID_UP;
268 removeBotsMenuInfo.up.generic.callback = UI_RemoveBotsMenu_UpEvent;
269 removeBotsMenuInfo.up.width = 64;
270 removeBotsMenuInfo.up.height = 64;
271 removeBotsMenuInfo.up.focuspic = ART_ARROWUP;
272
273 removeBotsMenuInfo.down.generic.type = MTYPE_BITMAP;
274 removeBotsMenuInfo.down.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
275 removeBotsMenuInfo.down.generic.x = 200;
276 removeBotsMenuInfo.down.generic.y = 128+64;
277 removeBotsMenuInfo.down.generic.id = ID_DOWN;
278 removeBotsMenuInfo.down.generic.callback = UI_RemoveBotsMenu_DownEvent;
279 removeBotsMenuInfo.down.width = 64;
280 removeBotsMenuInfo.down.height = 64;
281 removeBotsMenuInfo.down.focuspic = ART_ARROWDOWN;
282
283 for( n = 0, y = 120; n < count; n++, y += 20 ) {
284 removeBotsMenuInfo.bots[n].generic.type = MTYPE_PTEXT;
285 removeBotsMenuInfo.bots[n].generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
286 removeBotsMenuInfo.bots[n].generic.id = ID_BOTNAME0 + n;
287 removeBotsMenuInfo.bots[n].generic.x = 320 - 56;
288 removeBotsMenuInfo.bots[n].generic.y = y;
289 removeBotsMenuInfo.bots[n].generic.callback = UI_RemoveBotsMenu_BotEvent;
290 removeBotsMenuInfo.bots[n].string = removeBotsMenuInfo.botnames[n];
291 removeBotsMenuInfo.bots[n].color = color_orange;
292 removeBotsMenuInfo.bots[n].style = UI_LEFT|UI_SMALLFONT;
293 }
294
295 removeBotsMenuInfo.delete.generic.type = MTYPE_BITMAP;
296 removeBotsMenuInfo.delete.generic.name = ART_DELETE0;
297 removeBotsMenuInfo.delete.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
298 removeBotsMenuInfo.delete.generic.id = ID_DELETE;
299 removeBotsMenuInfo.delete.generic.callback = UI_RemoveBotsMenu_DeleteEvent;
300 removeBotsMenuInfo.delete.generic.x = 320+128-128;
301 removeBotsMenuInfo.delete.generic.y = 256+128-64;
302 removeBotsMenuInfo.delete.width = 128;
303 removeBotsMenuInfo.delete.height = 64;
304 removeBotsMenuInfo.delete.focuspic = ART_DELETE1;
305
306 removeBotsMenuInfo.back.generic.type = MTYPE_BITMAP;
307 removeBotsMenuInfo.back.generic.name = ART_BACK0;
308 removeBotsMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
309 removeBotsMenuInfo.back.generic.id = ID_BACK;
310 removeBotsMenuInfo.back.generic.callback = UI_RemoveBotsMenu_BackEvent;
311 removeBotsMenuInfo.back.generic.x = 320-128;
312 removeBotsMenuInfo.back.generic.y = 256+128-64;
313 removeBotsMenuInfo.back.width = 128;
314 removeBotsMenuInfo.back.height = 64;
315 removeBotsMenuInfo.back.focuspic = ART_BACK1;
316
317 Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.background );
318 Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.banner );
319 Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.arrows );
320 Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.up );
321 Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.down );
322 for( n = 0; n < count; n++ ) {
323 Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.bots[n] );
324 }
325 Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.delete );
326 Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.back );
327
328 removeBotsMenuInfo.baseBotNum = 0;
329 removeBotsMenuInfo.selectedBotNum = 0;
330 removeBotsMenuInfo.bots[0].color = color_white;
331 }
332
333
334 /*
335 =================
336 UI_RemoveBotsMenu
337 =================
338 */
UI_RemoveBotsMenu(void)339 void UI_RemoveBotsMenu( void ) {
340 UI_RemoveBotsMenu_Init();
341 UI_PushMenu( &removeBotsMenuInfo.menu );
342 }
343