Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

ui_addbots.c (11496B)


      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 Foobar; 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 ADD BOTS MENU
     27 
     28 =======================================================================
     29 */
     30 
     31 
     32 #include "ui_local.h"
     33 
     34 
     35 #define ART_BACK0			"menu/art/back_0"
     36 #define ART_BACK1			"menu/art/back_1"	
     37 #define ART_FIGHT0			"menu/art/accept_0"
     38 #define ART_FIGHT1			"menu/art/accept_1"
     39 #define ART_BACKGROUND		"menu/art/addbotframe"
     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_BACK				10
     45 #define ID_GO				11
     46 #define ID_LIST				12
     47 #define ID_UP				13
     48 #define ID_DOWN				14
     49 #define ID_SKILL			15
     50 #define ID_TEAM				16
     51 #define ID_BOTNAME0			20
     52 #define ID_BOTNAME1			21
     53 #define ID_BOTNAME2			22
     54 #define ID_BOTNAME3			23
     55 #define ID_BOTNAME4			24
     56 #define ID_BOTNAME5			25
     57 #define ID_BOTNAME6			26
     58 
     59 
     60 typedef struct {
     61 	menuframework_s	menu;
     62 	menubitmap_s	arrows;
     63 	menubitmap_s	up;
     64 	menubitmap_s	down;
     65 	menutext_s		bots[7];
     66 	menulist_s		skill;
     67 	menulist_s		team;
     68 	menubitmap_s	go;
     69 	menubitmap_s	back;
     70 
     71 	int				numBots;
     72 	int				delay;
     73 	int				baseBotNum;
     74 	int				selectedBotNum;
     75 	int				sortedBotNums[MAX_BOTS];
     76 	char			botnames[7][32];
     77 } addBotsMenuInfo_t;
     78 
     79 static addBotsMenuInfo_t	addBotsMenuInfo;
     80 
     81 
     82 /*
     83 =================
     84 UI_AddBotsMenu_FightEvent
     85 =================
     86 */
     87 static void UI_AddBotsMenu_FightEvent( void* ptr, int event ) {
     88 	const char	*team;
     89 	int			skill;
     90 
     91 	if (event != QM_ACTIVATED) {
     92 		return;
     93 	}
     94 
     95 	team = addBotsMenuInfo.team.itemnames[addBotsMenuInfo.team.curvalue];
     96 	skill = addBotsMenuInfo.skill.curvalue + 1;
     97 
     98 	trap_Cmd_ExecuteText( EXEC_APPEND, va("addbot %s %i %s %i\n",
     99 		addBotsMenuInfo.botnames[addBotsMenuInfo.selectedBotNum], skill, team, addBotsMenuInfo.delay) );
    100 
    101 	addBotsMenuInfo.delay += 1500;
    102 }
    103 
    104 
    105 /*
    106 =================
    107 UI_AddBotsMenu_BotEvent
    108 =================
    109 */
    110 static void UI_AddBotsMenu_BotEvent( void* ptr, int event ) {
    111 	if (event != QM_ACTIVATED) {
    112 		return;
    113 	}
    114 
    115 	addBotsMenuInfo.bots[addBotsMenuInfo.selectedBotNum].color = color_orange;
    116 	addBotsMenuInfo.selectedBotNum = ((menucommon_s*)ptr)->id - ID_BOTNAME0;
    117 	addBotsMenuInfo.bots[addBotsMenuInfo.selectedBotNum].color = color_white;
    118 }
    119 
    120 
    121 /*
    122 =================
    123 UI_AddBotsMenu_BackEvent
    124 =================
    125 */
    126 static void UI_AddBotsMenu_BackEvent( void* ptr, int event ) {
    127 	if (event != QM_ACTIVATED) {
    128 		return;
    129 	}
    130 	UI_PopMenu();
    131 }
    132 
    133 
    134 /*
    135 =================
    136 UI_AddBotsMenu_SetBotNames
    137 =================
    138 */
    139 static void UI_AddBotsMenu_SetBotNames( void ) {
    140 	int			n;
    141 	const char	*info;
    142 
    143 	for ( n = 0; n < 7; n++ ) {
    144 		info = UI_GetBotInfoByNumber( addBotsMenuInfo.sortedBotNums[addBotsMenuInfo.baseBotNum + n] );
    145 		Q_strncpyz( addBotsMenuInfo.botnames[n], Info_ValueForKey( info, "name" ), sizeof(addBotsMenuInfo.botnames[n]) );
    146 	}
    147 
    148 }
    149 
    150 
    151 /*
    152 =================
    153 UI_AddBotsMenu_UpEvent
    154 =================
    155 */
    156 static void UI_AddBotsMenu_UpEvent( void* ptr, int event ) {
    157 	if (event != QM_ACTIVATED) {
    158 		return;
    159 	}
    160 
    161 	if( addBotsMenuInfo.baseBotNum > 0 ) {
    162 		addBotsMenuInfo.baseBotNum--;
    163 		UI_AddBotsMenu_SetBotNames();
    164 	}
    165 }
    166 
    167 
    168 /*
    169 =================
    170 UI_AddBotsMenu_DownEvent
    171 =================
    172 */
    173 static void UI_AddBotsMenu_DownEvent( void* ptr, int event ) {
    174 	if (event != QM_ACTIVATED) {
    175 		return;
    176 	}
    177 
    178 	if( addBotsMenuInfo.baseBotNum + 7 < addBotsMenuInfo.numBots ) {
    179 		addBotsMenuInfo.baseBotNum++;
    180 		UI_AddBotsMenu_SetBotNames();
    181 	}
    182 }
    183 
    184 
    185 /*
    186 =================
    187 UI_AddBotsMenu_GetSortedBotNums
    188 =================
    189 */
    190 static int QDECL UI_AddBotsMenu_SortCompare( const void *arg1, const void *arg2 ) {
    191 	int			num1, num2;
    192 	const char	*info1, *info2;
    193 	const char	*name1, *name2;
    194 
    195 	num1 = *(int *)arg1;
    196 	num2 = *(int *)arg2;
    197 
    198 	info1 = UI_GetBotInfoByNumber( num1 );
    199 	info2 = UI_GetBotInfoByNumber( num2 );
    200 
    201 	name1 = Info_ValueForKey( info1, "name" );
    202 	name2 = Info_ValueForKey( info2, "name" );
    203 
    204 	return Q_stricmp( name1, name2 );
    205 }
    206 
    207 static void UI_AddBotsMenu_GetSortedBotNums( void ) {
    208 	int		n;
    209 
    210 	// initialize the array
    211 	for( n = 0; n < addBotsMenuInfo.numBots; n++ ) {
    212 		addBotsMenuInfo.sortedBotNums[n] = n;
    213 	}
    214 
    215 	qsort( addBotsMenuInfo.sortedBotNums, addBotsMenuInfo.numBots, sizeof(addBotsMenuInfo.sortedBotNums[0]), UI_AddBotsMenu_SortCompare );
    216 }
    217 
    218 
    219 /*
    220 =================
    221 UI_AddBotsMenu_Draw
    222 =================
    223 */
    224 static void UI_AddBotsMenu_Draw( void ) {
    225 	UI_DrawBannerString( 320, 16, "ADD BOTS", UI_CENTER, color_white );
    226 	UI_DrawNamedPic( 320-233, 240-166, 466, 332, ART_BACKGROUND );
    227 
    228 	// standard menu drawing
    229 	Menu_Draw( &addBotsMenuInfo.menu );
    230 }
    231 
    232 	
    233 /*
    234 =================
    235 UI_AddBotsMenu_Init
    236 =================
    237 */
    238 static const char *skillNames[] = {
    239 	"I Can Win",
    240 	"Bring It On",
    241 	"Hurt Me Plenty",
    242 	"Hardcore",
    243 	"Nightmare!",
    244 	0
    245 };
    246 
    247 static const char *teamNames1[] = {
    248 	"Free",
    249 	0
    250 };
    251 
    252 static const char *teamNames2[] = {
    253 	"Red",
    254 	"Blue",
    255 	0
    256 };
    257 
    258 static void UI_AddBotsMenu_Init( void ) {
    259 	int		n;
    260 	int		y;
    261 	int		gametype;
    262 	int		count;
    263 	char	info[MAX_INFO_STRING];
    264 
    265 	trap_GetConfigString(CS_SERVERINFO, info, MAX_INFO_STRING);   
    266 	gametype = atoi( Info_ValueForKey( info,"g_gametype" ) );
    267 
    268 	memset( &addBotsMenuInfo, 0 ,sizeof(addBotsMenuInfo) );
    269 	addBotsMenuInfo.menu.draw = UI_AddBotsMenu_Draw;
    270 	addBotsMenuInfo.menu.fullscreen = qfalse;
    271 	addBotsMenuInfo.menu.wrapAround = qtrue;
    272 	addBotsMenuInfo.delay = 1000;
    273 
    274 	UI_AddBots_Cache();
    275 
    276 	addBotsMenuInfo.numBots = UI_GetNumBots();
    277 	count = addBotsMenuInfo.numBots < 7 ? addBotsMenuInfo.numBots : 7;
    278 
    279 	addBotsMenuInfo.arrows.generic.type  = MTYPE_BITMAP;
    280 	addBotsMenuInfo.arrows.generic.name  = ART_ARROWS;
    281 	addBotsMenuInfo.arrows.generic.flags = QMF_INACTIVE;
    282 	addBotsMenuInfo.arrows.generic.x	 = 200;
    283 	addBotsMenuInfo.arrows.generic.y	 = 128;
    284 	addBotsMenuInfo.arrows.width  	     = 64;
    285 	addBotsMenuInfo.arrows.height  	     = 128;
    286 
    287 	addBotsMenuInfo.up.generic.type	    = MTYPE_BITMAP;
    288 	addBotsMenuInfo.up.generic.flags    = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
    289 	addBotsMenuInfo.up.generic.x		= 200;
    290 	addBotsMenuInfo.up.generic.y		= 128;
    291 	addBotsMenuInfo.up.generic.id	    = ID_UP;
    292 	addBotsMenuInfo.up.generic.callback = UI_AddBotsMenu_UpEvent;
    293 	addBotsMenuInfo.up.width  		    = 64;
    294 	addBotsMenuInfo.up.height  		    = 64;
    295 	addBotsMenuInfo.up.focuspic         = ART_ARROWUP;
    296 
    297 	addBotsMenuInfo.down.generic.type	  = MTYPE_BITMAP;
    298 	addBotsMenuInfo.down.generic.flags    = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
    299 	addBotsMenuInfo.down.generic.x		  = 200;
    300 	addBotsMenuInfo.down.generic.y		  = 128+64;
    301 	addBotsMenuInfo.down.generic.id	      = ID_DOWN;
    302 	addBotsMenuInfo.down.generic.callback = UI_AddBotsMenu_DownEvent;
    303 	addBotsMenuInfo.down.width  		  = 64;
    304 	addBotsMenuInfo.down.height  		  = 64;
    305 	addBotsMenuInfo.down.focuspic         = ART_ARROWDOWN;
    306 
    307 	for( n = 0, y = 120; n < count; n++, y += 20 ) {
    308 		addBotsMenuInfo.bots[n].generic.type		= MTYPE_PTEXT;
    309 		addBotsMenuInfo.bots[n].generic.flags		= QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
    310 		addBotsMenuInfo.bots[n].generic.id			= ID_BOTNAME0 + n;
    311 		addBotsMenuInfo.bots[n].generic.x			= 320 - 56;
    312 		addBotsMenuInfo.bots[n].generic.y			= y;
    313 		addBotsMenuInfo.bots[n].generic.callback	= UI_AddBotsMenu_BotEvent;
    314 		addBotsMenuInfo.bots[n].string				= addBotsMenuInfo.botnames[n];
    315 		addBotsMenuInfo.bots[n].color				= color_orange;
    316 		addBotsMenuInfo.bots[n].style				= UI_LEFT|UI_SMALLFONT;
    317 	}
    318 
    319 	y += 12;
    320 	addBotsMenuInfo.skill.generic.type		= MTYPE_SPINCONTROL;
    321 	addBotsMenuInfo.skill.generic.flags		= QMF_PULSEIFFOCUS|QMF_SMALLFONT;
    322 	addBotsMenuInfo.skill.generic.x			= 320;
    323 	addBotsMenuInfo.skill.generic.y			= y;
    324 	addBotsMenuInfo.skill.generic.name		= "Skill:";
    325 	addBotsMenuInfo.skill.generic.id		= ID_SKILL;
    326 	addBotsMenuInfo.skill.itemnames			= skillNames;
    327 	addBotsMenuInfo.skill.curvalue			= Com_Clamp( 0, 4, (int)trap_Cvar_VariableValue( "g_spSkill" ) - 1 );
    328 
    329 	y += SMALLCHAR_HEIGHT;
    330 	addBotsMenuInfo.team.generic.type		= MTYPE_SPINCONTROL;
    331 	addBotsMenuInfo.team.generic.flags		= QMF_PULSEIFFOCUS|QMF_SMALLFONT;
    332 	addBotsMenuInfo.team.generic.x			= 320;
    333 	addBotsMenuInfo.team.generic.y			= y;
    334 	addBotsMenuInfo.team.generic.name		= "Team: ";
    335 	addBotsMenuInfo.team.generic.id			= ID_TEAM;
    336 	if( gametype >= GT_TEAM ) {
    337 		addBotsMenuInfo.team.itemnames		= teamNames2;
    338 	}
    339 	else {
    340 		addBotsMenuInfo.team.itemnames		= teamNames1;
    341 		addBotsMenuInfo.team.generic.flags	= QMF_GRAYED;
    342 	}
    343 
    344 	addBotsMenuInfo.go.generic.type			= MTYPE_BITMAP;
    345 	addBotsMenuInfo.go.generic.name			= ART_FIGHT0;
    346 	addBotsMenuInfo.go.generic.flags		= QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
    347 	addBotsMenuInfo.go.generic.id			= ID_GO;
    348 	addBotsMenuInfo.go.generic.callback		= UI_AddBotsMenu_FightEvent;
    349 	addBotsMenuInfo.go.generic.x			= 320+128-128;
    350 	addBotsMenuInfo.go.generic.y			= 256+128-64;
    351 	addBotsMenuInfo.go.width  				= 128;
    352 	addBotsMenuInfo.go.height  				= 64;
    353 	addBotsMenuInfo.go.focuspic				= ART_FIGHT1;
    354 
    355 	addBotsMenuInfo.back.generic.type		= MTYPE_BITMAP;
    356 	addBotsMenuInfo.back.generic.name		= ART_BACK0;
    357 	addBotsMenuInfo.back.generic.flags		= QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
    358 	addBotsMenuInfo.back.generic.id			= ID_BACK;
    359 	addBotsMenuInfo.back.generic.callback	= UI_AddBotsMenu_BackEvent;
    360 	addBotsMenuInfo.back.generic.x			= 320-128;
    361 	addBotsMenuInfo.back.generic.y			= 256+128-64;
    362 	addBotsMenuInfo.back.width				= 128;
    363 	addBotsMenuInfo.back.height				= 64;
    364 	addBotsMenuInfo.back.focuspic			= ART_BACK1;
    365 
    366 	addBotsMenuInfo.baseBotNum = 0;
    367 	addBotsMenuInfo.selectedBotNum = 0;
    368 	addBotsMenuInfo.bots[0].color = color_white;
    369 
    370 	UI_AddBotsMenu_GetSortedBotNums();
    371 	UI_AddBotsMenu_SetBotNames();
    372 
    373 	Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.arrows );
    374 
    375 	Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.up );
    376 	Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.down );
    377 	for( n = 0; n < count; n++ ) {
    378 		Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.bots[n] );
    379 	}
    380 	Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.skill );
    381 	Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.team );
    382 	Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.go );
    383 	Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.back );
    384 }
    385 
    386 
    387 /*
    388 =================
    389 UI_AddBots_Cache
    390 =================
    391 */
    392 void UI_AddBots_Cache( void ) {
    393 	trap_R_RegisterShaderNoMip( ART_BACK0 );
    394 	trap_R_RegisterShaderNoMip( ART_BACK1 );
    395 	trap_R_RegisterShaderNoMip( ART_FIGHT0 );
    396 	trap_R_RegisterShaderNoMip( ART_FIGHT1 );
    397 	trap_R_RegisterShaderNoMip( ART_BACKGROUND );
    398 	trap_R_RegisterShaderNoMip( ART_ARROWS );
    399 	trap_R_RegisterShaderNoMip( ART_ARROWUP );
    400 	trap_R_RegisterShaderNoMip( ART_ARROWDOWN );
    401 }
    402 
    403 
    404 /*
    405 =================
    406 UI_AddBotsMenu
    407 =================
    408 */
    409 void UI_AddBotsMenu( void ) {
    410 	UI_AddBotsMenu_Init();
    411 	UI_PushMenu( &addBotsMenuInfo.menu );
    412 }