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