[PlayerStats]: Added new module.
This commit is contained in:
parent
22ecd2c816
commit
3f8b1a231f
@ -124,6 +124,33 @@ LANG_ENGLISH "Kills"
|
|||||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||||
LANG_ENGLISH "Total Play Time"
|
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
|
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||||
LANG_ENGLISH "D H M S"
|
LANG_ENGLISH "D H M S"
|
||||||
|
|
||||||
|
@ -124,6 +124,33 @@ LANG_FRENCH "Tu
|
|||||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||||
LANG_FRENCH "Temps total de jeu"
|
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
|
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||||
LANG_FRENCH "J H M S"
|
LANG_FRENCH "J H M S"
|
||||||
|
|
||||||
|
@ -130,6 +130,33 @@ LANG_GERMAN "Absch"
|
|||||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||||
LANG_GERMAN "Gesamte Spielzeit"
|
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
|
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||||
LANG_GERMAN "T S M S"
|
LANG_GERMAN "T S M S"
|
||||||
|
|
||||||
|
@ -124,6 +124,33 @@ LANG_ITALIAN "Uccisioni"
|
|||||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||||
LANG_ITALIAN "Tempo di gioco totale"
|
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
|
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||||
LANG_ITALIAN "G O M S"
|
LANG_ITALIAN "G O M S"
|
||||||
|
|
||||||
|
@ -124,6 +124,33 @@ LANG_PORTUGUESE "Kills"
|
|||||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||||
LANG_PORTUGUESE "Total Play Time"
|
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
|
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||||
LANG_PORTUGUESE "D H M S"
|
LANG_PORTUGUESE "D H M S"
|
||||||
|
|
||||||
|
@ -121,6 +121,33 @@ LANG_RUSSIAN "
|
|||||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||||
LANG_RUSSIAN "Èãðîâîå âðåìÿ"
|
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
|
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||||
LANG_RUSSIAN "Ä × Ì Ñ"
|
LANG_RUSSIAN "Ä × Ì Ñ"
|
||||||
|
|
||||||
|
@ -114,6 +114,33 @@ LANG_SLOVAK "Kills"
|
|||||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||||
LANG_SLOVAK "Total Play Time"
|
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
|
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||||
LANG_SLOVAK "D H M S"
|
LANG_SLOVAK "D H M S"
|
||||||
|
|
||||||
|
@ -125,6 +125,33 @@ LANG_SPANISH "Asesinatos"
|
|||||||
REFERENCE MENU_CAREER_PLAYTIMESP
|
REFERENCE MENU_CAREER_PLAYTIMESP
|
||||||
LANG_SPANISH "Tiempo total de juego"
|
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
|
REFERENCE MENU_SP_STAT_TIME_FORMAT
|
||||||
LANG_SPANISH "D H M S"
|
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_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_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_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_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_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_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( 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 ) ); )
|
CHOICE_BUTTON_VIS( 8, "@MENU_OPTIONS", open options_graphics;, when( !localvarBool( ui_hideBack ) ); )
|
||||||
|
@ -77,14 +77,15 @@ itemDef { \
|
|||||||
visible visArg \
|
visible visArg \
|
||||||
decoration }
|
decoration }
|
||||||
|
|
||||||
#define PREPROC_VALUE_TEXT( ptext, itemNumber, px_offset, pcolor ) \
|
#define PREPROC_VALUE_TEXT( pname, ptext, itemNumber, px_offset, pcolor ) \
|
||||||
PREPROC_VALUE_TEXT_VIS( ptext, itemNumber, px_offset, pcolor, 1, ITEM_ALIGN_MIDDLE_RIGHT )
|
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 ) \
|
#define PREPROC_VALUE_TEXT_LEFT_ALIGNED( pname, ptext, itemNumber, px_offset, pcolor ) \
|
||||||
PREPROC_VALUE_TEXT_VIS( ptext, itemNumber, px_offset, pcolor, 1, ITEM_ALIGN_MIDDLE_LEFT )
|
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 { \
|
itemDef { \
|
||||||
|
name pname \
|
||||||
text ptext; \
|
text ptext; \
|
||||||
type ITEM_TYPE_TEXT \
|
type ITEM_TYPE_TEXT \
|
||||||
rect ORIGIN_LABEL_ITEM( itemNumber ) (PLAYERSTATS_WIDTH) LABEL_ITEM_SPACING RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP \
|
rect ORIGIN_LABEL_ITEM( itemNumber ) (PLAYERSTATS_WIDTH) LABEL_ITEM_SPACING RIGHTITEM_ALIGN VERTICAL_ALIGN_TOP \
|
||||||
@ -98,6 +99,7 @@ itemDef { \
|
|||||||
visible visArg \
|
visible visArg \
|
||||||
decoration }
|
decoration }
|
||||||
|
|
||||||
|
/*
|
||||||
itemDef
|
itemDef
|
||||||
{
|
{
|
||||||
type ITEM_TYPE_TEXT
|
type ITEM_TYPE_TEXT
|
||||||
@ -112,6 +114,7 @@ itemDef { \
|
|||||||
visible 1
|
visible 1
|
||||||
decoration
|
decoration
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// UI art
|
// 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 )
|
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
|
//kills
|
||||||
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_KILLS", 1)
|
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
|
//headshots
|
||||||
PREPROC_SUB_LABEL( "@IW3SP_MOD_LOC_MENU_CAREER_HEADSHOTS", 2 )
|
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
|
//deaths
|
||||||
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_DEATHS", 3)
|
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_DEATHS", 5)
|
||||||
PREPROC_VALUE_TEXT( 228, 3, -24, LABEL_TITLECOLOR )
|
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)
|
//play time (add as the last element in player info)
|
||||||
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_PLAYTIMESP", 5)
|
PREPROC_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_PLAYTIMESP", 8)
|
||||||
PREPROC_VALUE_TEXT( "0:00:00:00", 5, -24, LABEL_TITLECOLOR )
|
PREPROC_VALUE_TEXT( "playedtime", "", 8, -24, LABEL_TITLECOLOR )
|
||||||
PREPROC_LABEL_TIME("@IW3SP_MOD_LOC_MENU_SP_STAT_TIME_FORMAT", 4.4)
|
|
||||||
|
|
||||||
PREPROC_DIVIDER( 6 )
|
PREPROC_DIVIDER( 9 )
|
||||||
|
|
||||||
//for sliders
|
//for sliders
|
||||||
//145(18) - 185 (40) - 8
|
//145(18) - 185 (40) - 8
|
||||||
@ -181,33 +199,69 @@ itemDef { \
|
|||||||
//289(18) - 439 (40) - 16
|
//289(18) - 439 (40) - 16
|
||||||
//307(18) - 479 (40) - 17
|
//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_SUB_LABEL( "@IW3SP_MOD_LOC_MENU_CAREER_SP_COMPLETED", 11 )
|
||||||
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_VALUE_TEXT( "difficulty", "", 11, -24, LABEL_TEXTCOLOR )
|
||||||
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_SUB_LABEL( "@IW3SP_MOD_LOC_MENU_CAREER_INTEL", 12 )
|
||||||
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_VALUE_TEXT( "intels", "", 12, -24, LABEL_TEXTCOLOR )
|
||||||
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_SUB_LABEL("@IW3SP_MOD_LOC_MENU_CAREER_ACHIEVEMENT_UNLOCKED", 13)
|
||||||
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_VALUE_TEXT( "achievements", "", 13, -24, LABEL_TEXTCOLOR )
|
||||||
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_DIVIDER( 14 )
|
||||||
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( "@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)
|
//#define PREPROC_SHADER_DRAW_ADV_VIS( pname, px, py, pw, ph, pshader, pcolor, pborder, pbordersize, pbordercolor, visArg )
|
||||||
PREPROC_VALUE_TEXT( 17, 13, -24, LABEL_TITLECOLOR )
|
|
||||||
PREPROC_LABEL("Achievement Unlocked", 14)
|
|
||||||
PREPROC_VALUE_TEXT( 35, 14, -24, LABEL_TITLECOLOR )
|
|
||||||
|
|
||||||
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 )
|
// OLD!!!!
|
||||||
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 )
|
// 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
|
style WINDOW_STYLE_FILLED
|
||||||
border 0
|
border 0
|
||||||
soundloop "music_mainmenu_mp"
|
soundloop "music_mainmenu_mp"
|
||||||
onOpen { /*uiScript get_career_info*/ }
|
onOpen { focusfirst; /*uiScript get_career_info*/ }
|
||||||
onEsc { close stats; }
|
onEsc { close stats; }
|
||||||
onClose { open main; }
|
onClose { open main; }
|
||||||
#include "ui/blurredbg.inc"
|
#include "ui/blurredbg.inc"
|
||||||
|
@ -65,6 +65,7 @@ namespace Components
|
|||||||
Register(new Markdown());
|
Register(new Markdown());
|
||||||
Register(new Changelog());
|
Register(new Changelog());
|
||||||
Register(new Paintball());
|
Register(new Paintball());
|
||||||
|
Register(new PlayerStats());
|
||||||
|
|
||||||
Pregame = false;
|
Pregame = false;
|
||||||
// Make sure preDestroy is called when the game shuts down
|
// Make sure preDestroy is called when the game shuts down
|
||||||
|
@ -83,3 +83,4 @@ namespace Components
|
|||||||
#include "Modules/GUI/Markdown.hpp"
|
#include "Modules/GUI/Markdown.hpp"
|
||||||
#include "Modules/Changelog.hpp"
|
#include "Modules/Changelog.hpp"
|
||||||
#include "Modules/Paintball.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
|
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, ...)
|
const char* VA(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
static VAProvider<4, 100> globalProvider;
|
static VAProvider<4, 100> globalProvider;
|
||||||
|
@ -73,6 +73,7 @@ namespace Utils
|
|||||||
};
|
};
|
||||||
|
|
||||||
const char* VA(const char* fmt, ...);
|
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
|
template <typename Arg> // This should display a nice "nullptr" instead of a number
|
||||||
static void SanitizeFormatArgs(Arg& arg)
|
static void SanitizeFormatArgs(Arg& arg)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user