📄 ui_splevel.c
字号:
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena 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.
Quake III Arena 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//
/*
=============================================================================
SINGLE PLAYER LEVEL SELECT MENU
=============================================================================
*/
#include "ui_local.h"
#define ART_LEVELFRAME_FOCUS "menu/art/maps_select"
#define ART_LEVELFRAME_SELECTED "menu/art/maps_selected"
#define ART_ARROW "menu/art/narrow_0"
#define ART_ARROW_FOCUS "menu/art/narrow_1"
#define ART_MAP_UNKNOWN "menu/art/unknownmap"
#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 ART_BACK0 "menu/art/back_0"
#define ART_BACK1 "menu/art/back_1"
#define ART_FIGHT0 "menu/art/fight_0"
#define ART_FIGHT1 "menu/art/fight_1"
#define ART_RESET0 "menu/art/reset_0"
#define ART_RESET1 "menu/art/reset_1"
#define ART_CUSTOM0 "menu/art/skirmish_0"
#define ART_CUSTOM1 "menu/art/skirmish_1"
#define ID_LEFTARROW 10
#define ID_PICTURE0 11
#define ID_PICTURE1 12
#define ID_PICTURE2 13
#define ID_PICTURE3 14
#define ID_RIGHTARROW 15
#define ID_PLAYERPIC 16
#define ID_AWARD1 17
#define ID_AWARD2 18
#define ID_AWARD3 19
#define ID_AWARD4 20
#define ID_AWARD5 21
#define ID_AWARD6 22
#define ID_BACK 23
#define ID_RESET 24
#define ID_CUSTOM 25
#define ID_NEXT 26
#define PLAYER_Y 314
#define AWARDS_Y (PLAYER_Y + 26)
typedef struct {
menuframework_s menu;
menutext_s item_banner;
menubitmap_s item_leftarrow;
menubitmap_s item_maps[4];
menubitmap_s item_rightarrow;
menubitmap_s item_player;
menubitmap_s item_awards[6];
menubitmap_s item_back;
menubitmap_s item_reset;
menubitmap_s item_custom;
menubitmap_s item_next;
menubitmap_s item_null;
qboolean reinit;
const char * selectedArenaInfo;
int numMaps;
char levelPicNames[4][MAX_QPATH];
char levelNames[4][16];
int levelScores[4];
int levelScoresSkill[4];
qhandle_t levelSelectedPic;
qhandle_t levelFocusPic;
qhandle_t levelCompletePic[5];
char playerModel[MAX_QPATH];
char playerPicName[MAX_QPATH];
int awardLevels[6];
sfxHandle_t awardSounds[6];
int numBots;
qhandle_t botPics[7];
char botNames[7][10];
} levelMenuInfo_t;
static levelMenuInfo_t levelMenuInfo;
static int selectedArenaSet;
static int selectedArena;
static int currentSet;
static int currentGame;
static int trainingTier;
static int finalTier;
static int minTier;
static int maxTier;
/*
=================
PlayerIcon
=================
*/
static void PlayerIcon( const char *modelAndSkin, char *iconName, int iconNameMaxSize ) {
char *skin;
char model[MAX_QPATH];
Q_strncpyz( model, modelAndSkin, sizeof(model));
skin = Q_strrchr( model, '/' );
if ( skin ) {
*skin++ = '\0';
}
else {
skin = "default";
}
Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_%s.tga", model, skin );
if( !trap_R_RegisterShaderNoMip( iconName ) && Q_stricmp( skin, "default" ) != 0 ) {
Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_default.tga", model );
}
}
/*
=================
PlayerIconhandle
=================
*/
static qhandle_t PlayerIconHandle( const char *modelAndSkin ) {
char iconName[MAX_QPATH];
PlayerIcon( modelAndSkin, iconName, sizeof(iconName) );
return trap_R_RegisterShaderNoMip( iconName );
}
/*
=================
UI_SPLevelMenu_SetBots
=================
*/
static void UI_SPLevelMenu_SetBots( void ) {
char *p;
char *bot;
char *botInfo;
char bots[MAX_INFO_STRING];
levelMenuInfo.numBots = 0;
if ( selectedArenaSet > currentSet ) {
return;
}
Q_strncpyz( bots, Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "bots" ), sizeof(bots) );
p = &bots[0];
while( *p && levelMenuInfo.numBots < 7 ) {
//skip spaces
while( *p && *p == ' ' ) {
p++;
}
if( !p ) {
break;
}
// mark start of bot name
bot = p;
// skip until space of null
while( *p && *p != ' ' ) {
p++;
}
if( *p ) {
*p++ = 0;
}
botInfo = UI_GetBotInfoByName( bot );
if( botInfo ) {
levelMenuInfo.botPics[levelMenuInfo.numBots] = PlayerIconHandle( Info_ValueForKey( botInfo, "model" ) );
Q_strncpyz( levelMenuInfo.botNames[levelMenuInfo.numBots], Info_ValueForKey( botInfo, "name" ), 10 );
}
else {
levelMenuInfo.botPics[levelMenuInfo.numBots] = 0;
Q_strncpyz( levelMenuInfo.botNames[levelMenuInfo.numBots], bot, 10 );
}
Q_CleanStr( levelMenuInfo.botNames[levelMenuInfo.numBots] );
levelMenuInfo.numBots++;
}
}
/*
=================
UI_SPLevelMenu_SetMenuItems
=================
*/
static void UI_SPLevelMenu_SetMenuArena( int n, int level, const char *arenaInfo ) {
char map[MAX_QPATH];
Q_strncpyz( map, Info_ValueForKey( arenaInfo, "map" ), sizeof(map) );
Q_strncpyz( levelMenuInfo.levelNames[n], map, sizeof(levelMenuInfo.levelNames[n]) );
Q_strupr( levelMenuInfo.levelNames[n] );
UI_GetBestScore( level, &levelMenuInfo.levelScores[n], &levelMenuInfo.levelScoresSkill[n] );
if( levelMenuInfo.levelScores[n] > 8 ) {
levelMenuInfo.levelScores[n] = 8;
}
strcpy( levelMenuInfo.levelPicNames[n], va( "levelshots/%s.tga", map ) );
if( !trap_R_RegisterShaderNoMip( levelMenuInfo.levelPicNames[n] ) ) {
strcpy( levelMenuInfo.levelPicNames[n], ART_MAP_UNKNOWN );
}
levelMenuInfo.item_maps[n].shader = 0;
if ( selectedArenaSet > currentSet ) {
levelMenuInfo.item_maps[n].generic.flags |= QMF_GRAYED;
}
else {
levelMenuInfo.item_maps[n].generic.flags &= ~QMF_GRAYED;
}
levelMenuInfo.item_maps[n].generic.flags &= ~QMF_INACTIVE;
}
static void UI_SPLevelMenu_SetMenuItems( void ) {
int n;
int level;
const char *arenaInfo;
if ( selectedArenaSet > currentSet ) {
selectedArena = -1;
}
else if ( selectedArena == -1 ) {
selectedArena = 0;
}
if( selectedArenaSet == trainingTier || selectedArenaSet == finalTier ) {
selectedArena = 0;
}
if( selectedArena != -1 ) {
trap_Cvar_SetValue( "ui_spSelection", selectedArenaSet * ARENAS_PER_TIER + selectedArena );
}
if( selectedArenaSet == trainingTier ) {
arenaInfo = UI_GetSpecialArenaInfo( "training" );
level = atoi( Info_ValueForKey( arenaInfo, "num" ) );
UI_SPLevelMenu_SetMenuArena( 0, level, arenaInfo );
levelMenuInfo.selectedArenaInfo = arenaInfo;
levelMenuInfo.item_maps[0].generic.x = 256;
Bitmap_Init( &levelMenuInfo.item_maps[0] );
levelMenuInfo.item_maps[0].generic.bottom += 32;
levelMenuInfo.numMaps = 1;
levelMenuInfo.item_maps[1].generic.flags |= QMF_INACTIVE;
levelMenuInfo.item_maps[2].generic.flags |= QMF_INACTIVE;
levelMenuInfo.item_maps[3].generic.flags |= QMF_INACTIVE;
levelMenuInfo.levelPicNames[1][0] = 0;
levelMenuInfo.levelPicNames[2][0] = 0;
levelMenuInfo.levelPicNames[3][0] = 0;
levelMenuInfo.item_maps[1].shader = 0;
levelMenuInfo.item_maps[2].shader = 0;
levelMenuInfo.item_maps[3].shader = 0;
}
else if( selectedArenaSet == finalTier ) {
arenaInfo = UI_GetSpecialArenaInfo( "final" );
level = atoi( Info_ValueForKey( arenaInfo, "num" ) );
UI_SPLevelMenu_SetMenuArena( 0, level, arenaInfo );
levelMenuInfo.selectedArenaInfo = arenaInfo;
levelMenuInfo.item_maps[0].generic.x = 256;
Bitmap_Init( &levelMenuInfo.item_maps[0] );
levelMenuInfo.item_maps[0].generic.bottom += 32;
levelMenuInfo.numMaps = 1;
levelMenuInfo.item_maps[1].generic.flags |= QMF_INACTIVE;
levelMenuInfo.item_maps[2].generic.flags |= QMF_INACTIVE;
levelMenuInfo.item_maps[3].generic.flags |= QMF_INACTIVE;
levelMenuInfo.levelPicNames[1][0] = 0;
levelMenuInfo.levelPicNames[2][0] = 0;
levelMenuInfo.levelPicNames[3][0] = 0;
levelMenuInfo.item_maps[1].shader = 0;
levelMenuInfo.item_maps[2].shader = 0;
levelMenuInfo.item_maps[3].shader = 0;
}
else {
levelMenuInfo.item_maps[0].generic.x = 46;
Bitmap_Init( &levelMenuInfo.item_maps[0] );
levelMenuInfo.item_maps[0].generic.bottom += 18;
levelMenuInfo.numMaps = 4;
for ( n = 0; n < 4; n++ ) {
level = selectedArenaSet * ARENAS_PER_TIER + n;
arenaInfo = UI_GetArenaInfoByNumber( level );
UI_SPLevelMenu_SetMenuArena( n, level, arenaInfo );
}
if( selectedArena != -1 ) {
levelMenuInfo.selectedArenaInfo = UI_GetArenaInfoByNumber( selectedArenaSet * ARENAS_PER_TIER + selectedArena );
}
}
// enable/disable arrows when they are valid/invalid
if ( selectedArenaSet == minTier ) {
levelMenuInfo.item_leftarrow.generic.flags |= ( QMF_INACTIVE | QMF_HIDDEN );
}
else {
levelMenuInfo.item_leftarrow.generic.flags &= ~( QMF_INACTIVE | QMF_HIDDEN );
}
if ( selectedArenaSet == maxTier ) {
levelMenuInfo.item_rightarrow.generic.flags |= ( QMF_INACTIVE | QMF_HIDDEN );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -