[PlayerStats]: Added new module.
This commit is contained in:
parent
22ecd2c816
commit
3f8b1a231f
@ -124,6 +124,33 @@ LANG_ENGLISH "Kills"
|
||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||
LANG_ENGLISH "Total Play Time"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_MELEE
|
||||
LANG_ENGLISH "Melee Kills"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_VEHICLES
|
||||
LANG_ENGLISH "Vehicle Killed"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_EXPLOSIVES
|
||||
LANG_ENGLISH "Explosives Kills"
|
||||
|
||||
REFERENCE MENU_CAREER_ACCURACY
|
||||
LANG_ENGLISH "Accuracy"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_STATS
|
||||
LANG_ENGLISH "Singleplayer Stats"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_COMPLETED
|
||||
LANG_ENGLISH "Campaign Completed"
|
||||
|
||||
REFERENCE MENU_CAREER_INTEL
|
||||
LANG_ENGLISH "Intel"
|
||||
|
||||
REFERENCE MENU_CAREER_ACHIEVEMENT_UNLOCKED
|
||||
LANG_ENGLISH "Achievements"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_PROGRESS
|
||||
LANG_ENGLISH "Campaign Progress"
|
||||
|
||||
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||
LANG_ENGLISH "D H M S"
|
||||
|
||||
|
@ -124,6 +124,33 @@ LANG_FRENCH "Tu
|
||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||
LANG_FRENCH "Temps total de jeu"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_MELEE
|
||||
LANG_FRENCH "Éliminations au corps à corps"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_VEHICLES
|
||||
LANG_FRENCH "Véhicules détruits"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_EXPLOSIVES
|
||||
LANG_FRENCH "Éliminations aux explosifs"
|
||||
|
||||
REFERENCE MENU_CAREER_ACCURACY
|
||||
LANG_FRENCH "Précision"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_STATS
|
||||
LANG_FRENCH "Statistiques solo"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_COMPLETED
|
||||
LANG_FRENCH "Campagne terminée"
|
||||
|
||||
REFERENCE MENU_CAREER_INTEL
|
||||
LANG_FRENCH "Renseignements"
|
||||
|
||||
REFERENCE MENU_CAREER_ACHIEVEMENT_UNLOCKED
|
||||
LANG_FRENCH "Succès débloqués"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_PROGRESS
|
||||
LANG_FRENCH "Avancement de la campagne"
|
||||
|
||||
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||
LANG_FRENCH "J H M S"
|
||||
|
||||
|
@ -130,6 +130,33 @@ LANG_GERMAN "Absch"
|
||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||
LANG_GERMAN "Gesamte Spielzeit"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_MELEE
|
||||
LANG_GERMAN "Nahkampf-Tötungen"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_VEHICLES
|
||||
LANG_GERMAN "Fahrzeuge zerstört"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_EXPLOSIVES
|
||||
LANG_GERMAN "Explosiv-Tötungen"
|
||||
|
||||
REFERENCE MENU_CAREER_ACCURACY
|
||||
LANG_GERMAN "Genauigkeit"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_STATS
|
||||
LANG_GERMAN "Einzelspieler-Statistiken"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_COMPLETED
|
||||
LANG_GERMAN "Kampagne abgeschlossen"
|
||||
|
||||
REFERENCE MENU_CAREER_INTEL
|
||||
LANG_GERMAN "Informationen"
|
||||
|
||||
REFERENCE MENU_CAREER_ACHIEVEMENT_UNLOCKED
|
||||
LANG_GERMAN "Errungenschaften"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_PROGRESS
|
||||
LANG_GERMAN "Kampagnenfortschritt"
|
||||
|
||||
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||
LANG_GERMAN "T S M S"
|
||||
|
||||
|
@ -124,6 +124,33 @@ LANG_ITALIAN "Uccisioni"
|
||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||
LANG_ITALIAN "Tempo di gioco totale"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_MELEE
|
||||
LANG_ITALIAN "Uccisioni con corpo a corpo"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_VEHICLES
|
||||
LANG_ITALIAN "Veicoli distrutti"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_EXPLOSIVES
|
||||
LANG_ITALIAN "Uccisioni con esplosivi"
|
||||
|
||||
REFERENCE MENU_CAREER_ACCURACY
|
||||
LANG_ITALIAN "Precisione"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_STATS
|
||||
LANG_ITALIAN "Statistiche giocatore singolo"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_COMPLETED
|
||||
LANG_ITALIAN "Campagna completata"
|
||||
|
||||
REFERENCE MENU_CAREER_INTEL
|
||||
LANG_ITALIAN "Informazioni"
|
||||
|
||||
REFERENCE MENU_CAREER_ACHIEVEMENT_UNLOCKED
|
||||
LANG_ITALIAN "Obiettivi sbloccati"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_PROGRESS
|
||||
LANG_ITALIAN "Progresso campagna"
|
||||
|
||||
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||
LANG_ITALIAN "G O M S"
|
||||
|
||||
|
@ -124,6 +124,33 @@ LANG_PORTUGUESE "Kills"
|
||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||
LANG_PORTUGUESE "Total Play Time"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_MELEE
|
||||
LANG_PORTUGUESE "Melee Kills"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_VEHICLES
|
||||
LANG_PORTUGUESE "Vehicle Killed"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_EXPLOSIVES
|
||||
LANG_PORTUGUESE "Explosives Kills"
|
||||
|
||||
REFERENCE MENU_CAREER_ACCURACY
|
||||
LANG_PORTUGUESE "Accuracy"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_STATS
|
||||
LANG_PORTUGUESE "Singleplayer Stats"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_COMPLETED
|
||||
LANG_PORTUGUESE "Campaign Completed"
|
||||
|
||||
REFERENCE MENU_CAREER_INTEL
|
||||
LANG_PORTUGUESE "Intel"
|
||||
|
||||
REFERENCE MENU_CAREER_ACHIEVEMENT_UNLOCKED
|
||||
LANG_PORTUGUESE "Achievements"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_PROGRESS
|
||||
LANG_PORTUGUESE "Campaign Progress"
|
||||
|
||||
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||
LANG_PORTUGUESE "D H M S"
|
||||
|
||||
|
@ -121,6 +121,33 @@ LANG_RUSSIAN "
|
||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||
LANG_RUSSIAN "Èãðîâîå âðåìÿ"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_MELEE
|
||||
LANG_RUSSIAN "Óáèéñòâà â áëèæíåì áîþ"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_VEHICLES
|
||||
LANG_RUSSIAN "Óíè÷òîæåííûå òðàíñïîðòíûå ñðåäñòâà"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_EXPLOSIVES
|
||||
LANG_RUSSIAN "Óáèéñòâà âçðûâ÷àòêîé"
|
||||
|
||||
REFERENCE MENU_CAREER_ACCURACY
|
||||
LANG_RUSSIAN "Òî÷íîñòü"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_STATS
|
||||
LANG_RUSSIAN "Ñòàòèñòèêà îäèíî÷íîé èãðû"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_COMPLETED
|
||||
LANG_RUSSIAN "Êàìïàíèèÿ çàâåðøåíà"
|
||||
|
||||
REFERENCE MENU_CAREER_INTEL
|
||||
LANG_RUSSIAN "Ñâåäåíèÿ"
|
||||
|
||||
REFERENCE MENU_CAREER_ACHIEVEMENT_UNLOCKED
|
||||
LANG_RUSSIAN "Äîñòèæåíèÿ"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_PROGRESS
|
||||
LANG_RUSSIAN "Ïðîãðåññ êàìïàíèè"
|
||||
|
||||
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||
LANG_RUSSIAN "Ä × Ì Ñ"
|
||||
|
||||
|
@ -114,6 +114,33 @@ LANG_SLOVAK "Kills"
|
||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||
LANG_SLOVAK "Total Play Time"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_MELEE
|
||||
LANG_SLOVAK "Melee Kills"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_VEHICLES
|
||||
LANG_SLOVAK "Vehicle Killed"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_EXPLOSIVES
|
||||
LANG_SLOVAK "Explosives Kills"
|
||||
|
||||
REFERENCE MENU_CAREER_ACCURACY
|
||||
LANG_SLOVAK "Accuracy"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_STATS
|
||||
LANG_SLOVAK "Singleplayer Stats"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_COMPLETED
|
||||
LANG_SLOVAK "Campaign Completed"
|
||||
|
||||
REFERENCE MENU_CAREER_INTEL
|
||||
LANG_SLOVAK "Intel"
|
||||
|
||||
REFERENCE MENU_CAREER_ACHIEVEMENT_UNLOCKED
|
||||
LANG_SLOVAK "Achievements"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_PROGRESS
|
||||
LANG_SLOVAK "Campaign Progress"
|
||||
|
||||
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||
LANG_SLOVAK "D H M S"
|
||||
|
||||
|
@ -125,6 +125,33 @@ LANG_SPANISH "Asesinatos"
|
||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||
LANG_SPANISH "Tiempo total de juego"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_MELEE
|
||||
LANG_SPANISH "Muertes cuerpo a cuerpo"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_VEHICLES
|
||||
LANG_SPANISH "Vehículos destruidos"
|
||||
|
||||
REFERENCE MENU_CAREER_KILLS_EXPLOSIVES
|
||||
LANG_SPANISH "Muertes por explosivos"
|
||||
|
||||
REFERENCE MENU_CAREER_ACCURACY
|
||||
LANG_SPANISH "Precisión"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_STATS
|
||||
LANG_SPANISH "Estadísticas de un jugador"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_COMPLETED
|
||||
LANG_SPANISH "Campaña completada"
|
||||
|
||||
REFERENCE MENU_CAREER_INTEL
|
||||
LANG_SPANISH "Información"
|
||||
|
||||
REFERENCE MENU_CAREER_ACHIEVEMENT_UNLOCKED
|
||||
LANG_SPANISH "Logros desbloqueados"
|
||||
|
||||
REFERENCE MENU_CAREER_SP_PROGRESS
|
||||
LANG_SPANISH "Progreso de campaña"
|
||||
|
||||
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||
LANG_SPANISH "D H M S"
|
||||
|
||||
|
@ -279,8 +279,8 @@
|
||||
CHOICE_DBUTTON_VIS( 5, "@MENU_ARCADEMODE", when( dvarInt( mis_01 ) < 20 && !localvarBool( ui_hideBack ) ); )
|
||||
// CHOICE_BUTTON_VIS( 5, "@MENU_ARCADEMODE", open popmenu_arcade; LOCAL_ARCADE_RESET, when( dvarInt( mis_01 ) >= 20 && !localvarBool( ui_hideBack ) ); )
|
||||
// CHOICE_DBUTTON_VIS( 5, "@MENU_ARCADEMODE", when( dvarInt( mis_01 ) < 20 && !localvarBool( ui_hideBack ) ); )
|
||||
CHOICE_BUTTON_VIS( 6, "@IW3SP_MOD_LOC_MENU_ACHIEVEMENTS", uiScript achievement_progressbar; open achievements; LOCAL_ARCADE_RESET, when( !localvarBool( ui_hideBack ) ); )
|
||||
//CHOICE_BUTTON_VIS( 6, "@IW3SP_MOD_LOC_MENU_STATS", open stats; LOCAL_ARCADE_RESET, when( !localvarBool( ui_hideBack ) ); )
|
||||
//CHOICE_BUTTON_VIS( 6, "@IW3SP_MOD_LOC_MENU_ACHIEVEMENTS", uiScript achievement_progressbar; open achievements; LOCAL_ARCADE_RESET, when( !localvarBool( ui_hideBack ) ); )
|
||||
CHOICE_BUTTON_VIS( 6, "@IW3SP_MOD_LOC_MENU_STATS", uiScript get_career_info; open stats; LOCAL_ARCADE_RESET, when( !localvarBool( ui_hideBack ) ); )
|
||||
CHOICE_SEPARATOR_VIS( CHOICE_SEP_1, when( !localvarBool( ui_hideBack ) ); )
|
||||
CHOICE_BUTTON_VIS( 7, "@MENU_CONTROLS", open iw3sp_mod_controls_pc_main /*open options_look*/;, when( !localvarBool( ui_hideBack ) ); )
|
||||
CHOICE_BUTTON_VIS( 8, "@MENU_OPTIONS", open options_graphics;, when( !localvarBool( ui_hideBack ) ); )
|
||||
|
@ -77,14 +77,15 @@ itemDef { \
|
||||
visible visArg \
|
||||
decoration }
|
||||
|
||||
#define PREPROC_VALUE_TEXT( ptext, itemNumber, px_offset, pcolor ) \
|
||||
PREPROC_VALUE_TEXT_VIS( ptext, itemNumber, px_offset, pcolor, 1, ITEM_ALIGN_MIDDLE_RIGHT )
|
||||
#define PREPROC_VALUE_TEXT( pname, ptext, itemNumber, px_offset, pcolor ) \
|
||||
PREPROC_VALUE_TEXT_VIS( pname, ptext, itemNumber, px_offset, pcolor, 1, ITEM_ALIGN_MIDDLE_RIGHT )
|
||||
|
||||
#define PREPROC_VALUE_TEXT_LEFT_ALIGNED( ptext, itemNumber, px_offset, pcolor ) \
|
||||
PREPROC_VALUE_TEXT_VIS( ptext, itemNumber, px_offset, pcolor, 1, ITEM_ALIGN_MIDDLE_LEFT )
|
||||
#define PREPROC_VALUE_TEXT_LEFT_ALIGNED( pname, ptext, itemNumber, px_offset, pcolor ) \
|
||||
PREPROC_VALUE_TEXT_VIS( pname, ptext, itemNumber, px_offset, pcolor, 1, ITEM_ALIGN_MIDDLE_LEFT )
|
||||
|
||||
#define PREPROC_VALUE_TEXT_VIS( ptext, itemNumber, px_offset, pcolor, visArg, alignment ) \
|
||||
#define PREPROC_VALUE_TEXT_VIS( pname, ptext, itemNumber, px_offset, pcolor, visArg, alignment ) \
|
||||
itemDef { \
|
||||
name pname \
|
||||
text ptext; \
|
||||
type ITEM_TYPE_TEXT \
|
||||
rect ORIGIN_LABEL_ITEM( itemNumber ) (PLAYERSTATS_WIDTH) LABEL_ITEM_SPACING RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP \
|
||||
@ -98,6 +99,7 @@ itemDef { \
|
||||
visible visArg \
|
||||
decoration }
|
||||
|
||||
/*
|
||||
itemDef
|
||||
{
|
||||
type ITEM_TYPE_TEXT
|
||||
@ -112,6 +114,7 @@ itemDef { \
|
||||
visible 1
|
||||
decoration
|
||||
}
|
||||
*/
|
||||
|
||||
// UI art
|
||||
PREPROC_SHADER_DRAW_ALIGNED( -4 12 (PLAYERSTATS_WIDTH+8) 326 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", FRAME_BG_COLOR, 0, 0, 0 0 0 0 )
|
||||
@ -150,24 +153,39 @@ itemDef { \
|
||||
|
||||
//kills
|
||||
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_KILLS", 1)
|
||||
PREPROC_VALUE_TEXT( 228, 1, -24, LABEL_TITLECOLOR )
|
||||
PREPROC_VALUE_TEXT( "kills", "", 1, -24, LABEL_TITLECOLOR )
|
||||
|
||||
//headshots
|
||||
PREPROC_SUB_LABEL( "@IW3SP_MOD_LOC_MENU_CAREER_HEADSHOTS", 2 )
|
||||
PREPROC_VALUE_TEXT( 228, 2, -24, LABEL_TEXTCOLOR )
|
||||
PREPROC_VALUE_TEXT( "headshots", "", 2, -24, LABEL_TEXTCOLOR )
|
||||
|
||||
//melee kills
|
||||
PREPROC_SUB_LABEL( "@IW3SP_MOD_LOC_MENU_CAREER_KILLS_MELEE", 3 )
|
||||
PREPROC_VALUE_TEXT( "kills_melee", "", 3, -24, LABEL_TEXTCOLOR )
|
||||
|
||||
//vehicle kills
|
||||
// PREPROC_SUB_LABEL( "@IW3SP_MOD_LOC_MENU_CAREER_KILLS_VEHICLES", 4 )
|
||||
// PREPROC_VALUE_TEXT( "kills_vehicle", "", 4, -24, LABEL_TEXTCOLOR )
|
||||
|
||||
//explosives kills
|
||||
PREPROC_SUB_LABEL( "@IW3SP_MOD_LOC_MENU_CAREER_KILLS_EXPLOSIVES", 4 )
|
||||
PREPROC_VALUE_TEXT( "kills_explosives", "", 4, -24, LABEL_TEXTCOLOR )
|
||||
|
||||
//deaths
|
||||
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_DEATHS", 3)
|
||||
PREPROC_VALUE_TEXT( 228, 3, -24, LABEL_TITLECOLOR )
|
||||
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_DEATHS", 5)
|
||||
PREPROC_VALUE_TEXT( "deaths", "", 5, -24, LABEL_TITLECOLOR )
|
||||
|
||||
PREPROC_DIVIDER( 4 )
|
||||
//accuracy
|
||||
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_ACCURACY", 6)
|
||||
PREPROC_VALUE_TEXT( "accuracy", "", 6, -24, LABEL_TITLECOLOR )
|
||||
|
||||
PREPROC_DIVIDER( 7 )
|
||||
|
||||
//play time (add as the last element in player info)
|
||||
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_PLAYTIMESP", 5)
|
||||
PREPROC_VALUE_TEXT( "0:00:00:00", 5, -24, LABEL_TITLECOLOR )
|
||||
PREPROC_LABEL_TIME("@IW3SP_MOD_LOC_MENU_SP_STAT_TIME_FORMAT", 4.4)
|
||||
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_PLAYTIMESP", 8)
|
||||
PREPROC_VALUE_TEXT( "playedtime", "", 8, -24, LABEL_TITLECOLOR )
|
||||
|
||||
PREPROC_DIVIDER( 6 )
|
||||
PREPROC_DIVIDER( 9 )
|
||||
|
||||
//for sliders
|
||||
//145(18) - 185 (40) - 8
|
||||
@ -181,33 +199,69 @@ itemDef { \
|
||||
//289(18) - 439 (40) - 16
|
||||
//307(18) - 479 (40) - 17
|
||||
|
||||
PREPROC_LABEL("Campaign Progress", 7)
|
||||
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_SP_STATS", 10)
|
||||
|
||||
PREPROC_SUB_LABEL( "Recruit Progress:", 8 )
|
||||
PREPROC_SHADER_DRAW_ALIGNED_VIS( 200 145 60 14 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", 0.1 0.1 0.1 0.35, 1, 1, 1 1 1 0.2, 1 )
|
||||
PREPROC_SHADER_DRAW_ADV_VIS( (PLAYERSTATS_X+202), /*167*/(PLAYERSTATS_Y+147), 50, 12, "gradient_fadein", 1 0.9 0.5 0.6, 0, 1, 1 1 1 1 rect 0 0 0 0 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, 1 )
|
||||
PREPROC_SUB_LABEL( "@IW3SP_MOD_LOC_MENU_CAREER_SP_COMPLETED", 11 )
|
||||
PREPROC_VALUE_TEXT( "difficulty", "", 11, -24, LABEL_TEXTCOLOR )
|
||||
|
||||
PREPROC_SUB_LABEL( "Regular Progress:", 9 )
|
||||
PREPROC_SHADER_DRAW_ALIGNED_VIS( 200 163 60 14 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", 0.1 0.1 0.1 0.35, 1, 1, 1 1 1 0.2, 1 )
|
||||
PREPROC_SHADER_DRAW_ADV_VIS( (PLAYERSTATS_X+202), /*167*/(PLAYERSTATS_Y+165), 50, 12, "gradient_fadein", 1 0.9 0.5 0.6, 0, 1, 1 1 1 1 rect 0 0 0 0 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, 1 )
|
||||
PREPROC_SUB_LABEL( "@IW3SP_MOD_LOC_MENU_CAREER_INTEL", 12 )
|
||||
PREPROC_VALUE_TEXT( "intels", "", 12, -24, LABEL_TEXTCOLOR )
|
||||
|
||||
PREPROC_SUB_LABEL( "Hardened Progress:", 10 )
|
||||
PREPROC_SHADER_DRAW_ALIGNED_VIS( 200 181 60 14 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", 0.1 0.1 0.1 0.35, 1, 1, 1 1 1 0.2, 1 )
|
||||
PREPROC_SHADER_DRAW_ADV_VIS( (PLAYERSTATS_X+202), /*167*/(PLAYERSTATS_Y+183), 50, 12, "gradient_fadein", 1 0.9 0.5 0.6, 0, 1, 1 1 1 1 rect 0 0 0 0 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, 1 )
|
||||
PREPROC_SUB_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_ACHIEVEMENT_UNLOCKED", 13)
|
||||
PREPROC_VALUE_TEXT( "achievements", "", 13, -24, LABEL_TEXTCOLOR )
|
||||
|
||||
PREPROC_SUB_LABEL( "Veteran Progress:", 11 )
|
||||
PREPROC_SHADER_DRAW_ALIGNED_VIS( 200 199 60 14 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", 0.1 0.1 0.1 0.35, 1, 1, 1 1 1 0.2, 1 )
|
||||
PREPROC_SHADER_DRAW_ADV_VIS( (PLAYERSTATS_X+202), /*167*/(PLAYERSTATS_Y+201), 50, 12, "gradient_fadein", 1 0.9 0.5 0.6, 0, 1, 1 1 1 1 rect 0 0 0 0 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, 1 )
|
||||
PREPROC_DIVIDER( 14 )
|
||||
|
||||
PREPROC_DIVIDER( 12 )
|
||||
PREPROC_LABEL( "@IW3SP_MOD_LOC_MENU_CAREER_SP_PROGRESS", 15 )
|
||||
PREPROC_VALUE_TEXT( "campaign_progress", "", 15, -24, LABEL_TITLECOLOR )
|
||||
//PREPROC_SHADER_DRAW_ALIGNED_VIS( 200 271 60 14 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", 0.1 0.1 0.1 0.35, 1, 1, 1 1 1 0.2, 1 )
|
||||
//PREPROC_SHADER_DRAW_ADV_VIS( "campaign_progressbar", (PLAYERSTATS_X+202), /*167*/(PLAYERSTATS_Y+273), 50, 12, "gradient_fadein", 1 0.9 0.5 0.6, 0, 1, 1 1 1 1 rect 0 0 0 0 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, 1 )
|
||||
|
||||
PREPROC_LABEL("Intel Items", 13)
|
||||
PREPROC_VALUE_TEXT( 17, 13, -24, LABEL_TITLECOLOR )
|
||||
PREPROC_LABEL("Achievement Unlocked", 14)
|
||||
PREPROC_VALUE_TEXT( 35, 14, -24, LABEL_TITLECOLOR )
|
||||
//#define PREPROC_SHADER_DRAW_ADV_VIS( pname, px, py, pw, ph, pshader, pcolor, pborder, pbordersize, pbordercolor, visArg )
|
||||
|
||||
PREPROC_DIVIDER( 15 )
|
||||
//itemDef
|
||||
//{
|
||||
// name "campaign_progressbar"
|
||||
// style WINDOW_STYLE_SHADER
|
||||
// rect 0 0 0 12 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP
|
||||
// exp rect X( PLAYERSTATS_X+202 )
|
||||
// exp rect Y( PLAYERSTATS_Y+273 )
|
||||
// forecolor 1 0.9 0.5 0.6
|
||||
// exp material( "gradient_fadein" );
|
||||
// border 0
|
||||
// bordersize 1
|
||||
// bordercolor 1 1 1 1
|
||||
// visible visArg
|
||||
// decoration
|
||||
//}
|
||||
|
||||
PREPROC_SUB_LABEL( "Campaign Progress:", 16 )
|
||||
PREPROC_SHADER_DRAW_ALIGNED_VIS( 200 289 60 14 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", 0.1 0.1 0.1 0.35, 1, 1, 1 1 1 0.2, 1 )
|
||||
PREPROC_SHADER_DRAW_ADV_VIS( (PLAYERSTATS_X+202), /*167*/(PLAYERSTATS_Y+291), 50, 12, "gradient_fadein", 1 0.9 0.5 0.6, 0, 1, 1 1 1 1 rect 0 0 0 0 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, 1 )
|
||||
|
||||
// OLD!!!!
|
||||
// PREPROC_SUB_LABEL( "Recruit Progress:", 8 )
|
||||
// PREPROC_SHADER_DRAW_ALIGNED_VIS( 200 145 60 14 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", 0.1 0.1 0.1 0.35, 1, 1, 1 1 1 0.2, 1 )
|
||||
// PREPROC_SHADER_DRAW_ADV_VIS( (PLAYERSTATS_X+202), /*167*/(PLAYERSTATS_Y+147), 50, 12, "gradient_fadein", 1 0.9 0.5 0.6, 0, 1, 1 1 1 1 rect 0 0 0 0 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, 1 )
|
||||
|
||||
// PREPROC_SUB_LABEL( "Regular Progress:", 9 )
|
||||
// PREPROC_SHADER_DRAW_ALIGNED_VIS( 200 163 60 14 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", 0.1 0.1 0.1 0.35, 1, 1, 1 1 1 0.2, 1 )
|
||||
// PREPROC_SHADER_DRAW_ADV_VIS( (PLAYERSTATS_X+202), /*167*/(PLAYERSTATS_Y+165), 50, 12, "gradient_fadein", 1 0.9 0.5 0.6, 0, 1, 1 1 1 1 rect 0 0 0 0 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, 1 )
|
||||
|
||||
// PREPROC_SUB_LABEL( "Hardened Progress:", 10 )
|
||||
// PREPROC_SHADER_DRAW_ALIGNED_VIS( 200 181 60 14 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", 0.1 0.1 0.1 0.35, 1, 1, 1 1 1 0.2, 1 )
|
||||
// PREPROC_SHADER_DRAW_ADV_VIS( (PLAYERSTATS_X+202), /*167*/(PLAYERSTATS_Y+183), 50, 12, "gradient_fadein", 1 0.9 0.5 0.6, 0, 1, 1 1 1 1 rect 0 0 0 0 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, 1 )
|
||||
|
||||
// PREPROC_SUB_LABEL( "Veteran Progress:", 11 )
|
||||
// PREPROC_SHADER_DRAW_ALIGNED_VIS( 200 199 60 14 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", 0.1 0.1 0.1 0.35, 1, 1, 1 1 1 0.2, 1 )
|
||||
// PREPROC_SHADER_DRAW_ADV_VIS( (PLAYERSTATS_X+202), /*167*/(PLAYERSTATS_Y+201), 50, 12, "gradient_fadein", 1 0.9 0.5 0.6, 0, 1, 1 1 1 1 rect 0 0 0 0 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, 1 )
|
||||
|
||||
//PREPROC_DIVIDER( 12 )
|
||||
|
||||
// PREPROC_LABEL("Intel Items", 13)
|
||||
// PREPROC_VALUE_TEXT( "intels", 17, 13, -24, LABEL_TITLECOLOR )
|
||||
// PREPROC_LABEL("Achievement Unlocked", 14)
|
||||
// PREPROC_VALUE_TEXT( "achievements", 35, 14, -24, LABEL_TITLECOLOR )
|
||||
|
||||
//PREPROC_DIVIDER( 15 )
|
||||
|
||||
// PREPROC_SUB_LABEL( "Campaign Progress:", 16 )
|
||||
// PREPROC_SHADER_DRAW_ALIGNED_VIS( 200 289 60 14 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, ORIGIN_PLAYERSTATS, "white", 0.1 0.1 0.1 0.35, 1, 1, 1 1 1 0.2, 1 )
|
||||
// PREPROC_SHADER_DRAW_ADV_VIS( (PLAYERSTATS_X+202), /*167*/(PLAYERSTATS_Y+291), 50, 12, "gradient_fadein", 1 0.9 0.5 0.6, 0, 1, 1 1 1 1 rect 0 0 0 0 RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP, 1 )
|
||||
|
@ -26,7 +26,7 @@
|
||||
style WINDOW_STYLE_FILLED
|
||||
border 0
|
||||
soundloop "music_mainmenu_mp"
|
||||
onOpen { /*uiScript get_career_info*/ }
|
||||
onOpen { focusfirst; /*uiScript get_career_info*/ }
|
||||
onEsc { close stats; }
|
||||
onClose { open main; }
|
||||
#include "ui/blurredbg.inc"
|
||||
|
@ -65,6 +65,7 @@ namespace Components
|
||||
Register(new Markdown());
|
||||
Register(new Changelog());
|
||||
Register(new Paintball());
|
||||
Register(new PlayerStats());
|
||||
|
||||
Pregame = false;
|
||||
// Make sure preDestroy is called when the game shuts down
|
||||
|
@ -83,3 +83,4 @@ namespace Components
|
||||
#include "Modules/GUI/Markdown.hpp"
|
||||
#include "Modules/Changelog.hpp"
|
||||
#include "Modules/Paintball.hpp"
|
||||
#include "Modules/PlayerStats.hpp"
|
||||
|
316
src/Components/Modules/PlayerStats.cpp
Normal file
316
src/Components/Modules/PlayerStats.cpp
Normal file
@ -0,0 +1,316 @@
|
||||
#include "STDInc.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
void PlayerStats::ChangeItemDefText(const char* menuName, const char* itemDefName, const char* value)
|
||||
{
|
||||
Game::menuDef_t* menu = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_MENU, menuName).menu;
|
||||
if (!menu) return;
|
||||
|
||||
for (auto i = 0; i < menu->itemCount; i++)
|
||||
{
|
||||
if (menu->items[i] && menu->items[i]->window.name)
|
||||
{
|
||||
if (!_stricmp(menu->items[i]->window.name, itemDefName))
|
||||
{
|
||||
menu->items[i]->text = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* PlayerStats::getHighestCompletedDifficulty(const float stat_easy, const float stat_regular, const float stat_hardened, const float stat_veteran)
|
||||
{
|
||||
if (stat_easy == 0.0f || stat_regular == 0.0f || stat_hardened == 0.0f || stat_veteran == 0.0f)
|
||||
return "MENU_NOT_STARTED";
|
||||
if (stat_veteran == 100.0f)
|
||||
return "MENU_VETERAN";
|
||||
else if (stat_hardened == 100.0f)
|
||||
return "MENU_HARDENED";
|
||||
else if (stat_regular == 100.0f)
|
||||
return "MENU_REGULAR";
|
||||
else if (stat_easy == 100.0f)
|
||||
return "MENU_RECRUIT";
|
||||
else
|
||||
return "MENU_IN_PROGRESS";
|
||||
}
|
||||
|
||||
double PlayerStats::CalculateAccuracy(uint32_t bullets_fired, uint32_t bullets_hit)
|
||||
{
|
||||
if (bullets_fired != 0)
|
||||
return static_cast<double>(bullets_hit) / bullets_fired * 100.0;
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float PlayerStats::getStatProgression(const std::string& difficulty_string, int difficulty)
|
||||
{
|
||||
int levels = 0;
|
||||
size_t max_missions = std::min(difficulty_string.size(), static_cast<size_t>(21));
|
||||
|
||||
for (size_t i = 0; i < max_missions; ++i) {
|
||||
if (static_cast<int>(difficulty_string[i] - '0') >= difficulty) {
|
||||
levels++;
|
||||
}
|
||||
}
|
||||
|
||||
float completion = static_cast<float>(levels) / max_missions * 100;
|
||||
return completion;
|
||||
}
|
||||
|
||||
float PlayerStats::getStatEasy(const std::string& difficulty_string)
|
||||
{
|
||||
return getStatProgression(difficulty_string, 1);
|
||||
}
|
||||
|
||||
float PlayerStats::getStatRegular(const std::string& difficulty_string)
|
||||
{
|
||||
return getStatProgression(difficulty_string, 2);
|
||||
}
|
||||
|
||||
float PlayerStats::getStatHardened(const std::string& difficulty_string)
|
||||
{
|
||||
return getStatProgression(difficulty_string, 3);
|
||||
}
|
||||
|
||||
float PlayerStats::getStatVeteran(const std::string& difficulty_string)
|
||||
{
|
||||
return getStatProgression(difficulty_string, 4);
|
||||
}
|
||||
|
||||
float PlayerStats::getStatIntel(int intelCount, int totalIntelItems)
|
||||
{
|
||||
return static_cast<float>(intelCount) / totalIntelItems * 100;
|
||||
}
|
||||
|
||||
int PlayerStats::getTotalPercentCompleteSP()
|
||||
{
|
||||
float stat_easy = getStatEasy(Dvars::Functions::Dvar_FindVar("mis_difficulty")->current.string);
|
||||
float stat_regular = getStatRegular(Dvars::Functions::Dvar_FindVar("mis_difficulty")->current.string);
|
||||
float stat_hardened = getStatHardened(Dvars::Functions::Dvar_FindVar("mis_difficulty")->current.string);
|
||||
float stat_veteran = getStatVeteran(Dvars::Functions::Dvar_FindVar("mis_difficulty")->current.string);
|
||||
float stat_intel = getStatIntel(GetStruct("career", "intel"), 30);
|
||||
Achievements::achievement_file_t file{};
|
||||
Achievements::GetAchievementsData(&file);
|
||||
int achievements_earned = Achievements::GetEarnedAchievementCount(&file);
|
||||
|
||||
// Calculate completion progress based on various factors
|
||||
float total_progress = 0.0;
|
||||
|
||||
// Completion progress based on difficulty completion
|
||||
total_progress += (0.1 / 1) * stat_easy;
|
||||
total_progress += (0.1 / 1) * stat_regular;
|
||||
total_progress += (0.1 / 1) * stat_hardened;
|
||||
total_progress += (0.5 / 1) * stat_veteran;
|
||||
|
||||
// Intel completion progress
|
||||
total_progress += (0.15 / 1) * stat_intel;
|
||||
|
||||
// Achievement completion progress
|
||||
total_progress += (0.15 / 38) * achievements_earned;
|
||||
|
||||
// Clamp total progress to 100%
|
||||
total_progress = std::min(total_progress, 100.0f);
|
||||
|
||||
// Convert total progress to integer
|
||||
return static_cast<int>(total_progress);
|
||||
}
|
||||
|
||||
uint32_t PlayerStats::CalculateDays(uint32_t totalMilliseconds) {
|
||||
return totalMilliseconds / (1000 * 60 * 60 * 24);
|
||||
}
|
||||
|
||||
uint32_t PlayerStats::CalculateHours(uint32_t totalMilliseconds) {
|
||||
totalMilliseconds %= (1000 * 60 * 60 * 24);
|
||||
return totalMilliseconds / (1000 * 60 * 60);
|
||||
}
|
||||
|
||||
uint32_t PlayerStats::CalculateMinutes(uint32_t totalMilliseconds) {
|
||||
totalMilliseconds %= (1000 * 60 * 60);
|
||||
return totalMilliseconds / (1000 * 60);
|
||||
}
|
||||
|
||||
uint32_t PlayerStats::CalculateSeconds(uint32_t totalMilliseconds) {
|
||||
totalMilliseconds %= (1000 * 60);
|
||||
return totalMilliseconds / 1000;
|
||||
}
|
||||
|
||||
void PlayerStats::DefaultStats()
|
||||
{
|
||||
const auto path = GetPlayerStatsPath();
|
||||
Utils::IO::RemoveFile(path);
|
||||
}
|
||||
|
||||
std::string PlayerStats::GetPlayerStatsPath()
|
||||
{
|
||||
auto fileBuffer = Utils::IO::ReadFile("players/profiles/active.txt");
|
||||
if (fileBuffer.empty())
|
||||
return "";
|
||||
|
||||
std::string game_folder = std::format("{}\\players\\profiles\\{}\\stats.json", Dvars::Functions::Dvar_FindVar("fs_basepath")->current.string, fileBuffer.c_str());
|
||||
return game_folder;
|
||||
}
|
||||
|
||||
nlohmann::json PlayerStats::ReadPlayerStats()
|
||||
{
|
||||
const auto path = GetPlayerStatsPath();
|
||||
if (!Utils::IO::FileExists(path))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const auto data = Utils::IO::ReadFile(path);
|
||||
return nlohmann::json::parse(data);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
Game::Com_Printf(0, "Failed to parse config file: %s\n", e.what());
|
||||
Utils::IO::WriteFile(path, "{}", false);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void PlayerStats::ResetData()
|
||||
{
|
||||
PlayerStats::DefaultStats();
|
||||
}
|
||||
|
||||
void PlayerStats::WriteData(const nlohmann::json& json)
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto path = GetPlayerStatsPath();
|
||||
const auto str = json.dump(4);
|
||||
Utils::IO::WriteFile(path, str, false);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
Game::Com_Printf(0, "Failed to write config file: %s\n", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerStats::PlayTimeStart()
|
||||
{
|
||||
Scheduler::Loop([]
|
||||
{
|
||||
static uint32_t lastUpdateTime = timeGetTime();
|
||||
|
||||
uint32_t currentTime = timeGetTime();
|
||||
uint32_t elapsedTime = currentTime - lastUpdateTime;
|
||||
|
||||
uint32_t playTimeSP = GetStruct("career", "playTimeSP");
|
||||
playTimeSP += elapsedTime;
|
||||
SetStruct("career", "playTimeSP", playTimeSP);
|
||||
|
||||
lastUpdateTime = currentTime;
|
||||
}, Scheduler::Pipeline::MAIN, 1000ms);
|
||||
}
|
||||
|
||||
void __declspec(naked) PlayerStats::Com_Init_Try_Block_Function_Stub()
|
||||
{
|
||||
const static uint32_t retn_addr = 0x535220;
|
||||
__asm
|
||||
{
|
||||
mov dword ptr ds:[0xF8E004], ebx;
|
||||
call PlayTimeStart;
|
||||
jmp retn_addr;
|
||||
}
|
||||
}
|
||||
|
||||
PlayerStats::PlayerStats()
|
||||
{
|
||||
Command::Add("reset_stats_json", [](Command::Params*)
|
||||
{
|
||||
ResetData();
|
||||
});
|
||||
|
||||
GSC::AddFunction("StatsGetFromStruct", []
|
||||
{
|
||||
const auto json_struct = Game::Scr_GetString(0);
|
||||
const auto field = Game::Scr_GetString(1);
|
||||
const auto value = GetStruct(json_struct, field);
|
||||
|
||||
return Game::Scr_AddInt(value);
|
||||
}, false);
|
||||
|
||||
GSC::AddFunction("StatsSetFromStruct", []
|
||||
{
|
||||
const auto json_struct = Game::Scr_GetString(0);
|
||||
const auto field = Game::Scr_GetString(1);
|
||||
const auto value = Game::Scr_GetInt(2);
|
||||
SetStruct(json_struct, field, value);
|
||||
}, false);
|
||||
|
||||
UIScript::Add("get_career_info", []([[maybe_unused]] const UIScript::Token& token, [[maybe_unused]] const Game::uiInfo_s* info)
|
||||
{
|
||||
//stats vars
|
||||
uint32_t var_bullets_fired = GetStruct("career", "bullets_fired");
|
||||
uint32_t var_bullets_hit = GetStruct("career", "bullets_hit");
|
||||
uint32_t var_deaths = GetStruct("career", "deaths");
|
||||
uint32_t var_headshots = GetStruct("career", "headshots");
|
||||
uint32_t var_kills = GetStruct("career", "kills");
|
||||
uint32_t var_kills_melee = GetStruct("career", "kills_melee");
|
||||
uint32_t var_kills_explosives = GetStruct("career", "kills_explosives");
|
||||
uint32_t var_playTimeSP = GetStruct("career", "playTimeSP");
|
||||
uint32_t var_intel = GetStruct("career", "intel");
|
||||
uint32_t var_days = CalculateDays(var_playTimeSP);
|
||||
uint32_t var_hours = CalculateHours(var_playTimeSP);
|
||||
uint32_t var_minutes = CalculateMinutes(var_playTimeSP);
|
||||
uint32_t var_seconds = CalculateSeconds(var_playTimeSP);
|
||||
|
||||
float stat_easy = getStatEasy(Dvars::Functions::Dvar_FindVar("mis_difficulty")->current.string);
|
||||
float stat_regular = getStatRegular(Dvars::Functions::Dvar_FindVar("mis_difficulty")->current.string);
|
||||
float stat_hardened = getStatHardened(Dvars::Functions::Dvar_FindVar("mis_difficulty")->current.string);
|
||||
float stat_veteran = getStatVeteran(Dvars::Functions::Dvar_FindVar("mis_difficulty")->current.string);
|
||||
|
||||
Achievements::achievement_file_t file{};
|
||||
Achievements::GetAchievementsData(&file);
|
||||
int var_achievements_earned = Achievements::GetEarnedAchievementCount(&file);
|
||||
|
||||
auto var_accuracy = CalculateAccuracy(var_bullets_fired, var_bullets_hit);
|
||||
|
||||
int total_progress = getTotalPercentCompleteSP();
|
||||
|
||||
// For menu showcase
|
||||
const char* kills = Utils::String::VA_NEW("%d", var_kills);
|
||||
const char* kills_melee = Utils::String::VA_NEW("%d", var_kills_melee);
|
||||
const char* kills_explosives = Utils::String::VA_NEW("%d", var_kills_explosives);
|
||||
const char* headshots = Utils::String::VA_NEW("%d", var_headshots);
|
||||
const char* deaths = Utils::String::VA_NEW("%d", var_deaths);
|
||||
const char* bullets_fired = Utils::String::VA_NEW("%d", var_bullets_fired);
|
||||
const char* bullets_hit = Utils::String::VA_NEW("%d", var_bullets_hit);
|
||||
const char* intel = Utils::String::VA_NEW("%d/%d", var_intel, 30);
|
||||
const char* timestamp = Utils::String::VA_NEW("%u:%02u:%02u:%02u", var_days, var_hours, var_minutes, var_seconds);
|
||||
const char* achievements_earned = Utils::String::VA_NEW("%d/%d", var_achievements_earned, Achievements::ACHIEVEMENT_TOTAL_COUNT);
|
||||
const char* accuracy = Utils::String::VA_NEW("%.0f%%", var_accuracy);
|
||||
const char* difficulty = getHighestCompletedDifficulty(stat_easy, stat_regular, stat_hardened, stat_veteran);
|
||||
const char* total_percent_sp = Utils::String::VA_NEW("%d%%", total_progress);
|
||||
|
||||
ChangeItemDefText("stats", "kills", kills);
|
||||
ChangeItemDefText("stats", "headshots", headshots);
|
||||
ChangeItemDefText("stats", "kills_melee", kills_melee);
|
||||
ChangeItemDefText("stats", "kills_explosives", kills_explosives);
|
||||
ChangeItemDefText("stats", "deaths", deaths);
|
||||
ChangeItemDefText("stats", "accuracy", accuracy);
|
||||
//-----------------------------------------------------------
|
||||
ChangeItemDefText("stats", "playedtime", timestamp);
|
||||
//-----------------------------------------------------------
|
||||
ChangeItemDefText("stats", "difficulty", Game::UI_SafeTranslateString(difficulty));
|
||||
ChangeItemDefText("stats", "intels", intel);
|
||||
ChangeItemDefText("stats", "achievements", achievements_earned);
|
||||
//-----------------------------------------------------------
|
||||
ChangeItemDefText("stats", "campaign_progress", total_percent_sp);
|
||||
//-----------------------------------------------------------
|
||||
});
|
||||
|
||||
Utils::Hook::Nop(0x53521A, 6);
|
||||
Utils::Hook(0x53521A, Com_Init_Try_Block_Function_Stub, HOOK_JUMP).install()->quick();
|
||||
}
|
||||
|
||||
PlayerStats::~PlayerStats()
|
||||
{
|
||||
}
|
||||
}
|
80
src/Components/Modules/PlayerStats.hpp
Normal file
80
src/Components/Modules/PlayerStats.hpp
Normal file
@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class PlayerStats : public Component
|
||||
{
|
||||
public:
|
||||
static std::string JsonToString(const nlohmann::json& j)
|
||||
{
|
||||
return j.dump();
|
||||
}
|
||||
|
||||
static nlohmann::json Get(const std::string& key)
|
||||
{
|
||||
const auto cfg = ReadPlayerStats();
|
||||
if (!cfg.is_object() || !cfg.contains(key) || !cfg[key].is_null())
|
||||
{
|
||||
Set(key, defaultValue);
|
||||
return cfg[key];
|
||||
}
|
||||
|
||||
return cfg[key];
|
||||
}
|
||||
|
||||
static nlohmann::json GetStruct(const std::string& name, const std::string& field)
|
||||
{
|
||||
const auto cfg = ReadPlayerStats();
|
||||
if (!cfg.is_object() || !cfg.contains(name) || !cfg[name].is_object() || !cfg[name].contains(field) || cfg[name][field].is_null())
|
||||
{
|
||||
SetStruct(name, field, defaultValue); // You may want to handle default value differently
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return cfg[name][field];
|
||||
}
|
||||
|
||||
static void Set(const std::string& key, const nlohmann::json& value)
|
||||
{
|
||||
auto cfg = ReadPlayerStats();
|
||||
cfg[key] = value;
|
||||
WriteData(cfg);
|
||||
}
|
||||
|
||||
static void SetStruct(const std::string& name, const std::string& field, const nlohmann::json& value)
|
||||
{
|
||||
auto cfg = ReadPlayerStats();
|
||||
cfg[name][field] = value;
|
||||
WriteData(cfg);
|
||||
}
|
||||
|
||||
PlayerStats();
|
||||
~PlayerStats();
|
||||
private:
|
||||
inline static int defaultValue = 0;
|
||||
|
||||
static uint32_t CalculateSeconds(uint32_t totalMilliseconds);
|
||||
static uint32_t CalculateMinutes(uint32_t totalMilliseconds);
|
||||
static uint32_t CalculateHours(uint32_t totalMilliseconds);
|
||||
static uint32_t CalculateDays(uint32_t totalMilliseconds);
|
||||
|
||||
static std::string GetPlayerStatsPath();
|
||||
static nlohmann::json ReadPlayerStats();
|
||||
static void WriteData(const nlohmann::json& json);
|
||||
static void ResetData();
|
||||
static void DefaultStats();
|
||||
static void PlayTimeStart();
|
||||
static void ChangeItemDefText(const char* menuName, const char* itemDefName, const char* value);
|
||||
static const char* getHighestCompletedDifficulty(const float stat_easy, const float stat_regular, const float stat_hardened, const float stat_veteran);
|
||||
static double CalculateAccuracy(uint32_t bullets_fired, uint32_t bullets_hit);
|
||||
static float getStatProgression(const std::string& difficulty_string, int difficulty);
|
||||
static float getStatEasy(const std::string& difficulty_string);
|
||||
static float getStatRegular(const std::string& difficulty_string);
|
||||
static float getStatHardened(const std::string& difficulty_string);
|
||||
static float getStatVeteran(const std::string& difficulty_string);
|
||||
static float getStatIntel(int intelCount, int totalIntelItems);
|
||||
static int getTotalPercentCompleteSP();
|
||||
|
||||
static void Com_Init_Try_Block_Function_Stub();
|
||||
};
|
||||
}
|
@ -7,6 +7,20 @@ namespace Utils
|
||||
{
|
||||
namespace String
|
||||
{
|
||||
const char* VA_NEW(const char* fmt, ...)
|
||||
{
|
||||
static char g_vaBuffer[64][65536];
|
||||
static int g_vaNextBufferIndex = 0;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
char* dest = g_vaBuffer[g_vaNextBufferIndex];
|
||||
vsnprintf(g_vaBuffer[g_vaNextBufferIndex], 65536, fmt, ap);
|
||||
g_vaNextBufferIndex = (g_vaNextBufferIndex + 1) % 64;
|
||||
va_end(ap);
|
||||
return dest;
|
||||
}
|
||||
|
||||
const char* VA(const char* fmt, ...)
|
||||
{
|
||||
static VAProvider<4, 100> globalProvider;
|
||||
|
@ -73,6 +73,7 @@ namespace Utils
|
||||
};
|
||||
|
||||
const char* VA(const char* fmt, ...);
|
||||
const char* VA_NEW(const char* fmt, ...);
|
||||
|
||||
template <typename Arg> // This should display a nice "nullptr" instead of a number
|
||||
static void SanitizeFormatArgs(Arg& arg)
|
||||
|
Loading…
x
Reference in New Issue
Block a user