/* =========================================================================== Copyright (C) 1999-2005 Id Software, Inc. Copyright (C) 2002-2021 Q3Rally Team (Per Thormann - q3rally@gmail.com) This file is part of q3rally source code. q3rally source code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. q3rally source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with q3rally; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ // /* ============================================================================= SINGLE PLAYER SKILL MENU ============================================================================= */ #include "ui_local.h" #define ART_FRAME "menu/art/cut_frame" #define ART_BACK "menu/art/back_0.tga" #define ART_BACK_FOCUS "menu/art/back_1.tga" #define ART_FIGHT "menu/art/fight_0" #define ART_FIGHT_FOCUS "menu/art/fight_1" #define ART_MAP_COMPLETE1 "menu/art/level_complete1" #define ART_MAP_COMPLETE2 "menu/art/level_complete2" #define ART_MAP_COMPLETE3 "menu/art/level_complete3" #define ART_MAP_COMPLETE4 "menu/art/level_complete4" #define ART_MAP_COMPLETE5 "menu/art/level_complete5" #define ID_BABY 10 #define ID_EASY 11 #define ID_MEDIUM 12 #define ID_HARD 13 #define ID_NIGHTMARE 14 #define ID_BACK 15 #define ID_FIGHT 16 typedef struct { menuframework_s menu; menubitmap_s art_frame; menutext_s art_banner; menutext_s item_baby; menutext_s item_easy; menutext_s item_medium; menutext_s item_hard; menutext_s item_nightmare; menubitmap_s art_skillPic; menubitmap_s item_back; menubitmap_s item_fight; const char *arenaInfo; qhandle_t skillpics[5]; sfxHandle_t nightmareSound; sfxHandle_t silenceSound; } skillMenuInfo_t; static skillMenuInfo_t skillMenuInfo; static void SetSkillColor( int skill, vec4_t color ) { switch( skill ) { case 1: skillMenuInfo.item_baby.color = color; break; case 2: skillMenuInfo.item_easy.color = color; break; case 3: skillMenuInfo.item_medium.color = color; break; case 4: skillMenuInfo.item_hard.color = color; break; case 5: skillMenuInfo.item_nightmare.color = color; break; default: break; } } /* ================= UI_SPSkillMenu_SkillEvent ================= */ static void UI_SPSkillMenu_SkillEvent( void *ptr, int notification ) { int id; int skill; if (notification != QM_ACTIVATED) return; SetSkillColor( (int)trap_Cvar_VariableValue( "g_spSkill" ), color_red ); id = ((menucommon_s*)ptr)->id; skill = id - ID_BABY + 1; trap_Cvar_SetValue( "g_spSkill", skill ); SetSkillColor( skill, color_white ); skillMenuInfo.art_skillPic.shader = skillMenuInfo.skillpics[skill - 1]; if( id == ID_NIGHTMARE ) { trap_S_StartLocalSound( skillMenuInfo.nightmareSound, CHAN_ANNOUNCER ); } else { trap_S_StartLocalSound( skillMenuInfo.silenceSound, CHAN_ANNOUNCER ); } } /* ================= UI_SPSkillMenu_FightEvent ================= */ static void UI_SPSkillMenu_FightEvent( void *ptr, int notification ) { if (notification != QM_ACTIVATED) return; UI_SPArena_Start( skillMenuInfo.arenaInfo ); } /* ================= UI_SPSkillMenu_BackEvent ================= */ static void UI_SPSkillMenu_BackEvent( void* ptr, int notification ) { if (notification != QM_ACTIVATED) { return; } trap_S_StartLocalSound( skillMenuInfo.silenceSound, CHAN_ANNOUNCER ); UI_PopMenu(); } /* ================= UI_SPSkillMenu_Key ================= */ static sfxHandle_t UI_SPSkillMenu_Key( int key ) { if( key == K_MOUSE2 || key == K_ESCAPE ) { trap_S_StartLocalSound( skillMenuInfo.silenceSound, CHAN_ANNOUNCER ); } return Menu_DefaultKey( &skillMenuInfo.menu, key ); } /* ================= UI_SPSkillMenu_Cache ================= */ void UI_SPSkillMenu_Cache( void ) { trap_R_RegisterShaderNoMip( ART_FRAME ); trap_R_RegisterShaderNoMip( ART_BACK ); trap_R_RegisterShaderNoMip( ART_BACK_FOCUS ); trap_R_RegisterShaderNoMip( ART_FIGHT ); trap_R_RegisterShaderNoMip( ART_FIGHT_FOCUS ); skillMenuInfo.skillpics[0] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE1 ); skillMenuInfo.skillpics[1] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE2 ); skillMenuInfo.skillpics[2] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE3 ); skillMenuInfo.skillpics[3] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE4 ); skillMenuInfo.skillpics[4] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE5 ); skillMenuInfo.nightmareSound = trap_S_RegisterSound( "sound/misc/nightmare.wav", qfalse ); skillMenuInfo.silenceSound = trap_S_RegisterSound( "sound/misc/silence.wav", qfalse ); } /* ================= UI_SPSkillMenu_Init ================= */ static void UI_SPSkillMenu_Init( void ) { int skill; memset( &skillMenuInfo, 0, sizeof(skillMenuInfo) ); skillMenuInfo.menu.fullscreen = qtrue; skillMenuInfo.menu.key = UI_SPSkillMenu_Key; UI_SPSkillMenu_Cache(); skillMenuInfo.art_frame.generic.type = MTYPE_BITMAP; skillMenuInfo.art_frame.generic.name = ART_FRAME; skillMenuInfo.art_frame.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; skillMenuInfo.art_frame.generic.x = 142; skillMenuInfo.art_frame.generic.y = 118; skillMenuInfo.art_frame.width = 359; skillMenuInfo.art_frame.height = 256; skillMenuInfo.art_banner.generic.type = MTYPE_BTEXT; skillMenuInfo.art_banner.generic.flags = QMF_CENTER_JUSTIFY; skillMenuInfo.art_banner.generic.x = 320; skillMenuInfo.art_banner.generic.y = 16; skillMenuInfo.art_banner.string = "DIFFICULTY"; skillMenuInfo.art_banner.color = color_white; skillMenuInfo.art_banner.style = UI_CENTER; skillMenuInfo.item_baby.generic.type = MTYPE_PTEXT; skillMenuInfo.item_baby.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; skillMenuInfo.item_baby.generic.x = 320; skillMenuInfo.item_baby.generic.y = 170; skillMenuInfo.item_baby.generic.callback = UI_SPSkillMenu_SkillEvent; skillMenuInfo.item_baby.generic.id = ID_BABY; skillMenuInfo.item_baby.string = "I Can Win"; skillMenuInfo.item_baby.color = color_red; skillMenuInfo.item_baby.style = UI_CENTER; skillMenuInfo.item_easy.generic.type = MTYPE_PTEXT; skillMenuInfo.item_easy.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; skillMenuInfo.item_easy.generic.x = 320; skillMenuInfo.item_easy.generic.y = 198; skillMenuInfo.item_easy.generic.callback = UI_SPSkillMenu_SkillEvent; skillMenuInfo.item_easy.generic.id = ID_EASY; skillMenuInfo.item_easy.string = "Bring It On"; skillMenuInfo.item_easy.color = color_red; skillMenuInfo.item_easy.style = UI_CENTER; skillMenuInfo.item_medium.generic.type = MTYPE_PTEXT; skillMenuInfo.item_medium.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; skillMenuInfo.item_medium.generic.x = 320; skillMenuInfo.item_medium.generic.y = 227; skillMenuInfo.item_medium.generic.callback = UI_SPSkillMenu_SkillEvent; skillMenuInfo.item_medium.generic.id = ID_MEDIUM; skillMenuInfo.item_medium.string = "Hurt Me Plenty"; skillMenuInfo.item_medium.color = color_red; skillMenuInfo.item_medium.style = UI_CENTER; skillMenuInfo.item_hard.generic.type = MTYPE_PTEXT; skillMenuInfo.item_hard.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; skillMenuInfo.item_hard.generic.x = 320; skillMenuInfo.item_hard.generic.y = 255; skillMenuInfo.item_hard.generic.callback = UI_SPSkillMenu_SkillEvent; skillMenuInfo.item_hard.generic.id = ID_HARD; skillMenuInfo.item_hard.string = "Hardcore"; skillMenuInfo.item_hard.color = color_red; skillMenuInfo.item_hard.style = UI_CENTER; skillMenuInfo.item_nightmare.generic.type = MTYPE_PTEXT; skillMenuInfo.item_nightmare.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; skillMenuInfo.item_nightmare.generic.x = 320; skillMenuInfo.item_nightmare.generic.y = 283; skillMenuInfo.item_nightmare.generic.callback = UI_SPSkillMenu_SkillEvent; skillMenuInfo.item_nightmare.generic.id = ID_NIGHTMARE; skillMenuInfo.item_nightmare.string = "NIGHTMARE!"; skillMenuInfo.item_nightmare.color = color_red; skillMenuInfo.item_nightmare.style = UI_CENTER; skillMenuInfo.item_back.generic.type = MTYPE_BITMAP; skillMenuInfo.item_back.generic.name = ART_BACK; skillMenuInfo.item_back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; skillMenuInfo.item_back.generic.x = 0; skillMenuInfo.item_back.generic.y = 480-64; skillMenuInfo.item_back.generic.callback = UI_SPSkillMenu_BackEvent; skillMenuInfo.item_back.generic.id = ID_BACK; skillMenuInfo.item_back.width = 128; skillMenuInfo.item_back.height = 64; skillMenuInfo.item_back.focuspic = ART_BACK_FOCUS; skillMenuInfo.art_skillPic.generic.type = MTYPE_BITMAP; skillMenuInfo.art_skillPic.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; skillMenuInfo.art_skillPic.generic.x = 320-64; skillMenuInfo.art_skillPic.generic.y = 368; skillMenuInfo.art_skillPic.width = 128; skillMenuInfo.art_skillPic.height = 96; skillMenuInfo.item_fight.generic.type = MTYPE_BITMAP; skillMenuInfo.item_fight.generic.name = ART_FIGHT; skillMenuInfo.item_fight.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; skillMenuInfo.item_fight.generic.callback = UI_SPSkillMenu_FightEvent; skillMenuInfo.item_fight.generic.id = ID_FIGHT; skillMenuInfo.item_fight.generic.x = 640; skillMenuInfo.item_fight.generic.y = 480-64; skillMenuInfo.item_fight.width = 128; skillMenuInfo.item_fight.height = 64; skillMenuInfo.item_fight.focuspic = ART_FIGHT_FOCUS; Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_frame ); Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_banner ); Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_baby ); Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_easy ); Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_medium ); Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_hard ); Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_nightmare ); Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_skillPic ); Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_back ); Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_fight ); skill = (int)Com_Clamp( 1, 5, trap_Cvar_VariableValue( "g_spSkill" ) ); SetSkillColor( skill, color_white ); skillMenuInfo.art_skillPic.shader = skillMenuInfo.skillpics[skill - 1]; if( skill == 5 ) { trap_S_StartLocalSound( skillMenuInfo.nightmareSound, CHAN_ANNOUNCER ); } } void UI_SPSkillMenu( const char *arenaInfo ) { UI_SPSkillMenu_Init(); skillMenuInfo.arenaInfo = arenaInfo; UI_PushMenu( &skillMenuInfo.menu ); Menu_SetCursorToItem( &skillMenuInfo.menu, &skillMenuInfo.item_fight ); }