diff --git a/engine/action/snapshot_stats.cpp b/engine/action/snapshot_stats.cpp index f87b92de00c..61581a9c9e4 100644 --- a/engine/action/snapshot_stats.cpp +++ b/engine/action/snapshot_stats.cpp @@ -94,6 +94,16 @@ void snapshot_stats_t::execute() buffed_stats.corruption_resistance = p->cache.corruption_resistance(); buffed_stats.leech = p->cache.leech(); + buffed_stats.spell_crit_rating = p->composite_spell_crit_rating(); + buffed_stats.melee_crit_rating = p->composite_melee_crit_rating(); + buffed_stats.spell_haste_rating = p->composite_spell_haste_rating(); + buffed_stats.melee_haste_rating = p->composite_melee_haste_rating(); + buffed_stats.mastery_rating = p->composite_mastery_rating(); + buffed_stats.versatility_rating = p->composite_damage_versatility_rating(); + buffed_stats.avoidance_rating = p->composite_avoidance_rating(); + buffed_stats.leech_rating = p->composite_leech_rating(); + buffed_stats.speed_rating = p->composite_speed_rating(); + buffed_stats.spell_power = static_cast( p->cache.spell_power( SCHOOL_MAX ) * p->composite_spell_power_multiplier() ); buffed_stats.spell_hit = p->cache.spell_hit(); diff --git a/engine/player/player_collected_data.hpp b/engine/player/player_collected_data.hpp index 2f2d0a7e657..a72f83f6184 100644 --- a/engine/player/player_collected_data.hpp +++ b/engine/player/player_collected_data.hpp @@ -157,6 +157,11 @@ struct player_collected_data_t double mastery_value; double damage_versatility, heal_versatility, mitigation_versatility; double leech, run_speed, avoidance; + double spell_crit_rating, melee_crit_rating; + double spell_haste_rating, melee_haste_rating; + double mastery_rating; + double versatility_rating; + double avoidance_rating, leech_rating, speed_rating; double corruption, corruption_resistance; } buffed_stats_snapshot; diff --git a/engine/report/json/report_json.cpp b/engine/report/json/report_json.cpp index 6f0c287413c..511f366a3e6 100644 --- a/engine/report/json/report_json.cpp +++ b/engine/report/json/report_json.cpp @@ -406,7 +406,7 @@ void gear_to_json( JsonOutput root, const player_t& p ) } } -void to_json( JsonOutput root, const player_t& p, const player_collected_data_t::buffed_stats_t& bs, +void to_json( JsonOutput root, const player_collected_data_t::buffed_stats_t& bs, const std::vector& relevant_resources ) { for ( attribute_e a = ATTRIBUTE_NONE; a < ATTRIBUTE_MAX; ++a ) @@ -437,30 +437,27 @@ void to_json( JsonOutput root, const player_t& p, const player_collected_data_t: // doll stats in-game. crit and haste pick the max between melee/spell which seems to be the game logic add_non_zero( root[ "stats" ], "crit_rating", - p.composite_melee_crit_rating() > p.composite_spell_crit_rating() ? p.composite_melee_crit_rating() - : p.composite_spell_crit_rating() ); + bs.melee_crit_rating > bs.spell_crit_rating ? bs.melee_crit_rating : bs.spell_crit_rating ); add_non_zero( root[ "stats" ], "crit_pct", bs.attack_crit_chance > bs.spell_crit_chance ? bs.attack_crit_chance : bs.spell_crit_chance ); double attack_haste_pct = bs.attack_haste != 0 ? 1 / bs.attack_haste - 1 : 0; double spell_haste_pct = bs.spell_haste != 0 ? 1 / bs.spell_haste - 1 : 0; add_non_zero( root[ "stats" ], "haste_rating", - p.composite_melee_haste_rating() > p.composite_spell_haste_rating() - ? p.composite_melee_haste_rating() - : p.composite_spell_haste_rating() ); + bs.melee_haste_rating > bs.spell_haste_rating ? bs.melee_haste_rating : bs.spell_haste_rating ); add_non_zero( root[ "stats" ], "haste_pct", attack_haste_pct > spell_haste_pct ? attack_haste_pct : spell_haste_pct ); - add_non_zero( root[ "stats" ], "mastery_rating", p.composite_mastery_rating() ); + add_non_zero( root[ "stats" ], "mastery_rating", bs.mastery_rating ); add_non_zero( root[ "stats" ], "mastery_pct", bs.mastery_value ); - add_non_zero( root[ "stats" ], "versatility_rating", p.composite_damage_versatility_rating() ); + add_non_zero( root[ "stats" ], "versatility_rating", bs.versatility_rating ); add_non_zero( root[ "stats" ], "versatility_pct", bs.damage_versatility ); - add_non_zero( root[ "stats" ], "avoidance_rating", p.composite_avoidance_rating() ); + add_non_zero( root[ "stats" ], "avoidance_rating", bs.avoidance_rating ); add_non_zero( root[ "stats" ], "avoidance_pct", bs.avoidance ); - add_non_zero( root[ "stats" ], "leech_rating", p.composite_leech_rating() ); + add_non_zero( root[ "stats" ], "leech_rating", bs.leech_rating ); add_non_zero( root[ "stats" ], "leech_pct", bs.leech ); - add_non_zero( root[ "stats" ], "speed_rating", p.composite_speed_rating() ); + add_non_zero( root[ "stats" ], "speed_rating", bs.speed_rating ); add_non_zero( root[ "stats" ], "speed_pct", bs.run_speed ); add_non_zero( root[ "stats" ], "manareg_per_second", bs.manareg_per_second ); @@ -627,7 +624,7 @@ void collected_data_to_json( JsonOutput root, const ::report::json::report_confi } // always include buffed_stats in JSON - to_json( root[ "buffed_stats" ], p, cd.buffed_stats_snapshot, relevant_resources ); + to_json( root[ "buffed_stats" ], cd.buffed_stats_snapshot, relevant_resources ); if ( sim.report_details != 0 ) { diff --git a/engine/report/report_html_player.cpp b/engine/report/report_html_player.cpp index 0f16114cc98..9fb6f001c53 100644 --- a/engine/report/report_html_player.cpp +++ b/engine/report/report_html_player.cpp @@ -1542,10 +1542,11 @@ void print_html_stats( report::sc_html_stream& os, const player_t& p ) os.format( R"(Crit)" "" "" - "{:.2f}%" + "{:.2f}% ({:.0f})" "{:.2f}%" "{:.0f}\n", 100 * buffed_stats.attack_crit_chance, + buffed_stats.melee_crit_rating, 100 * p.composite_melee_crit_chance(), p.composite_melee_crit_rating() ); } @@ -1554,19 +1555,21 @@ void print_html_stats( report::sc_html_stream& os, const player_t& p ) os.format( R"(Melee Crit)" "" "" - "{:.2f}%" + "{:.2f}% ({:.0f})" "{:.2f}%" "{:.0f}\n" R"(Spell Crit)" "" "" - "{:.2f}%" + "{:.2f}% ({:.0f})" "{:.2f}%" "{:.0f}\n", 100 * buffed_stats.attack_crit_chance, + buffed_stats.melee_crit_rating, 100 * p.composite_melee_crit_chance(), p.composite_melee_crit_rating(), 100 * buffed_stats.spell_crit_chance, + buffed_stats.spell_crit_rating, 100 * p.composite_spell_crit_chance(), p.composite_spell_crit_rating() ); } @@ -1575,10 +1578,11 @@ void print_html_stats( report::sc_html_stream& os, const player_t& p ) os.format( R"(Haste)" "" "" - "{:.2f}%" + "{:.2f}% ({:.0f})" "{:.2f}%" "{:.0f}\n", 100 * ( 1 / buffed_stats.attack_haste - 1 ), // Melee/Spell haste have been merged into a single stat. + buffed_stats.melee_haste_rating, 100 * ( 1 / p.composite_melee_haste() - 1 ), p.composite_melee_haste_rating() ); } @@ -1587,19 +1591,21 @@ void print_html_stats( report::sc_html_stream& os, const player_t& p ) os.format( R"(Melee Haste)" "" "" - "{:.2f}%" + "{:.2f}% ({:.0f})" "{:.2f}%" "{:.0f}\n" R"(Spell Haste)" "" "" - "{:.2f}%" + "{:.2f}% ({:.0f})" "{:.2f}%" "{:.0f}\n", 100 * ( 1 / buffed_stats.attack_haste - 1 ), + buffed_stats.melee_haste_rating, 100 * ( 1 / p.composite_melee_haste() - 1 ), p.composite_melee_haste_rating(), 100 * ( 1 / buffed_stats.spell_haste - 1 ), + buffed_stats.spell_haste_rating, 100 * ( 1 / p.composite_spell_haste() - 1 ), p.composite_spell_haste_rating() ); } @@ -1632,10 +1638,11 @@ void print_html_stats( report::sc_html_stream& os, const player_t& p ) os.format( R"(Versatility)" "" "" - "{:.2f}%" + "{:.2f}% ({:.0f})" "{:.2f}%" "{:.0f}\n", 100 * buffed_stats.damage_versatility, + buffed_stats.versatility_rating, 100 * p.composite_damage_versatility(), p.composite_damage_versatility_rating() ); if ( p.primary_role() == ROLE_TANK ) @@ -1676,10 +1683,11 @@ void print_html_stats( report::sc_html_stream& os, const player_t& p ) os.format( R"(Mastery)" "" "" - "{:.2f}%" + "{:.2f}% ({:.0f})" "{:.2f}%" "{:.0f}\n", 100.0 * buffed_stats.mastery_value, + buffed_stats.mastery_rating, 100.0 * p.cache.mastery_value(), p.composite_mastery_rating() ); if ( buffed_stats.mh_attack_expertise > 7.5 ) { diff --git a/engine/sim/profileset.cpp b/engine/sim/profileset.cpp index 607af886dec..4828b634131 100644 --- a/engine/sim/profileset.cpp +++ b/engine/sim/profileset.cpp @@ -1077,35 +1077,35 @@ void save_output_data( profile_set_t& profileset, const player_t* parent_player, // secondary stats profileset.output_data().crit_rating( - util::floor( player->composite_melee_crit_rating() > player->composite_spell_crit_rating() - ? player->composite_melee_crit_rating() - : player->composite_spell_crit_rating() ) ); + util::floor( buffed_stats.melee_crit_rating > buffed_stats.spell_crit_rating + ? buffed_stats.melee_crit_rating + : buffed_stats.spell_crit_rating ) ); profileset.output_data().crit_pct( buffed_stats.attack_crit_chance > buffed_stats.spell_crit_chance ? buffed_stats.attack_crit_chance : buffed_stats.spell_crit_chance ); profileset.output_data().haste_rating( - util::floor( player->composite_melee_haste_rating() > player->composite_spell_haste_rating() - ? player->composite_melee_haste_rating() - : player->composite_spell_haste_rating() ) ); + util::floor( buffed_stats.melee_haste_rating > buffed_stats.spell_haste_rating + ? buffed_stats.melee_haste_rating + : buffed_stats.spell_haste_rating ) ); double attack_haste_pct = 1 / buffed_stats.attack_haste - 1; double spell_haste_pct = 1 / buffed_stats.spell_haste - 1; profileset.output_data().haste_pct( attack_haste_pct > spell_haste_pct ? attack_haste_pct : spell_haste_pct ); - profileset.output_data().mastery_rating( util::floor( player->composite_mastery_rating() ) ); + profileset.output_data().mastery_rating( util::floor( buffed_stats.mastery_rating ) ); profileset.output_data().mastery_pct( buffed_stats.mastery_value ); - profileset.output_data().versatility_rating( util::floor( player->composite_damage_versatility_rating() ) ); + profileset.output_data().versatility_rating( util::floor( buffed_stats.versatility_rating ) ); profileset.output_data().versatility_pct( buffed_stats.damage_versatility ); // tertiary stats - profileset.output_data().avoidance_rating( player->composite_avoidance_rating() ); + profileset.output_data().avoidance_rating( buffed_stats.avoidance_rating ); profileset.output_data().avoidance_pct( buffed_stats.avoidance ); - profileset.output_data().leech_rating( player->composite_leech_rating() ); + profileset.output_data().leech_rating( buffed_stats.leech_rating ); profileset.output_data().leech_pct( buffed_stats.leech ); - profileset.output_data().speed_rating( player->composite_spell_haste_rating() ); + profileset.output_data().speed_rating( buffed_stats.speed_rating ); profileset.output_data().speed_pct( buffed_stats.run_speed ); profileset.output_data().corruption( buffed_stats.corruption );