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 }