From e8cbfeb3ccacd69e9daae899db29ee5270351b3e Mon Sep 17 00:00:00 2001 From: okvdai <108829133+okvdai@users.noreply.github.com> Date: Thu, 20 Apr 2023 18:54:49 +0200 Subject: [PATCH] Prepare for v1.0.0 release (#2) * Replace sh_stats.gnut with pulse.gnut * Add menu_stats_utility.nut * Add menu_stats_overview.nut --------- Co-authored-by: legonzaur --- README.md | 9 +- mod.json | 11 +- mod/scripts/vscripts/pulse.gnut | 55 ++ mod/scripts/vscripts/sh_stats.gnut | 522 ----------------- .../vscripts/ui/menu_stats_overview.nut | 460 +++++++++++++++ .../vscripts/ui/menu_stats_utility.nut | 551 ++++++++++++++++++ .../vscripts/ui/menu_stats_weapons.nut | 187 ++++++ 7 files changed, 1267 insertions(+), 528 deletions(-) create mode 100644 mod/scripts/vscripts/pulse.gnut delete mode 100644 mod/scripts/vscripts/sh_stats.gnut create mode 100644 mod/scripts/vscripts/ui/menu_stats_overview.nut create mode 100644 mod/scripts/vscripts/ui/menu_stats_utility.nut create mode 100644 mod/scripts/vscripts/ui/menu_stats_weapons.nut diff --git a/README.md b/README.md index 39e3f35..35c536f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ -# Pulse -## This repository is currently W.I.P. -Pulse is (or, will be someday) a clientside Titanfall 2 mod that allows players to view statistics saved in the Tone API using the currently nonfunctional `Stats` tab. +# Pulse - Development Branch -Currently to do: -- the entire repository +This repository is only for us throwing braincells at code and trying to make it work. + +Please go back to [the main branch](https://github.com/ToneAPI/pulse/tree/main). diff --git a/mod.json b/mod.json index 7b1bd34..cfe7e16 100644 --- a/mod.json +++ b/mod.json @@ -2,5 +2,14 @@ "Name": "ToneAPI.pulse", "Description": "placeholder text", "Version": "0.0.1", - "LoadPriority": 2 + "LoadPriority": 1, + "Scripts": [ + { + "Path": "pulse.gnut", + "RunOn": "UI", + "UICallback": { + "After": "GetStatsFromToneAPI" + } + } + ] } \ No newline at end of file diff --git a/mod/scripts/vscripts/pulse.gnut b/mod/scripts/vscripts/pulse.gnut new file mode 100644 index 0000000..6a7f254 --- /dev/null +++ b/mod/scripts/vscripts/pulse.gnut @@ -0,0 +1,55 @@ +global function GetStatsFromToneAPI +global function getWeaponKillsFromToneApi + +global table globalToneAPIKillData = {} + +void function GetStatsFromToneAPI() +{ + //SetConVarString("ToneURL", "https://toneapi.sleepycat.date/v1") + print("[PULSE] Loaded, getting data...") + HttpRequest getStats + getStats.method = HttpRequestMethod.GET + getStats.url = "https://tone.sleepycat.date/v1/client/weapons" + getStats.queryParameters["player"] <- [NSGetLocalPlayerUID().tostring()] + void functionref(HttpRequestResponse) onSuccess = void function(HttpRequestResponse response) + { + print("[PULSE] Kill data received, processing...") + table JSONForConversion = DecodeJSON(response.body) + foreach (var key, var value in JSONForConversion) { + table test = expect table(value) + //this won't work on v2 since kills will be an integer already + string kills = expect string(test.kills) + globalToneAPIKillData[string(key)] <- kills.tointeger() + print("[PULSE] " + key + " has been added.") + } + print("[PULSE] Kill data has been processed.") + } + + void functionref(HttpRequestFailure) onFailure = void function(HttpRequestFailure failure) + { + print("[PULSE] Encountered an error getting kill data...") + } + + bool result = NSHttpRequest(getStats, onSuccess, onFailure) + print("[PULSE] result is " + result) +} + +int function getWeaponKillsFromToneApi(string weaponRef){ + + //Sliced names are to be removed afterwards + print("[PULSE]" + weaponRef) + if(weaponRef.find("mp_weapon") != null){ + weaponRef = weaponRef.slice(10) + } + + foreach (var key, var value in globalToneAPIKillData) { + print(key) + print(value) + } + if(weaponRef in globalToneAPIKillData){ + print("found!") + print(globalToneAPIKillData[weaponRef]) + return expect int(globalToneAPIKillData[weaponRef]) + } + return 0 +} \ No newline at end of file diff --git a/mod/scripts/vscripts/sh_stats.gnut b/mod/scripts/vscripts/sh_stats.gnut deleted file mode 100644 index 3f4d077..0000000 --- a/mod/scripts/vscripts/sh_stats.gnut +++ /dev/null @@ -1,522 +0,0 @@ - -global function InitStatsTables -global function IsValidStat -global function GetPlayerStatInt -global function GetPlayerStatFloat -global function GetPlayerStat_AllCompetitiveModesAndMapsInt -global function GetStatVar -global function GetStatVarType -global function GetStatVarLocalizedUnlock -global function Stats_GetFixedSaveVar -global function FD_GetHighestDifficultyForTitan - -/*void function AddItemsToStatsList( array refs ) -{ - foreach ( ref in refs ) - shGlobalMP.statsItemsList.append( ref ) -}*/ - -void function InitStatsTables() -{ - int persistenceItemsCount = PersistenceGetEnumCount( "loadoutWeaponsAndAbilities" ) - for ( int i = 0; i < persistenceItemsCount; i++ ) - { - string enumName = PersistenceGetEnumItemNameForIndex( "loadoutWeaponsAndAbilities", i ) - if ( enumName != "" ) - shGlobalMP.statsItemsList.append( enumName ) - } - - //############################################## - // GAMES STATS - //############################################## - - AddPersistentStatCategory( "game_stats" ) - - AddPersistentStat( "game_stats", "game_joined", "", "mapStats[%mapname%].gamesJoined[%gamemode%]", "#" ) - AddPersistentStat( "game_stats", "game_completed", "", "mapStats[%mapname%].gamesCompleted[%gamemode%]", "#" ) - AddPersistentStat( "game_stats", "game_won", "", "mapStats[%mapname%].gamesWon[%gamemode%]", "#" ) - AddPersistentStat( "game_stats", "game_lost", "", "mapStats[%mapname%].gamesLost[%gamemode%]", "#" ) - AddPersistentStat( "game_stats", "mvp", "", "mapStats[%mapname%].topPlayerOnTeam[%gamemode%]", "#" ) - AddPersistentStat( "game_stats", "top3OnTeam", "", "mapStats[%mapname%].top3OnTeam[%gamemode%]", "#" ) - AddPersistentStat( "game_stats", "hoursPlayed", "", "mapStats[%mapname%].hoursPlayed[%gamemode%]", "#" ) - AddPersistentStat( "game_stats", "perfectMatches", "", "mapStats[%mapname%].perfectMatchesByDifficulty[%difficulty%]", "#" ) - AddPersistentStat( "game_stats", "games_completed_fd", "", "mapStats[%mapname%].matchesByDifficulty[%difficulty%]", "#" ) - AddPersistentStat( "game_stats", "games_won_fd", "", "mapStats[%mapname%].winsByDifficulty[%difficulty%]", "#" ) - - int gameModeCount = PersistenceGetEnumCount( "gameModes" ) - for ( int modeIndex = 0; modeIndex < gameModeCount; modeIndex++ ) - { - string gameModeName = PersistenceGetEnumItemNameForIndex( "gameModes", modeIndex ) - - AddPersistentStat( "game_stats", "mode_played", gameModeName, "gameStats.modesPlayed[" + gameModeName + "]", "#UNLOCK_MODE_PLAYED" ) - AddPersistentStat( "game_stats", "mode_won", gameModeName, "gameStats.modesWon[" + gameModeName + "]", "#UNLOCK_MODE_WON" ) - - AddPersistentStat( "game_stats", "pvp_kills_by_mode", gameModeName, "gameStats.pvpKills[" + gameModeName + "]", "#UNLOCK_MODE_PILOT_KILLS" ) - AddPersistentStat( "game_stats", "times_kd_2_to_1_by_mode", gameModeName, "gameStats.timesKillDeathRatio2to1[" + gameModeName + "]", "#UNLOCK_MODE_KD_2_1" ) - AddPersistentStat( "game_stats", "times_kd_2_to_1_pvp_by_mode", gameModeName, "gameStats.timesKillDeathRatio2to1_pvp[" + gameModeName + "]", "#UNLOCK_MODE_PILOT_KD_2_1" ) - } - - AddPersistentStat( "game_stats", "mvp_total", "", "gameStats.mvp_total", "#UNLOCK_GAME_MVP" ) - AddPersistentStat( "game_stats", "game_completed_total", "", "gameStats.gamesCompletedTotal", "#UNLOCK_GAME_COMPLETED" ) - AddPersistentStat( "game_stats", "game_won_total", "", "gameStats.gamesWonTotal", "#UNLOCK_GAME_WON" ) - - //############################################## - // TIME STATS - //############################################## - - AddPersistentStatCategory( "time_stats" ) - - AddPersistentStatFloat( "time_stats", "hours_total", "", "timeStats.total", "#UNLOCK_TIME_HOURS" ) - AddPersistentStatFloat( "time_stats", "hours_as_pilot", "", "timeStats.asPilot", "#UNLOCK_TIME_HOURS_PILOT" ) - AddPersistentStatFloat( "time_stats", "hours_wallrunning", "", "timeStats.wallrunning", "#UNLOCK_TIME_HOURS_WALLRUN" ) - AddPersistentStatFloat( "time_stats", "hours_inAir", "", "timeStats.inAir", "#UNLOCK_TIME_HOURS_AIR" ) - AddPersistentStatFloat( "time_stats", "hours_as_titan", "", "timeStats.asTitanTotal", "#UNLOCK_TIME_HOURS_TITAN" ) - - AddPersistentStatFloat( "time_stats", "hours_dead", "", "timeStats.dead", "#" ) - AddPersistentStatFloat( "time_stats", "hours_wallhanging", "", "timeStats.wallhanging", "#" ) - - // hours_as_titan_stryder - // hours_as_titan_atlas - // hours_as_titan_ogre - foreach ( titan, alias in GetAsTitanTypes() ) - { - AddPersistentStatFloat( "time_stats", "hours_as_titan_" + alias, "", "timeStats.asTitan[" + alias + "]", "#UNLOCK_TIME_HOURS_TITAN_SPECIFIC" ) - } - - //############################################## - // DISTANCE STATS - //############################################## - - AddPersistentStatCategory( "distance_stats" ) - - AddPersistentStatFloat( "distance_stats", "total", "", "distanceStats.total", "#UNLOCK_DISTANCE_KM" ) - AddPersistentStatFloat( "distance_stats", "asPilot", "", "distanceStats.asPilot", "#UNLOCK_DISTANCE_KM_PILOT" ) - AddPersistentStatFloat( "distance_stats", "wallrunning", "", "distanceStats.wallrunning", "#UNLOCK_DISTANCE_KM_WALLRUN" ) - AddPersistentStatFloat( "distance_stats", "inAir", "", "distanceStats.inAir", "#UNLOCK_DISTANCE_KM_AIR" ) - AddPersistentStatFloat( "distance_stats", "asTitan", "", "distanceStats.asTitanTotal", "#UNLOCK_TIME_HOURS_TITAN" ) - - AddPersistentStatFloat( "distance_stats", "ziplining", "", "distanceStats.ziplining", "#" ) - AddPersistentStatFloat( "distance_stats", "onFriendlyTitan", "", "distanceStats.onFriendlyTitan", "#" ) - AddPersistentStatFloat( "distance_stats", "onEnemyTitan", "", "distanceStats.onEnemyTitan", "#" ) - - foreach ( titan, alias in GetAsTitanTypes() ) - { - AddPersistentStatFloat( "distance_stats", titan, "", "distanceStats.asTitan[" + alias + "]", "#UNLOCK_DISTANCE_KM_TITAN_SPECIFIC" ) - } - - //############################################## - // WEAPON STATS - //############################################## - - AddPersistentStatCategory( "weapon_stats" ) - - foreach ( string ref in shGlobalMP.statsItemsList ) - { - AddPersistentStat( "weapon_stats", "shotsHit", ref, "weaponStats[" + ref + "].shotsHit", "#UNLOCK_WEAPON_SHOTS_HIT" ) - AddPersistentStat( "weapon_stats", "headshots", ref, "weaponStats[" + ref + "].headshots", "#UNLOCK_WEAPON_HEADSHOTS" ) - AddPersistentStat( "weapon_stats", "critHits", ref, "weaponStats[" + ref + "].critHits", "#UNLOCK_WEAPON_SHOTS_CRIT" ) - AddPersistentStatFloat( "weapon_stats", "hoursUsed", ref, "weaponStats[" + ref + "].hoursUsed", "#UNLOCK_WEAPON_HOURS_USED" ) - AddPersistentStatFloat( "weapon_stats", "hoursEquipped", ref, "weaponStats[" + ref + "].hoursEquipped", "#UNLOCK_WEAPON_HOURS_EQUIPPED" ) - - AddPersistentStat( "weapon_stats", "shotsFired", ref, "weaponStats[" + ref + "].shotsFired", "#" ) - AddPersistentStat( "weapon_stats", "titanDamage", ref, "weaponStats[" + ref + "].titanDamage", "#UNLOCK_WEAPON_TITAN_DAMAGE" ) - } - - //############################################## - // KILLS STATS FOR WEAPON - //############################################## - - AddPersistentStatCategory( "weapon_kill_stats" ) - - foreach ( string ref in shGlobalMP.statsItemsList ) - { - AddPersistentStat( "weapon_kill_stats", "total", ref, "weaponKillStats[" + ref + "].total", "#UNLOCK_WEAPON_KILLS" ) - AddPersistentStat( "weapon_kill_stats", "pilots", ref, "weaponKillStats[" + ref + "].pilots", "#UNLOCK_WEAPON_PILOT_KILLS" ) - AddPersistentStat( "weapon_kill_stats", "ejecting_pilots", ref, "weaponKillStats[" + ref + "].ejecting_pilots", "#UNLOCK_WEAPON_GOOSER_KILLS" ) - AddPersistentStat( "weapon_kill_stats", "titansTotal", ref, "weaponKillStats[" + ref + "].titansTotal", "#UNLOCK_WEAPON_TITAN_KILLS" ) - AddPersistentStat( "weapon_kill_stats", "assistsTotal", ref, "weaponKillStats[" + ref + "].assistsTotal", "#UNLOCK_WEAPON_ASSISTS" ) - AddPersistentStat( "weapon_kill_stats", "killingSprees", ref, "weaponKillStats[" + ref + "].killingSprees", "#UNLOCK_WEAPON_KILLING_SPREES" ) - - AddPersistentStat( "weapon_kill_stats", "spectres", ref, "weaponKillStats[" + ref + "].spectres", "#" ) - AddPersistentStat( "weapon_kill_stats", "marvins", ref, "weaponKillStats[" + ref + "].marvins", "#" ) - AddPersistentStat( "weapon_kill_stats", "grunts", ref, "weaponKillStats[" + ref + "].grunts", "#" ) - AddPersistentStat( "weapon_kill_stats", "ai", ref, "weaponKillStats[" + ref + "].ai", "#" ) - - foreach ( titan, alias in GetPluralTitanTypes() ) - { - AddPersistentStat( "weapon_kill_stats", titan, ref, "weaponKillStats[" + ref + "].titans[" + alias + "]", "#" ) - } - - // fix this so it doesn't need explicit list of titans - AddPersistentStat( "weapon_kill_stats", "npcTitans_ion", ref, "weaponKillStats[" + ref + "].npcTitans[ion]", "#" ) - AddPersistentStat( "weapon_kill_stats", "npcTitans_scorch", ref, "weaponKillStats[" + ref + "].npcTitans[scorch]", "#" ) - AddPersistentStat( "weapon_kill_stats", "npcTitans_northstar", ref, "weaponKillStats[" + ref + "].npcTitans[northstar]", "#" ) - AddPersistentStat( "weapon_kill_stats", "npcTitans_ronin", ref, "weaponKillStats[" + ref + "].npcTitans[ronin]", "#" ) - AddPersistentStat( "weapon_kill_stats", "npcTitans_tone", ref, "weaponKillStats[" + ref + "].npcTitans[tone]", "#" ) - AddPersistentStat( "weapon_kill_stats", "npcTitans_legion", ref, "weaponKillStats[" + ref + "].npcTitans[legion]", "#" ) - AddPersistentStat( "weapon_kill_stats", "npcTitans_vanguard", ref, "weaponKillStats[" + ref + "].npcTitans[vanguard]", "#" ) - } - - //############################################## - // GENERAL KILLS STATS - //############################################## - - AddPersistentStatCategory( "kills_stats" ) - - AddPersistentStat( "kills_stats", "total", "", "killStats.total", "#UNLOCK_KILLS_TOTAL" ) - AddPersistentStat( "kills_stats", "totalWhileUsingBurnCard", "", "killStats.totalWhileUsingBurnCard", "#" ) - AddPersistentStat( "kills_stats", "titansWhileTitanBCActive", "", "killStats.titansWhileTitanBCActive", "#" ) - AddPersistentStat( "kills_stats", "totalPVP", "", "killStats.totalPVP", "#" ) - AddPersistentStat( "kills_stats", "pilots", "", "killStats.pilots", "#UNLOCK_KILLS_PILOT" ) - AddPersistentStat( "kills_stats", "spectres", "", "killStats.spectres", "#" ) - AddPersistentStat( "kills_stats", "marvins", "", "killStats.marvins", "#" ) - AddPersistentStat( "kills_stats", "grunts", "", "killStats.grunts", "#" ) - AddPersistentStat( "kills_stats", "totalTitans", "", "killStats.totalTitans", "#UNLOCK_KILLS_TITAN" ) - AddPersistentStat( "kills_stats", "totalPilots", "", "killStats.totalPilots", "#" ) - AddPersistentStat( "kills_stats", "totalNPC", "", "killStats.totalNPC", "#" ) - AddPersistentStat( "kills_stats", "totalTitansWhileDoomed", "", "killStats.totalTitansWhileDoomed", "#UNLOCK_KILLS_TITAN_WHILE_DOOMED" ) - AddPersistentStat( "kills_stats", "asPilot", "", "killStats.asPilot", "#" ) - AddPersistentStat( "kills_stats", "totalAssists", "", "killStats.totalAssists", "#UNLOCK_KILLS_ASSISTS" ) - - foreach ( titan, alias in GetAsTitanTypes() ) - { - AddPersistentStat( "kills_stats", titan, "", "killStats.asTitan[" + alias + "]", "#UNLOCK_KILLS_ASTITAN" ) - } - - AddPersistentStat( "kills_stats", "killingSpressAs_ion", "", "killStats.killingSprees[ion]", "#UNLOCK_KILLS_SPREES_ASTITAN" ) - AddPersistentStat( "kills_stats", "killingSpressAs_scorch", "", "killStats.killingSprees[scorch]", "#UNLOCK_KILLS_SPREES_ASTITAN" ) - AddPersistentStat( "kills_stats", "killingSpressAs_northstar", "", "killStats.killingSprees[northstar]", "#UNLOCK_KILLS_SPREES_ASTITAN" ) - AddPersistentStat( "kills_stats", "killingSpressAs_ronin", "", "killStats.killingSprees[ronin]", "#UNLOCK_KILLS_SPREES_ASTITAN" ) - AddPersistentStat( "kills_stats", "killingSpressAs_tone", "", "killStats.killingSprees[tone]", "#UNLOCK_KILLS_SPREES_ASTITAN" ) - AddPersistentStat( "kills_stats", "killingSpressAs_legion", "", "killStats.killingSprees[legion]", "#UNLOCK_KILLS_SPREES_ASTITAN" ) - AddPersistentStat( "kills_stats", "killingSpressAs_vanguard", "", "killStats.killingSprees[vanguard]", "#UNLOCK_KILLS_SPREES_ASTITAN" ) - - AddPersistentStat( "kills_stats", "firstStrikes", "", "killStats.firstStrikes", "#UNLOCK_KILLS_FIRST_STRIKE" ) - AddPersistentStat( "kills_stats", "ejectingPilots", "", "killStats.ejectingPilots", "#UNLOCK_KILLS_GOOSER" ) - AddPersistentStat( "kills_stats", "whileEjecting", "", "killStats.whileEjecting", "#" ) - AddPersistentStat( "kills_stats", "cloakedPilots", "", "killStats.cloakedPilots", "#" ) - AddPersistentStat( "kills_stats", "whileCloaked", "", "killStats.whileCloaked", "#" ) - AddPersistentStat( "kills_stats", "wallrunningPilots", "", "killStats.wallrunningPilots", "#" ) - AddPersistentStat( "kills_stats", "whileWallrunning", "", "killStats.whileWallrunning", "#" ) - AddPersistentStat( "kills_stats", "wallhangingPilots", "", "killStats.wallhangingPilots", "#" ) - AddPersistentStat( "kills_stats", "whileWallhanging", "", "killStats.whileWallhanging", "#" ) - - AddPersistentStat( "kills_stats", "pilotExecution", "", "killStats.pilotExecution", "#" ) - AddPersistentStat( "kills_stats", "pilotExecutePilot", "", "killStats.pilotExecutePilot", "#UNLOCK_KILLS_PILOT_EXECUTION" ) - AddPersistentStat( "kills_stats", "pilotExecutePilotWhileCloaked", "", "killStats.pilotExecutePilotWhileCloaked", "#UNLOCK_KILLS_PILOT_EXECUTION_WHILE_CLOAKED" ) - AddPersistentStat( "kills_stats", "pilotKillsWithHoloPilotActive", "", "killStats.pilotKillsWithHoloPilotActive", "#UNLOCK_KILLS_PILOT_KILLS_WHILE_HOLOPILOT_ACTIVE" ) - AddPersistentStat( "kills_stats", "pilotKillsWithAmpedWallActive", "", "killStats.pilotKillsWithAmpedWallActive", "#UNLOCK_KILLS_PILOT_KILLS_WHILE_AMPEDWALL_ACTIVE" ) - - int pilotExecutionCount = PersistenceGetEnumCount( "pilotExecution" ) - for ( int i = 0; i < pilotExecutionCount; i++ ) - { - string executionRef = PersistenceGetEnumItemNameForIndex( "pilotExecution", i ) - if ( executionRef != "" ) - AddPersistentStat( "kills_stats", "pilotExecutePilotUsing_" + executionRef, "", "killStats.pilotExecutePilotByType[" + executionRef + "]", "#UNLOCK_KILLS_PILOT_EXECUTION_USING_TELEFRAG" ) // will need to modify string if other unlock refs are used - } - - AddPersistentStat( "kills_stats", "pilotKickMelee", "", "killStats.pilotKickMelee", "#" ) - AddPersistentStat( "kills_stats", "pilotKickMeleePilot", "", "killStats.pilotKickMeleePilot", "#" ) - AddPersistentStat( "kills_stats", "titanMelee", "", "killStats.titanMelee", "#" ) - AddPersistentStat( "kills_stats", "titanMeleePilot", "", "killStats.titanMeleePilot", "#" ) - AddPersistentStat( "kills_stats", "titanStepCrush", "", "killStats.titanStepCrush", "#" ) - AddPersistentStat( "kills_stats", "titanStepCrushPilot", "", "killStats.titanStepCrushPilot", "#" ) - - foreach ( titan, alias in GetCapitalizedTitanTypes() ) - { - AddPersistentStat( "kills_stats", "titanExocution" + titan, "", "killStats.titanExocution" + titan, "#UNLOCK_KILLS_TITAN_EXECUTION" ) - } - - AddPersistentStat( "kills_stats", "titanFallKill", "", "killStats.titanFallKill", "#UNLOCK_KILLS_TITANFALL" ) - AddPersistentStat( "kills_stats", "petTitanKillsFollowMode", "", "killStats.petTitanKillsFollowMode", "#" ) - AddPersistentStat( "kills_stats", "petTitanKillsGuardMode", "", "killStats.petTitanKillsGuardMode", "#" ) - AddPersistentStat( "kills_stats", "rodeo_total", "", "killStats.rodeo_total", "#UNLOCK_KILLS_RODEO" ) - AddPersistentStat( "kills_stats", "pilot_headshots_total", "", "killStats.pilot_headshots_total", "#UNLOCK_KILLS_HEADSHOT" ) - AddPersistentStat( "kills_stats", "evacShips", "", "killStats.evacShips", "#" ) - AddPersistentStat( "kills_stats", "flyers", "", "killStats.flyers", "#" ) - AddPersistentStat( "kills_stats", "nuclearCore", "", "killStats.nuclearCore", "#" ) - AddPersistentStat( "kills_stats", "evacuatingEnemies", "", "killStats.evacuatingEnemies", "#" ) - AddPersistentStat( "kills_stats", "coopChallenge_NukeTitan_Kills", "", "killStats.coopChallenge_NukeTitan_Kills", "#" ) - AddPersistentStat( "kills_stats", "coopChallenge_MortarTitan_Kills", "", "killStats.coopChallenge_MortarTitan_Kills", "#" ) - AddPersistentStat( "kills_stats", "coopChallenge_EmpTitan_Kills", "", "killStats.coopChallenge_EmpTitan_Kills", "#" ) - AddPersistentStat( "kills_stats", "coopChallenge_SuicideSpectre_Kills", "", "killStats.coopChallenge_SuicideSpectre_Kills", "#" ) - AddPersistentStat( "kills_stats", "coopChallenge_Turret_Kills", "", "killStats.coopChallenge_Turret_Kills", "#" ) - AddPersistentStat( "kills_stats", "coopChallenge_CloakDrone_Kills", "", "killStats.coopChallenge_CloakDrone_Kills", "#" ) - AddPersistentStat( "kills_stats", "coopChallenge_BubbleShieldGrunt_Kills", "", "killStats.coopChallenge_BubbleShieldGrunt_Kills", "#" ) - AddPersistentStat( "kills_stats", "coopChallenge_Dropship_Kills", "", "killStats.coopChallenge_Dropship_Kills", "#" ) - AddPersistentStat( "kills_stats", "coopChallenge_Sniper_Kills", "", "killStats.coopChallenge_Sniper_Kills", "#" ) - AddPersistentStat( "kills_stats", "ampedVortexKills", "", "killStats.ampedVortexKills", "#" ) - AddPersistentStat( "kills_stats", "meleeWhileCloaked", "", "killStats.meleeWhileCloaked", "#" ) - AddPersistentStat( "kills_stats", "pilotKillsWhileUsingActiveRadarPulse", "", "killStats.pilotKillsWhileUsingActiveRadarPulse", "#" ) - AddPersistentStat( "kills_stats", "titanKillsAsPilot", "", "killStats.titanKillsAsPilot", "#UNLOCK_KILLS_PVT" ) - AddPersistentStat( "kills_stats", "pilotKillsWhileStimActive", "", "killStats.pilotKillsWhileStimActive", "#" ) - AddPersistentStat( "kills_stats", "pilotKillsAsTitan", "", "killStats.pilotKillsAsTitan", "#UNLOCK_KILLS_TVP" ) - AddPersistentStat( "kills_stats", "pilotKillsAsPilot", "", "killStats.pilotKillsAsPilot", "#" ) - AddPersistentStat( "kills_stats", "titanKillsAsTitan", "", "killStats.titanKillsAsTitan", "#" ) - - //############################################## - // GENERAL DEATHS STATS - //############################################## - - AddPersistentStatCategory( "deaths_stats" ) - - AddPersistentStat( "deaths_stats", "total", "", "deathStats.total" ) - AddPersistentStat( "deaths_stats", "totalPVP", "", "deathStats.totalPVP" ) - AddPersistentStat( "deaths_stats", "asPilot", "", "deathStats.asPilot" ) - - foreach ( titan, alias in GetAsTitanTypes() ) - { - AddPersistentStat( "deaths_stats", titan, "", "deathStats.asTitan[" + alias + "]" ) - } - - AddPersistentStat( "deaths_stats", "byPilots", "", "deathStats.byPilots" ) - - foreach ( titan, alias in GetByTitanTypes() ) - { - AddPersistentStat( "deaths_stats", titan, "", "deathStats.byTitans[" + alias + "]" ) - } - - AddPersistentStat( "deaths_stats", "bySpectres", "", "deathStats.bySpectres" ) - AddPersistentStat( "deaths_stats", "byGrunts", "", "deathStats.byGrunts" ) - - foreach ( titan, alias in GetAsNPCTitanTypes() ) - { - AddPersistentStat( "deaths_stats", titan, "", "deathStats.byNPCTitans[" + alias + "]" ) - } - AddPersistentStat( "deaths_stats", "suicides", "", "deathStats.suicides" ) - AddPersistentStat( "deaths_stats", "whileEjecting", "", "deathStats.whileEjecting" ) - - - array titanChassis = ["ion", "scorch", "northstar", "ronin", "tone", "legion", "vanguard"] - - AddPersistentStatCategory( "titan_stats" ) - - foreach ( titan, chassis in GetCapitalizedTitanTypes() ) - { - AddPersistentStat( "titan_stats", "pilots", chassis, "titanStats[" + chassis + "].pilots", "#UNLOCK_TITAN_PILOT_KILLS" ) - AddPersistentStat( "titan_stats", "titansTotal", chassis, "titanStats[" + chassis + "].titansTotal", "#UNLOCK_TITAN_TITAN_KILLS" ) - AddPersistentStat( "titan_stats", "titanDamage", chassis, "titanStats[" + chassis + "].titanDamage", "#UNLOCK_TITAN_TITAN_DAMAGE" ) - AddPersistentStat( "titan_stats", "coresEarned", chassis, "titanStats[" + chassis + "].coresEarned" ) - AddPersistentStat( "titan_stats", "pilotsAsPrime", chassis, "titanStats[" + chassis + "].pilotsAsPrime", "#UNLOCK_TITAN_PRIME_PILOT_KILLS" ) - AddPersistentStat( "titan_stats", "titansAsPrime", chassis, "titanStats[" + chassis + "].titansAsPrime", "#UNLOCK_TITAN_PRIME_TITAN_KILLS" ) - AddPersistentStat( "titan_stats", "executionsAsPrime", chassis, "titanStats[" + chassis + "].executionsAsPrime", "#UNLOCK_TITAN_PRIME_EXECUTIONS" ) - AddPersistentStat( "titan_stats", "matchesByDifficulty", chassis, "titanStats[" + chassis + "].matchesByDifficulty[%difficulty%]", "" ) - AddPersistentStat( "titan_stats", "perfectMatchesByDifficulty", chassis, "titanStats[" + chassis + "].perfectMatchesByDifficulty[%difficulty%]", "" ) - } - - //############################################## - // MISC STATS - //############################################## - - AddPersistentStatCategory( "misc_stats" ) - - AddPersistentStat( "misc_stats", "titanFalls", "", "miscStats.titanFalls", "#UNLOCK_MISC_TITANFALLS" ) - AddPersistentStat( "misc_stats", "titanFallsFirst", "", "miscStats.titanFallsFirst", "#UNLOCK_MISC_TITANFALLS_FIRST" ) - AddPersistentStat( "misc_stats", "titanEmbarks", "", "miscStats.titanEmbarks", "#" ) - AddPersistentStat( "misc_stats", "rodeos", "", "miscStats.rodeos", "#UNLOCK_MISC_RODEOS" ) - AddPersistentStat( "misc_stats", "rodeosFromEject", "", "miscStats.rodeosFromEject", "#UNLOCK_MISC_RODOES_EJECT" ) - AddPersistentStat( "misc_stats", "timesEjected", "", "miscStats.timesEjected", "#" ) - AddPersistentStat( "misc_stats", "timesEjectedNuclear", "", "miscStats.timesEjectedNuclear", "#" ) - AddPersistentStat( "misc_stats", "burnCardsEarned", "", "miscStats.burnCardsEarned", "#" ) - AddPersistentStat( "misc_stats", "burnCardsSpent", "", "miscStats.burnCardsSpent", "#" ) - AddPersistentStat( "misc_stats", "boostsActivated", "", "miscStats.boostsActivated", "#" ) - AddPersistentStat( "misc_stats", "spectreLeeches", "", "miscStats.spectreLeeches", "#" ) - AddPersistentStat( "misc_stats", "spectreLeechesByMap", "", "miscStats.spectreLeechesByMap[%mapname%]", "#" ) - AddPersistentStat( "misc_stats", "evacsAttempted", "", "miscStats.evacsAttempted", "#" ) - AddPersistentStat( "misc_stats", "evacsSurvived", "", "miscStats.evacsSurvived", "#UNLOCK_MISC_EVACS" ) - AddPersistentStat( "misc_stats", "flagsCaptured", "", "miscStats.flagsCaptured", "#" ) - AddPersistentStat( "misc_stats", "flagsReturned", "", "miscStats.flagsReturned", "#" ) - AddPersistentStat( "misc_stats", "arcCannonMultiKills", "", "miscStats.arcCannonMultiKills", "#" ) - AddPersistentStat( "misc_stats", "gruntsConscripted", "", "miscStats.gruntsConscripted", "#" ) - AddPersistentStat( "misc_stats", "hardpointsCaptured", "", "miscStats.hardpointsCaptured", "#" ) - AddPersistentStat( "misc_stats", "challengeTiersCompleted", "", "miscStats.challengeTiersCompleted", "#" ) - AddPersistentStat( "misc_stats", "challengesCompleted", "", "miscStats.challengesCompleted", "#" ) - AddPersistentStat( "misc_stats", "dailyChallengesCompleted", "", "miscStats.dailyChallengesCompleted", "#" ) - AddPersistentStat( "misc_stats", "timesLastTitanRemaining", "", "miscStats.timesLastTitanRemaining", "#" ) - AddPersistentStat( "misc_stats", "killingSprees", "", "miscStats.killingSprees", "#UNLOCK_MISC_KILLING_SPREES" ) - AddPersistentStat( "misc_stats", "coopChallengesCompleted", "", "miscStats.coopChallengesCompleted", "#" ) - - //############################################## - // FD STATS - //############################################## - - AddPersistentStatCategory( "fd_stats" ) - - AddPersistentStat( "fd_stats", "arcMinesPlaced", "", "fdStats.arcMinesPlaced", "#UNLOCK_MISC_ARC_MINE_PLACE" ) - AddPersistentStat( "fd_stats", "turretsPlaced", "", "fdStats.turretsPlaced", "#UNLOCK_MISC_TURRET_PLACE" ) - AddPersistentStat( "fd_stats", "rodeos", "", "fdStats.rodeos", "#UNLOCK_FD_RODEOS" ) - AddPersistentStat( "fd_stats", "rodeoNukes", "", "fdStats.rodeoNukes", "#UNLOCK_MISC_RODEO_NUKES" ) - AddPersistentStat( "fd_stats", "arcMineZaps", "", "fdStats.arcMineZaps", "#UNLOCK_MISC_ARC_MINE_ZAPS" ) - AddPersistentStat( "fd_stats", "turretKills", "", "fdStats.turretKills", "#UNLOCK_MISC_TURRET_KILLS" ) - AddPersistentStat( "fd_stats", "harvesterBoosts", "", "fdStats.harvesterBoosts", "#UNLOCK_MISC_HARVESTER_BOOSTS" ) - AddPersistentStat( "fd_stats", "wavesComplete", "", "fdStats.wavesComplete", "#UNLOCK_MISC_WAVES_COMPLETE" ) - AddPersistentStat( "fd_stats", "easyWins", "", "fdStats.easyWins", "#UNLOCK_FD_EASY_WINS" ) - AddPersistentStat( "fd_stats", "normalWins", "", "fdStats.normalWins", "#UNLOCK_FD_NORMAL_WINS" ) - AddPersistentStat( "fd_stats", "hardWins", "", "fdStats.hardWins", "#UNLOCK_FD_HARD_WINS" ) - AddPersistentStat( "fd_stats", "masterWins", "", "fdStats.masterWins", "#UNLOCK_FD_MASTER_WINS" ) - AddPersistentStat( "fd_stats", "insaneWins", "", "fdStats.insaneWins", "#UNLOCK_FD_INSANE_WINS" ) - AddPersistentStat( "fd_stats", "highestTitanFDLevel", "", "fdStats.highestTitanFDLevel", "#UNLOCK_FD_TITAN_LEVEL" ) - - //############################################################# - // DEV ONLY STATS (NOT TRACKED IN RETAIL FOR PLAYER DISPLAY) - //############################################################# - - AddPersistentStatCategory( "dev_stats" ) - - AddPersistentStat( "dev_stats", "rank_skill", "", DEV_STAT ) - AddPersistentStat( "dev_stats", "raw_rank_skill", "", DEV_STAT ) -} - -void function AddPersistentStatCategory( string category ) -{ - shGlobalMP.playerStatVars[ category ] <- {} -} - -void function AddPersistentStat( string category, string alias, string subAlias, string variable, string localizedUnlock = "" ) -{ - if ( !( alias in shGlobalMP.playerStatVars[ category ] ) ) - shGlobalMP.playerStatVars[ category ][ alias ] <- {} - Assert( !( variable in shGlobalMP.playerStatVars[ category ][ alias ] ) ) - - PlayerStatData playerStatData - playerStatData.statVar = variable - playerStatData.statType = ePlayerStatType.INT - playerStatData.localizedUnlock = localizedUnlock - shGlobalMP.playerStatVars[ category ][ alias ][ subAlias ] <- playerStatData -} - -void function AddPersistentStatInt( string category, string alias, string subAlias, string variable, string localizedUnlock = "" ) -{ - if ( !( alias in shGlobalMP.playerStatVars[ category ] ) ) - shGlobalMP.playerStatVars[ category ][ alias ] <- {} - Assert( !( variable in shGlobalMP.playerStatVars[ category ][ alias ] ) ) - - PlayerStatData playerStatData - playerStatData.statVar = variable - playerStatData.statType = ePlayerStatType.INT - playerStatData.localizedUnlock = localizedUnlock - shGlobalMP.playerStatVars[ category ][ alias ][ subAlias ] <- playerStatData -} - -void function AddPersistentStatFloat( string category, string alias, string subAlias, string variable, string localizedUnlock = "" ) -{ - if ( !( alias in shGlobalMP.playerStatVars[ category ] ) ) - shGlobalMP.playerStatVars[ category ][ alias ] <- {} - Assert( !( variable in shGlobalMP.playerStatVars[ category ][ alias ] ) ) - - PlayerStatData playerStatData - playerStatData.statVar = variable - playerStatData.statType = ePlayerStatType.FLOAT - playerStatData.localizedUnlock = localizedUnlock - shGlobalMP.playerStatVars[ category ][ alias ][ subAlias ] <- playerStatData -} - -bool function IsValidStat( string category, string alias, string subAlias ) -{ - if ( category == "" || alias == "" ) - return false - - if ( !( category in shGlobalMP.playerStatVars ) ) - return false - - if ( !( alias in shGlobalMP.playerStatVars[ category ] ) ) - return false - - return ( subAlias in shGlobalMP.playerStatVars[ category ][ alias ] ) -} - -string function GetStatVar( string category, string alias, string subAlias = "" ) -{ - Assert( category in shGlobalMP.playerStatVars, "Invalid stat category " + category ) - Assert( alias in shGlobalMP.playerStatVars[ category ], "No stat alias " + alias + " in category " + category ) - - - Assert( subAlias in shGlobalMP.playerStatVars[ category ][ alias ] ) - return shGlobalMP.playerStatVars[ category ][ alias ][ subAlias ].statVar -} - -int function GetStatVarType( string category, string alias, string subAlias = "" ) -{ - Assert( category in shGlobalMP.playerStatVars, "Invalid stat category " + category ) - Assert( alias in shGlobalMP.playerStatVars[ category ], "No stat alias " + alias + " in category " + category ) - - Assert( subAlias in shGlobalMP.playerStatVars[ category ][ alias ] ) - return shGlobalMP.playerStatVars[ category ][ alias ][ subAlias ].statType -} - -string function GetStatVarLocalizedUnlock( string category, string alias, string subAlias = "" ) -{ - Assert( category in shGlobalMP.playerStatVars, "Invalid stat category " + category ) - Assert( alias in shGlobalMP.playerStatVars[ category ], "No stat alias " + alias + " in category " + category ) - - Assert( subAlias in shGlobalMP.playerStatVars[ category ][ alias ] ) - return shGlobalMP.playerStatVars[ category ][ alias ][ subAlias ].localizedUnlock -} - -int function GetPlayerStatInt( entity player, string category, string alias, string subAlias = "" ) -{ - Assert( IsUI() || IsValid( player ) ) - - string statString = GetStatVar( category, alias, subAlias ) - return player.GetPersistentVarAsInt( statString ) -} - -float function GetPlayerStatFloat( entity player, string category, string alias, string subAlias = "" ) -{ - Assert( IsUI() || IsValid( player ) ) - - string statString = GetStatVar( category, alias, subAlias ) - return expect float( player.GetPersistentVar( statString ) ) -} - - -string function Stats_GetFixedSaveVar( string saveVar, string mapName, string modeName, string difficultyLevel ) -{ - string fixedSaveVar = saveVar - fixedSaveVar = StringReplace( fixedSaveVar, "%mapname%", mapName ) - fixedSaveVar = StringReplace( fixedSaveVar, "%gamemode%", modeName ) - fixedSaveVar = StringReplace( fixedSaveVar, "%difficulty%", difficultyLevel ) - - return fixedSaveVar -} - -int function GetPlayerStat_AllCompetitiveModesAndMapsInt( entity player, string category, string alias, string subAlias = "" ) -{ - Assert( IsUI() || IsValid( player ) ) - - int count = 0 - - int numMaps = PersistenceGetEnumCount( "maps" ) - int numModes = PersistenceGetEnumCount( "gameModes" ) - - string statVarName = GetStatVar( category, alias, subAlias ) - string fixedSaveVar - - for ( int mode = 0; mode < numModes; mode++ ) - { - for( int map = 0; map < numMaps; map++ ) - { - fixedSaveVar = Stats_GetFixedSaveVar( statVarName, string( map ), string( mode ), "0" ) - count += expect int( player.GetPersistentVar( fixedSaveVar ) ) - } - } - - return count -} - - -int function FD_GetHighestDifficultyForTitan( entity player, string titanRef ) -{ - string statVar = GetStatVar( "titan_stats", "matchesByDifficulty", titanRef ) - - int highestDifficulty = 0 - for ( int difficulty = 0; difficulty < 5; difficulty++ ) - { - string persistentVar = Stats_GetFixedSaveVar( statVar, "", "", string( difficulty ) ) - if ( player.GetPersistentVarAsInt( persistentVar ) > 0 ) - highestDifficulty = difficulty - } - - return highestDifficulty -} - diff --git a/mod/scripts/vscripts/ui/menu_stats_overview.nut b/mod/scripts/vscripts/ui/menu_stats_overview.nut new file mode 100644 index 0000000..ab14cc3 --- /dev/null +++ b/mod/scripts/vscripts/ui/menu_stats_overview.nut @@ -0,0 +1,460 @@ +untyped + +global function InitViewStatsOverviewMenu + +struct +{ + var menu +} file + +const MAX_DOTS_ON_GRAPH = 10 + +const IMAGE_TITAN_STRYDER = $"ui/menu/personal_stats/ps_titan_icon_stryder" +const IMAGE_TITAN_ATLAS = $"ui/menu/personal_stats/ps_titan_icon_atlas" +const IMAGE_TITAN_OGRE = $"ui/menu/personal_stats/ps_titan_icon_ogre" + +void function InitViewStatsOverviewMenu() +{ + PrecacheHUDMaterial( IMAGE_TITAN_STRYDER ) + PrecacheHUDMaterial( IMAGE_TITAN_ATLAS ) + PrecacheHUDMaterial( IMAGE_TITAN_OGRE ) + + var menu = GetMenu( "ViewStats_Overview_Menu" ) + file.menu = menu + + AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnStatsOverview_Open ) + + AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) +} + +void function OnStatsOverview_Open() +{ + UI_SetPresentationType( ePresentationType.NO_MODELS ) + + UpdateViewStatsOverviewMenu() +} + +function UpdateViewStatsOverviewMenu() +{ + entity player = GetUIPlayer() + if ( player == null ) + return + + //######################### + // Games + //######################### + + string timePlayed = StatToTimeString( "time_stats", "hours_total" ) + int gamesPlayed = GetPlayerStat_AllCompetitiveModesAndMapsInt( player, "game_stats", "game_completed" ) + int gamesWon = GetPlayerStat_AllCompetitiveModesAndMapsInt( player, "game_stats", "game_won" ) + string winPercent = GetPercent( float( gamesWon ), float( gamesPlayed ), 0 ) + int timesMVP = GetPlayerStatInt( player, "game_stats", "mvp_total" ) + int timesTop3 = GetPlayerStat_AllCompetitiveModesAndMapsInt( player, "game_stats", "top3OnTeam" ) + + SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat0" ), Localize( "#STATS_HEADER_TIME_PLAYED" ), timePlayed ) + SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat1" ), Localize( "#STATS_GAMES_PLAYED" ), string( gamesPlayed ) ) + SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat2" ), Localize( "#STATS_GAMES_WON" ), string( gamesWon ) ) + SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat3" ), Localize( "#STATS_GAMES_WIN_PERCENT" ), Localize( "#STATS_PERCENTAGE", winPercent ) ) + SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat4" ), Localize( "#STATS_GAMES_MVP" ), string( timesMVP ) ) + SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat5" ), Localize( "#STATS_GAMES_TOP3" ), string( timesTop3 ) ) + + //######################### + // Modes + //######################### + + /*local gameModePlayedVar = GetStatVar( "game_stats", "mode_played" ) + local basicModes = [ "tdm", "cp", "at", "lts", "ctf" ] + + local timesPlayedArray = [] + local gameModeNamesArray = [] + local otherGameModesPlayed = 0 + array gameModesArray = GetPersistenceEnumAsArray( "gameModes" ) + + foreach ( modeName in gameModesArray ) + { + local gameModePlaysVar = StringReplace( expect string( gameModePlayedVar ), "%gamemode%", modeName ) + local timesPlayed = player.GetPersistentVar( gameModePlaysVar ) + + if ( basicModes.contains( modeName ) ) //Don't really like doing ArrayContains, but Chad prefers not storing a separate enum in persistence that contains the "other" gamemodes + { + timesPlayedArray.append( timesPlayed ) + gameModeNamesArray.append( GAMETYPE_TEXT[ modeName] ) + } + else + { + otherGameModesPlayed += timesPlayed + } + } + + //Add Other game modes' data to the end of the arrays + gameModeNamesArray.append( "#GAMEMODE_OTHER" ) + timesPlayedArray.append( otherGameModesPlayed ) + + local data = {} + data.names <- gameModeNamesArray + data.values <- timesPlayedArray + + SetPieChartData( menu, "ModesPieChart", "#GAME_MODES_PLAYED", data )*/ + + //######################### + // Completion + //######################### + + // Challenges complete + //local challengeData = GetChallengeCompleteData() + //SetStatsBarValues( menu, "CompletionBar0", "#STATS_COMPLETION_CHALLENGES", 0, challengeData.total, challengeData.complete ) + + // Item unlocks + //local itemUnlockData = GetItemUnlockCountData() + //SetStatsBarValues( menu, "CompletionBar1", "#STATS_COMPLETION_WEAPONS", 0, itemUnlockData["weapons"].total, itemUnlockData["weapons"].unlocked ) + //SetStatsBarValues( menu, "CompletionBar2", "#STATS_COMPLETION_ATTACHMENTS", 0, itemUnlockData["attachments"].total, itemUnlockData["attachments"].unlocked ) + //SetStatsBarValues( menu, "CompletionBar3", "#STATS_COMPLETION_MODS", 0, itemUnlockData["mods"].total, itemUnlockData["mods"].unlocked ) + //SetStatsBarValues( menu, "CompletionBar4", "#STATS_COMPLETION_ABILITIES", 0, itemUnlockData["abilities"].total, itemUnlockData["abilities"].unlocked ) + //SetStatsBarValues( menu, "CompletionBar5", "#STATS_COMPLETION_GEAR", 0, itemUnlockData["gear"].total, itemUnlockData["gear"].unlocked ) + + //######################### + // Weapons + //######################### + + table weaponData = GetOverviewWeaponData() + table mostKillsData = weaponData[ "most_kills" ] + table mostUsedData = weaponData[ "most_used" ] + table highestKPMData = weaponData[ "highest_kpm" ] + + var weaponImageElem + var weaponRui + var weaponNameElem + var weaponDescElem + var noDataElem + + // Weapon with most kills + weaponImageElem = Hud_GetChild( file.menu, "WeaponImage0" ) + weaponRui = Hud_GetRui( weaponImageElem ) + weaponNameElem = Hud_GetChild( file.menu, "WeaponName0" ) + weaponDescElem = Hud_GetChild( file.menu, "WeaponDesc0" ) + noDataElem = Hud_GetChild( file.menu, "WeaponImageTextOverlay0" ) + if ( mostKillsData.ref != "" ) + { + SetItemImageWidth( weaponImageElem, expect string( mostKillsData.ref ) ) + RuiSetImage( weaponRui, "buttonImage", GetItemImage( expect string( mostKillsData.ref ) ) ) + Hud_Show( weaponImageElem ) + Hud_SetText( weaponNameElem, mostKillsData.printName ) + Hud_Show( weaponNameElem ) + Hud_SetText( weaponDescElem, "#STATS_MOST_KILLS_VALUE", mostKillsData.val ) + Hud_Show( weaponDescElem ) + Hud_Hide( noDataElem ) + } + else + { + Hud_Hide( weaponImageElem ) + Hud_Hide( weaponNameElem ) + Hud_Hide( weaponDescElem ) + Hud_Show( noDataElem ) + } + + // Most Used Weapon + weaponImageElem = Hud_GetChild( file.menu, "WeaponImage1" ) + weaponRui = Hud_GetRui( weaponImageElem ) + weaponNameElem = Hud_GetChild( file.menu, "WeaponName1" ) + weaponDescElem = Hud_GetChild( file.menu, "WeaponDesc1" ) + noDataElem = Hud_GetChild( file.menu, "WeaponImageTextOverlay1" ) + if ( mostUsedData.ref != "" ) + { + SetItemImageWidth( weaponImageElem, expect string( mostUsedData.ref ) ) + RuiSetImage( weaponRui, "buttonImage", GetItemImage( expect string( mostUsedData.ref ) ) ) + Hud_Show( weaponImageElem ) + Hud_SetText( weaponNameElem, mostUsedData.printName ) + Hud_Show( weaponNameElem ) + SetStatsLabelValue( file.menu, "WeaponDesc1", HoursToTimeString( expect float( mostUsedData.val ) ) ) + Hud_Show( weaponDescElem ) + Hud_Hide( noDataElem ) + } + else + { + Hud_Hide( weaponImageElem ) + Hud_Hide( weaponNameElem ) + Hud_Hide( weaponDescElem ) + Hud_Show( noDataElem ) + } + + // Weapon with highest KPM + weaponImageElem = Hud_GetChild( file.menu, "WeaponImage2" ) + weaponRui = Hud_GetRui( weaponImageElem ) + weaponNameElem = Hud_GetChild( file.menu, "WeaponName2" ) + weaponDescElem = Hud_GetChild( file.menu, "WeaponDesc2" ) + noDataElem = Hud_GetChild( file.menu, "WeaponImageTextOverlay2" ) + if ( highestKPMData.ref != "" ) + { + SetItemImageWidth( weaponImageElem, expect string( highestKPMData.ref ) ) + RuiSetImage( weaponRui, "buttonImage", GetItemImage( expect string( highestKPMData.ref ) ) ) + Hud_Show( weaponImageElem ) + Hud_SetText( weaponNameElem, highestKPMData.printName ) + Hud_Show( weaponNameElem ) + Hud_SetText( weaponDescElem, "#STATS_MOST_EFFICIENT_VALUE", highestKPMData.val ) + Hud_Show( weaponDescElem ) + Hud_Hide( noDataElem ) + } + else + { + Hud_Hide( weaponImageElem ) + Hud_Hide( weaponNameElem ) + Hud_Hide( weaponDescElem ) + Hud_Show( noDataElem ) + } + + //######################### + // Titan Unlocks + //######################### + + Assert( player == GetUIPlayer() ) + Assert( player != null ) + + int unlockedCount = 0 + + //var imageLabel = GetElem( menu, "TitanUnlockImage0" ) + //if ( !IsItemLocked( player, "titan_stryder" ) ) + //{ + // imageLabel.SetImage( IMAGE_TITAN_STRYDER ) + // unlockedCount++ + //} + //else + // imageLabel.SetImage( $"ui/menu/personal_stats/ps_titan_icon_locked" ) + // + //imageLabel = GetElem( menu, "TitanUnlockImage1" ) + //if ( !IsItemLocked( player, "titan_atlas" ) ) + //{ + // imageLabel.SetImage( IMAGE_TITAN_ATLAS ) + // unlockedCount++ + //} + //else + // imageLabel.SetImage( $"ui/menu/personal_stats/ps_titan_icon_locked" ) + // + //imageLabel = GetElem( menu, "TitanUnlockImage2" ) + //if ( !IsItemLocked( player, "titan_ogre" ) ) + //{ + // imageLabel.SetImage( IMAGE_TITAN_OGRE ) + // unlockedCount++ + //} + //else + // imageLabel.SetImage( $"ui/menu/personal_stats/ps_titan_icon_locked" ) + // + //var unlockCountLabel = GetElem( menu, "TitanUnlocksCount" ) + //Hud_SetText( unlockCountLabel, "#STATS_CHASSIS_UNLOCK_COUNT", string( unlockedCount ) ) + + //######################### + // K/D Ratios + //######################### + + // Lifetime + local lifetimeAverage = player.GetPersistentVar( "kdratio_lifetime" ).tofloat() + local formattedLifetimeAverage + if ( lifetimeAverage % 1 == 0 ) + formattedLifetimeAverage = format( "%.0f", lifetimeAverage ) + else + formattedLifetimeAverage = format( "%.1f", lifetimeAverage ) + SetStatsLabelValue( file.menu, "LifetimeAverageValue", [ "#STATS_KD_VALUE", formattedLifetimeAverage ] ) + + // Lifetime (PVP) + local lifetimeAveragePVP = player.GetPersistentVar( "kdratio_lifetime_pvp" ).tofloat() + local formattedLifetimeAveragePVP + if ( lifetimeAveragePVP % 1 == 0 ) + formattedLifetimeAveragePVP = format( "%.0f", lifetimeAveragePVP ) + else + formattedLifetimeAveragePVP = format( "%.1f", lifetimeAveragePVP ) + SetStatsLabelValue( file.menu, "LifetimePVPAverageValue", [ "#STATS_KD_VALUE", formattedLifetimeAveragePVP ] ) + + bool last10GamesStatsVisible = gamesPlayed >= NUM_GAMES_TRACK_KDRATIO ? true : false + SetLast10GamesStatVisibility( file.menu, last10GamesStatsVisible ) + + // Last 10 Matches + local kdratio_match = [] + local kdratiopvp_match = [] + for ( int i = NUM_GAMES_TRACK_KDRATIO - 1 ; i >= 0 ; i-- ) + { + kdratio_match.append( player.GetPersistentVar( "kdratio_match[" + i + "]" ) ) + kdratiopvp_match.append( player.GetPersistentVar( "kdratiopvp_match[" + i + "]" ) ) + } + + // Last 10 + local kdratio_match_sum = 0 + local count = 0 + foreach( value in kdratio_match ) + { + if ( value == 0 ) + continue + kdratio_match_sum += value + count++ + } + local kdratio_match_average = count > 0 ? kdratio_match_sum / count : kdratio_match_sum + if ( kdratio_match_average % 1 == 0 ) + kdratio_match_average = format( "%.0f", kdratio_match_average ) + else + kdratio_match_average = format( "%.1f", kdratio_match_average ) + SetStatsLabelValue( file.menu, "Last10GamesValue", [ "#STATS_KD_VALUE", kdratio_match_average ] ) + PlotKDPointsOnGraph( file.menu, 0, kdratio_match, lifetimeAverage ) + + // Last 10 (PVP) + local kdratiopvp_match_sum = 0 + count = 0 + foreach( value in kdratiopvp_match ) + { + if ( value == 0 ) + continue + kdratiopvp_match_sum += value + count++ + } + local kdratiopvp_match_average = count > 0 ? kdratiopvp_match_sum / count : kdratiopvp_match_sum + if ( kdratiopvp_match_average % 1 == 0 ) + kdratiopvp_match_average = format( "%.0f", kdratiopvp_match_average ) + else + kdratiopvp_match_average = format( "%.1f", kdratiopvp_match_average ) + SetStatsLabelValue( file.menu, "Last10GamesPVPValue", [ "#STATS_KD_VALUE", kdratiopvp_match_average ] ) + PlotKDPointsOnGraph( file.menu, 1, kdratiopvp_match, lifetimeAveragePVP ) + + var totalPilotKills = 0 + + foreach (var key, var value in globalToneAPIKillData) { + totalPilotKills += value + } + + ///////////////////////// + Hud_SetText( GetElem( file.menu, "KillsAsPilotValue0" ), string( totalPilotKills ) ) + Hud_SetText( GetElem( file.menu, "KillsAsPilotValue1" ), string( GetPlayerStatInt( player, "kills_stats", "titanKillsAsPilot" ) ) ) + Hud_SetText( GetElem( file.menu, "KillsAsPilotValue2" ), string( GetPlayerStatInt( player, "kills_stats", "totalNPC" ) ) ) + Hud_SetText( GetElem( file.menu, "KillsAsPilotValue3" ), string( GetPlayerStatInt( player, "kills_stats", "pilotKickMeleePilot" ) ) ) + Hud_SetText( GetElem( file.menu, "KillsAsPilotValue4" ), string( GetPlayerStatInt( player, "kills_stats", "pilotExecutePilot" ) ) ) +// Hud_SetText( GetElem( file.menu, "KillsAsPilotValue5" ), string( GetPlayerStatInt( player, "kills_stats", "titanFallKill" ) ) ) + + + + int totalTitanExecutions = 0 + totalTitanExecutions += GetPlayerStatInt( player, "kills_stats", "titanExocutionIon" ) + totalTitanExecutions += GetPlayerStatInt( player, "kills_stats", "titanExocutionScorch" ) + totalTitanExecutions += GetPlayerStatInt( player, "kills_stats", "titanExocutionNorthstar" ) + totalTitanExecutions += GetPlayerStatInt( player, "kills_stats", "titanExocutionRonin" ) + totalTitanExecutions += GetPlayerStatInt( player, "kills_stats", "titanExocutionTone" ) + totalTitanExecutions += GetPlayerStatInt( player, "kills_stats", "titanExocutionLegion" ) + totalTitanExecutions += GetPlayerStatInt( player, "kills_stats", "titanExocutionVanguard" ) + + Hud_SetText( GetElem( file.menu, "KillsAsTitanValue0" ), string( GetPlayerStatInt( player, "kills_stats", "pilotKillsAsTitan" ) ) ) + Hud_SetText( GetElem( file.menu, "KillsAsTitanValue1" ), string( GetPlayerStatInt( player, "kills_stats", "titanKillsAsTitan" ) ) ) + Hud_SetText( GetElem( file.menu, "KillsAsTitanValue2" ), string( totalTitanExecutions ) ) + Hud_SetText( GetElem( file.menu, "KillsAsTitanValue3" ), string( GetPlayerStatInt( player, "kills_stats", "titanMeleePilot" ) ) ) + Hud_SetText( GetElem( file.menu, "KillsAsTitanValue4" ), string( GetPlayerStatInt( player, "kills_stats", "titanStepCrushPilot" ) ) ) +} + +function PlotKDPointsOnGraph( menu, graphIndex, values, dottedAverage ) +{ + //printt( "values:" ) + //PrintTable( values ) + + var background = GetElem( menu, "KDRatioLast10Graph" + graphIndex ) + local graphHeight = Hud_GetBaseHeight( background ) + local graphOrigin = Hud_GetAbsPos( background ) + graphOrigin[1] += graphHeight + local dotSpacing = Hud_GetBaseWidth( background ) / 9.0 + local dotPositions = [] + + // Calculate min/max for the graph + local graphMin = 0.0 + local graphMax = max( dottedAverage, 1.0 ) + foreach( value in values ) + { + if ( value > graphMax ) + graphMax = value + } + graphMax += graphMax * 0.1 + + var maxLabel = GetElem( menu, "Graph" + graphIndex + "ValueMax" ) + local maxValueString = format( "%.1f", graphMax ) + Hud_SetText( maxLabel, maxValueString ) + + // Plot the dots + for ( int i = 0; i < MAX_DOTS_ON_GRAPH; i++ ) + { + var dot = GetElem( menu, "Graph" + graphIndex + "Dot" + i ) + + if ( i >= values.len() ) + { + Hud_Hide( dot ) + continue + } + + float dotOffset = GraphCapped( values[i], graphMin, graphMax, 0, graphHeight ) + + local posX = graphOrigin[0] - ( Hud_GetBaseWidth( dot ) * 0.5 ) + ( dotSpacing * i ) + local posY = graphOrigin[1] - ( Hud_GetBaseHeight( dot ) * 0.5 ) - dotOffset + Hud_SetPos( dot, posX, posY ) + Hud_Show( dot ) + + dotPositions.append( [ posX + ( Hud_GetBaseWidth( dot ) * 0.5 ), posY + ( Hud_GetBaseHeight( dot ) * 0.5 ) ] ) + } + + { + // Place the dotted lifetime average line + var dottedLine = GetElem( menu, "KDRatioLast10Graph" + graphIndex + "DottedLine0" ) + float dottedLineOffset = GraphCapped( dottedAverage, graphMin, graphMax, 0, graphHeight ) + local posX = graphOrigin[0] + local posY = graphOrigin[1] - ( Hud_GetBaseHeight( dottedLine ) * 0.5 ) - dottedLineOffset + Hud_SetPos( dottedLine, posX, posY ) + Hud_Show( dottedLine ) + } + + { + // Place the dotted zero line + var dottedLine = GetElem( menu, "KDRatioLast10Graph" + graphIndex + "DottedLine1" ) + float dottedLineOffset = GraphCapped( 0.0, graphMin, graphMax, 0, graphHeight ) + local posX = graphOrigin[0] + local posY = graphOrigin[1] - ( Hud_GetBaseHeight( dottedLine ) * 0.5 ) - dottedLineOffset + Hud_SetPos( dottedLine, posX, posY ) + Hud_Show( dottedLine ) + } + + // Connect the dots with lines + for ( int i = 1; i < MAX_DOTS_ON_GRAPH; i++ ) + { + var line = GetElem( menu, "Graph" + graphIndex + "Line" + i ) + + if ( i >= values.len() ) + { + Hud_Hide( line ) + continue + } + + // Get angle from previous dot to this dot + local startPos = dotPositions[i-1] + local endPos = dotPositions[i] + local offsetX = endPos[0] - startPos[0] + local offsetY = endPos[1] - startPos[1] + local angle = ( atan( offsetX / offsetY ) * ( 180 / PI ) ) + + // Get line length + local length = sqrt( offsetX * offsetX + offsetY * offsetY ) + + // Calculate where the line should be positioned + local posX = endPos[0] - ( offsetX / 2.0 ) - ( length / 2.0 ) + local posY = endPos[1] - ( offsetY / 2.0 ) - ( Hud_GetBaseHeight( line ) / 2.0 ) + + //line.SetHeight( 2.0 ) + Hud_SetWidth( line, length ) + Hud_SetRotation( line, angle + 90.0 ) + Hud_SetPos( line, posX, posY ) + Hud_Show( line ) + } +} + +void function SetLast10GamesStatVisibility( var menu, bool visible ) +{ + Hud_SetVisible( Hud_GetChild( menu, "Last10GamesLabel" ), visible ) + Hud_SetVisible( Hud_GetChild( menu, "Last10GamesValue" ), visible ) + Hud_SetVisible( Hud_GetChild( menu, "Last10GamesPVPLabel" ), visible ) + Hud_SetVisible( Hud_GetChild( menu, "Last10GamesPVPValue" ), visible ) +} + +void function SetItemImageWidth( var imageElem, string ref ) +{ + vector vec = GetItemImageAspect( ref ) + float aspectRatio = vec.x / vec.y + int imageWidth = int( Hud_GetHeight( imageElem ) * aspectRatio ) + Hud_SetWidth( imageElem, imageWidth ) +} \ No newline at end of file diff --git a/mod/scripts/vscripts/ui/menu_stats_utility.nut b/mod/scripts/vscripts/ui/menu_stats_utility.nut new file mode 100644 index 0000000..e4c235c --- /dev/null +++ b/mod/scripts/vscripts/ui/menu_stats_utility.nut @@ -0,0 +1,551 @@ +untyped + + +global function SetPieChartData +global function SetStatsBarValues +global function SetStatsValueInfo +global function SetStatsLabelValue +global function GetPercent +//global function GetChallengeCompleteData +global function GetItemUnlockCountData +global function GetOverviewWeaponData +global function StatToTimeString +global function HoursToTimeString +global function StatToDistanceString +global function ComparePieChartEntryValues +global function SetStatBoxDisplay +global function SetMedalStatBoxDisplay + +void function SetPieChartData( var menu, string panelName, string titleString, PieChartData data ) +{ + Assert( data.entries.len() <= 8 ) + + // Get nested panel + var piePanel = GetElem( menu, panelName ) + + // Create background + var background = Hud_GetChild( piePanel, "BarBG" ) + Hud_SetBarProgress( background, 1.0 ) + Hud_SetColor( background, [190, 190, 190, 255] ) + + // Calculate total of all values combined + foreach ( entry in data.entries ) + data.sum += entry.numValue + + // Calculate bar fraction for each value + foreach ( entry in data.entries ) + { + if ( data.sum > 0 ) + entry.fracValue = entry.numValue / data.sum + else + entry.fracValue = 0.0 + } + + // Set slice sizes and text data + var titleLabel = Hud_GetChild( piePanel, "Title" ) + Hud_SetText( titleLabel, titleString ) + Hud_SetColor( titleLabel, data.labelColor ) + + var noDataLabel = Hud_GetChild( piePanel, "NoData" ) + + for ( int index = 0; index < 8; index++ ) + { + var barColorGuide = Hud_GetChild( piePanel, "BarColorGuide" + index ) + // Hud_SetColor( barColorGuide, entry.color ) + Hud_Hide( barColorGuide ) + + var barColorGuideFrame = Hud_GetChild( piePanel, "BarColorGuideFrame" + index ) + Hud_Hide( barColorGuideFrame ) + + var barName = Hud_GetChild( piePanel, "BarName" + index ) + Hud_SetColor( barName, data.labelColor ) + Hud_SetText( barName, "" ) + + var bar = Hud_GetChild( piePanel, "Bar" + index ) + //Hud_SetBarProgress( bar, combinedFrac ) + //Hud_SetColor( bar, entry.color ) + Hud_Hide( bar ) + } + + if ( data.entries.len() > 0 ) + { + Hud_Hide( noDataLabel ) + + float combinedFrac = 0.0 + int largestTextWidth = 0 + + foreach ( index, entry in data.entries ) + { + var barColorGuide = Hud_GetChild( piePanel, "BarColorGuide" + index ) + Hud_SetColor( barColorGuide, entry.color ) + Hud_Show( barColorGuide ) + + var barColorGuideFrame = Hud_GetChild( piePanel, "BarColorGuideFrame" + index ) + Hud_Show( barColorGuideFrame ) + + string percent = GetPercent( entry.fracValue, 1.0, 0, true ) + var barName = Hud_GetChild( piePanel, "BarName" + index ) + Hud_SetColor( barName, data.labelColor ) + + if ( data.timeBased ) + Hud_SetText( barName, PieChartHoursToTimeString( entry.numValue, entry.displayName, percent ) ) + else + Hud_SetText( barName, "#STATS_TEXT_AND_PERCENTAGE", entry.displayName, percent ) + + int currentTextWidth = Hud_GetTextWidth( barName ) + if ( currentTextWidth > largestTextWidth ) + largestTextWidth = currentTextWidth + + Hud_Show( barName ) + + combinedFrac += entry.fracValue + var bar = Hud_GetChild( piePanel, "Bar" + index ) + Hud_SetBarProgress( bar, combinedFrac ) + Hud_SetColor( bar, entry.color ) + Hud_Show( bar ) + } + + // Position the list + int xOffset = int( ( largestTextWidth / -2 ) + ContentScaledX( 18 ) ) + Hud_SetX( Hud_GetChild( piePanel, "BarName0" ), xOffset ) + } + else + { + Hud_Show( noDataLabel ) + for ( int index = 0; index < 8; index++ ) + { + var barColorGuide = Hud_GetChild( piePanel, "BarColorGuide" + index ) +// Hud_SetColor( barColorGuide, entry.color ) + Hud_Hide( barColorGuide ) + + var barColorGuideFrame = Hud_GetChild( piePanel, "BarColorGuideFrame" + index ) + Hud_Hide( barColorGuideFrame ) + + var barName = Hud_GetChild( piePanel, "BarName" + index ) + Hud_SetColor( barName, data.labelColor ) + Hud_SetText( barName, "" ) + + var bar = Hud_GetChild( piePanel, "Bar" + index ) + //Hud_SetBarProgress( bar, combinedFrac ) + //Hud_SetColor( bar, entry.color ) + Hud_Hide( bar ) + } + } +} + +function SetStatsBarValues( menu, panelName, titleString, startValue, endValue, currentValue ) +{ + Assert( endValue > startValue ) + Assert( currentValue >= startValue && currentValue <= endValue ) + + // Get nested panel + var panel = GetElem( menu, panelName ) + + // Update titel + var title = Hud_GetChild( panel, "Title" ) + Hud_SetText( title, titleString ) + + // Update progress text + var progressText = Hud_GetChild( panel, "ProgressText" ) + Hud_SetText( progressText, "#STATS_PROGRESS_BAR_VALUE", currentValue, endValue ) + + // Update bar progress + float frac = GraphCapped( currentValue, startValue, endValue, 0.0, 1.0 ) + + var barFill = Hud_GetChild( panel, "BarFill" ) + Hud_SetScaleX( barFill, frac ) + + var barFillShadow = Hud_GetChild( panel, "BarFillShadow" ) + Hud_SetScaleX( barFillShadow, frac ) +} + +void function SetStatsValueInfo( var menu, valueID, labelText, textString ) +{ + var elem = GetElem( menu, "Column0Label" + valueID ) + Assert( elem != null ) + Hud_SetText( elem, labelText ) + + elem = GetElem( menu, "Column0Value" + valueID ) + Assert( elem != null ) + SetStatsLabelValueOnLabel( elem, textString ) +} + +void function SetStatsLabelValue( var menu, labelName, textString ) +{ + var elem = GetElem( menu, labelName ) + Assert( elem != null) + SetStatsLabelValueOnLabel( elem, textString ) +} + +void function SetStatsLabelValueOnLabel( elem, textString ) +{ + if ( type( textString ) == "array" ) + { + if ( textString.len() == 6 ) + Hud_SetText( elem, string( textString[0] ), textString[1], textString[2], textString[3], textString[4], textString[5] ) + if ( textString.len() == 5 ) + Hud_SetText( elem, string( textString[0] ), textString[1], textString[2], textString[3], textString[4] ) + if ( textString.len() == 4 ) + Hud_SetText( elem, string( textString[0] ), textString[1], textString[2], textString[3] ) + if ( textString.len() == 3 ) + Hud_SetText( elem, string( textString[0] ), textString[1], textString[2] ) + if ( textString.len() == 2 ) + Hud_SetText( elem, string( textString[0] ), textString[1] ) + if ( textString.len() == 1 ) + Hud_SetText( elem, string( textString[0] ) ) + } + else + { + Hud_SetText( elem, string( textString ) ) + } +} + +string function GetPercent( float val, float total, float defaultPercent, bool doClamp = true ) +{ + float percent = defaultPercent + if ( total > 0 ) + { + percent = val / total + percent *= 100 + } + + if ( doClamp ) + percent = clamp( percent, 0, 100 ) + + string formattedPercent + if ( int( percent * 10 ) % 10 == 0 ) + formattedPercent = format( "%.0f", percent ) + else + formattedPercent = format( "%.1f", percent ) + + return formattedPercent +} + +//function GetChallengeCompleteData() +//{ +// local Table = {} +// Table.total <- 0 +// Table.complete <- 0 +// +// UI_GetAllChallengesProgress() +// var allChallenges = GetLocalChallengeTable() +// +// foreach( challengeRef, val in allChallenges ) +// { +// if ( IsDailyChallenge( challengeRef ) ) +// continue +// local tierCount = GetChallengeTierCount( challengeRef ) +// Table.total += tierCount +// for ( int i = 0; i < tierCount; i++ ) +// { +// if ( IsChallengeTierComplete( challengeRef, i ) ) +// Table.complete++ +// } +// } +// +// return Table +//} + +function GetItemUnlockCountData() +{ + entity player = GetUIPlayer() + if ( player == null ) + return {} + + local Table = {} + Table[ "weapons" ] <- {} + Table[ "weapons" ].total <- 0 + Table[ "weapons" ].unlocked <- 0 + Table[ "attachments" ] <- {} + Table[ "attachments" ].total <- 0 + Table[ "attachments" ].unlocked <- 0 + Table[ "mods" ] <- {} + Table[ "mods" ].total <- 0 + Table[ "mods" ].unlocked <- 0 + Table[ "abilities" ] <- {} + Table[ "abilities" ].total <- 0 + Table[ "abilities" ].unlocked <- 0 + Table[ "gear" ] <- {} + Table[ "gear" ].total <- 0 + Table[ "gear" ].unlocked <- 0 +/* + local tableMapping = {} + + tableMapping[ eItemTypes.PILOT_PRIMARY ] <- "weapons" + tableMapping[ eItemTypes.PILOT_SECONDARY ] <- "weapons" + tableMapping[ eItemTypes.PILOT_ORDNANCE ] <- "weapons" + tableMapping[ eItemTypes.TITAN_PRIMARY ] <- "weapons" + tableMapping[ eItemTypes.TITAN_ORDNANCE ] <- "weapons" + tableMapping[ eItemTypes.PILOT_PRIMARY_ATTACHMENT ] <- "attachments" + tableMapping[ eItemTypes.PILOT_PRIMARY_MOD ] <- "mods" + tableMapping[ eItemTypes.PILOT_SECONDARY_MOD ] <- "mods" + tableMapping[ eItemTypes.TITAN_PRIMARY_MOD ] <- "mods" + tableMapping[ eItemTypes.PILOT_SPECIAL_MOD ] <- "mods" + tableMapping[ eItemTypes.TITAN_SPECIAL_MOD ] <- "mods" + tableMapping[ eItemTypes.PILOT_SPECIAL ] <- "abilities" + tableMapping[ eItemTypes.TITAN_SPECIAL ] <- "abilities" + + local itemRefs = GetAllItemRefs() + foreach ( data in itemRefs ) + { + if ( !( data.Type in tableMapping ) ) + continue + Table[ tableMapping[ data.Type ] ].total++ + + if ( !IsItemLocked( player, expect string( data.childRef ), expect string( data.ref ) ) ) + Table[ tableMapping[ data.Type ] ].unlocked++ + } +*/ + return Table +} + +table function GetOverviewWeaponData() +{ + table Table = {} + Table[ "most_kills" ] <- {} + Table[ "most_kills" ].ref <- "" + Table[ "most_kills" ].printName <- "" + Table[ "most_kills" ].val <- 0 + Table[ "most_used" ] <- {} + Table[ "most_used" ].ref <- "" + Table[ "most_used" ].printName <- "" + Table[ "most_used" ].val <- 0 + Table[ "highest_kpm" ] <- {} + Table[ "highest_kpm" ].ref <- "" + Table[ "highest_kpm" ].printName <- "" + Table[ "highest_kpm" ].val <- 0 + + entity player = GetUIPlayer() + if ( player == null ) + return Table + + array allWeapons = [] + + allWeapons.extend( GetVisibleItemsOfType( eItemTypes.PILOT_PRIMARY ) ) + allWeapons.extend( GetVisibleItemsOfType( eItemTypes.PILOT_SECONDARY ) ) + //allWeapons.extend( GetVisibleItemsOfType( eItemTypes.PILOT_ORDNANCE ) ) // art looks bad + allWeapons.extend( GetVisibleItemsOfType( eItemTypes.TITAN_PRIMARY ) ) + allWeapons.extend( GetVisibleItemsOfType( eItemTypes.TITAN_ORDNANCE ) ) + allWeapons.extend( GetVisibleItemsOfType( eItemTypes.TITAN_ANTIRODEO ) ) + allWeapons.extend( GetVisibleItemsOfType( eItemTypes.TITAN_SPECIAL ) ) + //allWeapons.extend( GetVisibleItemsOfType( eItemTypes.BURN_METER_REWARD ) ) // script errors + + foreach ( weapon in allWeapons ) + { + string weaponName = weapon.ref + string weaponDisplayName = expect string( GetWeaponInfoFileKeyField_Global( weaponName, "printname" ) ) + + if ( !PersistenceEnumValueIsValid( "loadoutWeaponsAndAbilities", weaponName ) ) + continue + + int val = getWeaponKillsFromToneApi(weaponName) + if ( val > Table[ "most_kills" ].val ) + { + Table[ "most_kills" ].ref = weaponName + Table[ "most_kills" ].printName = weaponDisplayName + Table[ "most_kills" ].val = val + } + + float fVal = GetPlayerStatFloat( player, "weapon_stats", "hoursUsed", weaponName ) + if ( fVal > Table[ "most_used" ].val ) + { + Table[ "most_used" ].ref = weaponName + Table[ "most_used" ].printName = weaponDisplayName + Table[ "most_used" ].val = fVal + } + + local killsPerMinute = 0 + local hoursEquipped = GetPlayerStatFloat( player, "weapon_stats", "hoursEquipped", weaponName ) + local killCount = GetPlayerStatInt( player, "weapon_kill_stats", "total", weaponName ) + if ( hoursEquipped > 0 ) + killsPerMinute = format( "%.2f", ( killCount / ( hoursEquipped * 60.0 ) ).tofloat() ) + if ( killsPerMinute.tofloat() > Table[ "highest_kpm" ].val.tofloat() ) + { + Table[ "highest_kpm" ].ref = weaponName + Table[ "highest_kpm" ].printName = weaponDisplayName + Table[ "highest_kpm" ].val = killsPerMinute + } + } + + return Table +} + +string function StatToTimeString( string category, string alias, string weapon = "" ) +{ + entity player = GetUIPlayer() + if ( player == null ) + return "0" + + string statString = GetStatVar( category, alias, weapon ) + float savedHours = expect float( player.GetPersistentVar( statString ) ) + + return HoursToTimeString( savedHours ) +} + +string function HoursToTimeString( float savedHours ) +{ + string timeString + local minutes = floor( savedHours * 60.0 ) + + if ( minutes < 0 ) + minutes = 0 + + int days = 0 + int hours = 0 + + while ( minutes >= 1440 ) + { + minutes -= 1440 + days++ + } + + while ( minutes >= 60 ) + { + minutes -= 60 + hours++ + } + + if ( days > 0 && hours > 0 && minutes > 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_D_H_M", days, hours, minutes ) + } + else if ( days > 0 && hours == 0 && minutes == 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_D", days ) + } + else if ( days == 0 && hours > 0 && minutes == 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_H", hours ) + } + else if ( days == 0 && hours == 0 && minutes >= 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_M", minutes ) + } + else if ( days > 0 && hours > 0 && minutes == 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_D_H", days, hours ) + } + else if ( days == 0 && hours > 0 && minutes > 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_H_M", hours, minutes ) + } + else if ( days > 0 && hours == 0 && minutes > 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_D_M", days, minutes ) + } + else + { + Assert( 0, "Unhandled time string creation case" ) + } + + return timeString +} + +string function PieChartHoursToTimeString( float savedHours, string pieChartHeader, string pieChartPercent ) +{ + string timeString + local minutes = floor( savedHours * 60.0 ) + + if ( minutes < 0 ) + minutes = 0 + + int days = 0 + int hours = 0 + + while ( minutes >= 1440 ) + { + minutes -= 1440 + days++ + } + + while ( minutes >= 60 ) + { + minutes -= 60 + hours++ + } + + if ( days > 0 && hours > 0 && minutes > 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_D_H_M_PIECHART", days, hours, minutes, Localize( pieChartHeader ), pieChartPercent ) + } + else if ( days > 0 && hours == 0 && minutes == 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_D_PIECHART", days, Localize( pieChartHeader ), pieChartPercent ) + } + else if ( days == 0 && hours > 0 && minutes == 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_H_PIECHART", hours, Localize( pieChartHeader ), pieChartPercent ) + } + else if ( days == 0 && hours == 0 && minutes >= 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_M_PIECHART", minutes, Localize( pieChartHeader ), pieChartPercent ) + } + else if ( days > 0 && hours > 0 && minutes == 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_D_H_PIECHART", days, hours, Localize( pieChartHeader ), pieChartPercent ) + } + else if ( days == 0 && hours > 0 && minutes > 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_H_M_PIECHART", hours, minutes, Localize( pieChartHeader ), pieChartPercent ) + } + else if ( days > 0 && hours == 0 && minutes > 0 ) + { + timeString = Localize( "#STATS_TIME_STRING_D_M_PIECHART", days, minutes, Localize( pieChartHeader ), pieChartPercent ) + } + else + { + Assert( 0, "Unhandled time string creation case" ) + } + + return timeString +} + +string function StatToDistanceString( string category, string alias, string weapon = "" ) +{ + entity player = GetUIPlayer() + if ( player == null ) + return "" + + string statString = GetStatVar( category, alias, weapon ) + float kilometers = expect float( player.GetPersistentVar( statString ) ) + + string formattedNum + if ( kilometers % 1 == 0 ) + formattedNum = format( "%.0f", kilometers ) + else + formattedNum = format( "%.2f", kilometers ) + + string distString = Localize( "#STATS_KILOMETERS_ABBREVIATION", formattedNum ) + + return distString +} + +int function ComparePieChartEntryValues( PieChartEntry a, PieChartEntry b ) +{ + float aVal = a.numValue + float bVal = b.numValue + + if ( aVal < bVal ) + return 1 + else if ( aVal > bVal ) + return -1 + + return 0 +} + +void function SetStatBoxDisplay( var vguiElem, string text, string value ) +{ + var rui = Hud_GetRui( vguiElem ) + + RuiSetString( rui, "statText", text ) + RuiSetString( rui, "statValue", value ) +} + +void function SetMedalStatBoxDisplay( var vguiElem, string text, asset image, int value ) +{ + var rui = Hud_GetRui( vguiElem ) + + RuiSetString( rui, "statText", text ) + RuiSetString( rui, "statValue", string( value ) ) + RuiSetImage( rui, "statImage", image ) +} \ No newline at end of file diff --git a/mod/scripts/vscripts/ui/menu_stats_weapons.nut b/mod/scripts/vscripts/ui/menu_stats_weapons.nut new file mode 100644 index 0000000..3f86c63 --- /dev/null +++ b/mod/scripts/vscripts/ui/menu_stats_weapons.nut @@ -0,0 +1,187 @@ +//TODO: Kills Per Minute stat + +global function InitViewStatsWeaponsMenu + +struct +{ + var menu + GridMenuData gridData + bool isGridInitialized = false + array allPilotWeapons +} file + +void function InitViewStatsWeaponsMenu() +{ + var menu = GetMenu( "ViewStats_Weapons_Menu" ) + file.menu = menu + + Hud_SetText( Hud_GetChild( file.menu, "MenuTitle" ), "#STATS_PILOT_WEAPONS" ) + + file.gridData.rows = 5 + file.gridData.columns = 1 + //file.gridData.numElements // Set in OnViewStatsWeapons_Open after itemdata exists + file.gridData.pageType = eGridPageType.VERTICAL + file.gridData.tileWidth = 224 + file.gridData.tileHeight = 112 + file.gridData.paddingVert = 6 + file.gridData.paddingHorz = 6 + + Grid_AutoAspectSettings( menu, file.gridData ) + + file.gridData.initCallback = WeaponButton_Init + file.gridData.getFocusCallback = WeaponButton_GetFocus + //file.gridData.clickCallback = WeaponButton_Activate + + AddMenuEventHandler( file.menu, eUIEvent.MENU_OPEN, OnViewStatsWeapons_Open ) + + AddMenuFooterOption( file.menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) +} + +void function OnViewStatsWeapons_Open() +{ + //UI_SetPresentationType( ePresentationType.NO_MODELS ) + UI_SetPresentationType( ePresentationType.STORE_WEAPON_SKINS ) + + // Get Pilot weapon list + file.allPilotWeapons = GetVisibleItemsOfType( eItemTypes.PILOT_PRIMARY ) + file.allPilotWeapons.extend( GetVisibleItemsOfType( eItemTypes.PILOT_SECONDARY ) ) + file.allPilotWeapons.sort( SortItemsAlphabetically ) + //file.allPilotWeapons.extend( GetVisibleItemsOfType( eItemTypes.PILOT_ORDNANCE ) ) + //file.allPilotWeapons.extend( GetVisibleItemsOfType( eItemTypes.PILOT_SPECIAL ) ) + + file.gridData.numElements = file.allPilotWeapons.len() + + if ( !file.isGridInitialized ) + { + GridMenuInit( file.menu, file.gridData ) + file.isGridInitialized = true + } + + file.gridData.currentPage = 0 + + Grid_InitPage( file.menu, file.gridData ) + Hud_SetFocused( Grid_GetButtonForElementNumber( file.menu, 0 ) ) + UpdateStatsForWeapon( file.allPilotWeapons[ 0 ].ref ) +} + +bool function WeaponButton_Init( var button, int elemNum ) +{ + string ref = file.allPilotWeapons[ elemNum ].ref + int itemType = GetItemType( ref ) + + var rui = Hud_GetRui( button ) + asset image = GetImage( itemType, ref ) + RuiSetImage( rui, "buttonImage", image ) + + Hud_SetEnabled( button, true ) + Hud_SetVisible( button, true ) + + return true +} + +void function WeaponButton_GetFocus( var button, int elemNum ) +{ + //if ( IsControllerModeActive() ) + UpdateStatsForWeapon( file.allPilotWeapons[ elemNum ].ref ) +} + +//void function WeaponButton_Activate( var button, int elemNum ) +//{ +// if ( !IsControllerModeActive() ) +// UpdateStatsForWeapon( file.allPilotWeapons[ elemNum ].ref ) +//} + +void function UpdateStatsForWeapon( string weaponRef ) +{ + //Sliced names are to be removed afterwards + string slicedName = "" + if(weaponRef.find("mp_weapon")){ + slicedName = weaponRef.slice(10) + } + entity player = GetUIPlayer() + if ( player == null ) + return + + RunMenuClientFunction( "UpdateStoreWeaponModelSkin", weaponRef, 0 ) + + // Name + Hud_SetText( Hud_GetChild( file.menu, "WeaponName" ), GetItemName( weaponRef ) ) + + // Locked info + var lockLabel = GetElementsByClassname( file.menu, "LblWeaponLocked" )[0] + + if ( IsItemLocked( player, weaponRef ) ) + { + Hud_SetText( lockLabel, "#LOUADOUT_UNLOCK_REQUIREMENT_LEVEL", GetUnlockLevelReq( weaponRef ) ) + Hud_Show( lockLabel ) + } + else + { + Hud_Hide( lockLabel ) + } + + // Get required data needed for some calculations + //float hoursUsed = GetPlayerStatFloat( player, "weapon_stats", "hoursUsed", weaponRef ) + string timeUsed = StatToTimeString( "weapon_stats", "hoursUsed", weaponRef ) + int shotsHit = GetPlayerStatInt( player, "weapon_stats", "shotsHit", weaponRef ) + int headshots = GetPlayerStatInt( player, "weapon_stats", "headshots", weaponRef ) + int crits = GetPlayerStatInt( player, "weapon_stats", "critHits", weaponRef ) + + string headShotsValue = Localize( "#STATS_NOT_APPLICABLE" ) + bool headshotWeapon = GetWeaponInfoFileKeyField_Global( weaponRef, "allow_headshots" ) == true + if ( headshotWeapon ) + headShotsValue = string( headshots ) + + string critHitsValue = Localize( "#STATS_NOT_APPLICABLE" ) + bool critHitWeapon = GetWeaponInfoFileKeyField_Global( weaponRef, "critical_hit" ) == true + if ( critHitWeapon ) + critHitsValue = string( crits ) + + SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat0" ), Localize( "#STATS_HEADER_TIME_USED" ), timeUsed ) + SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat1" ), Localize( "#STATS_HEADER_SHOTS_HIT" ), string( shotsHit ) ) + SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat2" ), Localize( "#STATS_HEADER_HEADSHOTS" ), headShotsValue ) + SetStatBoxDisplay( Hud_GetChild( file.menu, "Stat3" ), Localize( "#STATS_HEADER_CRITICAL_HITS" ), critHitsValue ) + + string nextUnlockRef = GetNextUnlockForWeaponLevel( player, weaponRef, WeaponGetRawLevel( player, weaponRef ) + 1 ) + if ( nextUnlockRef != "" ) + { + var rui = Hud_GetRui( Hud_GetChild( file.menu, "NextUnlock" ) ) + + if ( nextUnlockRef == "random" ) + { + RuiSetString( rui, "unlockName", "" ) + RuiSetImage( rui, "unlockImage", $"rui/menu/common/unlock_random" ) + } + else + { + ItemDisplayData displayData + if ( IsSubItemType( GetItemType( nextUnlockRef ) ) ) + displayData = GetItemDisplayData( nextUnlockRef, weaponRef ) + else + displayData = GetItemDisplayData( nextUnlockRef ) + + RuiSetString( rui, "unlockName", displayData.name ) + RuiSetImage( rui, "unlockImage", displayData.image ) + + vector aspect = GetItemImageAspect( nextUnlockRef ) + + float mult = 1.0 + if ( aspect.x > aspect.y ) + mult = 120.0 / aspect.x + else + mult = 120.0 / aspect.y + + aspect.x *= mult + aspect.y *= mult + + RuiSetFloat2( rui, "unlockImageSize", aspect ) + } + //printt( displayData.image ) + } + + // Total Kills Stats + SetStatsLabelValue( file.menu, "KillsValue0", getWeaponKillsFromToneApi(weaponRef) ) + SetStatsLabelValue( file.menu, "KillsValue1", getWeaponKillsFromToneApi(weaponRef) ) + SetStatsLabelValue( file.menu, "KillsValue2", GetPlayerStatInt( player, "weapon_kill_stats", "titansTotal", weaponRef ) ) + SetStatsLabelValue( file.menu, "KillsValue3", GetPlayerStatInt( player, "weapon_kill_stats", "ai", weaponRef ) ) +}