diff --git a/output_functions.py b/output_functions.py index cc2181b..45e92e5 100644 --- a/output_functions.py +++ b/output_functions.py @@ -729,7 +729,6 @@ def build_uptime_summary(top_stats: dict, boons: dict, buff_data: dict, caption: # Build the Squad table rows header2 = f"|Squad Average Uptime |<|<|<|<|" for boon_id in boons: - print(f"{boon_id=}") if boon_id not in buff_data: continue if boon_id not in top_stats["overall"]["buffUptimes"]: @@ -1345,7 +1344,7 @@ def build_buffs_stats_tid(datetime): caption = "Buffs" creator = "Drevarr@github.com" - text = (f"<>") @@ -1685,6 +1684,84 @@ def build_mechanics_tid(mechanics: dict, players: dict, caption: str, tid_date_t tid_list ) +def build_personal_buff_summary(top_stats: dict, buff_data: dict, personal_buff_data: dict, caption: str, tid_date_time: str) -> None: + """Print a table of personal buff stats for all players in the log running the extension. + + Args: + top_stats (dict): Dictionary containing top statistics for players. + buff_data (dict): Dictionary containing buff stats for each player. + caption (str): The caption for the table. + tid_date_time (str): A string to use as the date and time for the table id. + """ + personal_buffs_tags = f"{tid_date_time}" + personal_buff_title = f"{tid_date_time}-Personal-Buffs" + personal_buff_caption = f"{caption}" + personal_buff_creator = f"Drevarr@github.com" + personal_buff_text ="<>" + append_tid_for_output( + create_new_tid_from_template(personal_buff_title, personal_buff_caption, personal_buff_text, personal_buffs_tags, creator=personal_buff_creator), + tid_list + ) + + for profession in personal_buff_data: + if profession == 'total': + continue + prof_buff_list = personal_buff_data[profession] + + rows = [] + rows.append('
\n\n') + # Build the table header + header = "|thead-dark table-caption-top table-hover sortable|k\n" + header += "|!Party |!Name | !Prof |!Account | !{{FightTime}} |" + for buff_id in prof_buff_list: + if buff_id not in buff_data: + continue + skillIcon = buff_data[buff_id]["icon"] + header += f"! [img width=24 [{buff_data[buff_id]['name']}|{skillIcon}]] |" + header += "h" + rows.append(header) + + # Build the table body + for player, player_data in top_stats['player'].items(): + if player_data['profession'] == profession: + + # Build the row + row = f"| {player_data['last_party']} |{player_data['name']} | {{{{{player_data['profession']}}}}} |{player_data['account'][:32]} | {player_data['fight_time'] / 1000:.2f}|" + + for buff_id in prof_buff_list: + if buff_id in player_data['buffUptimes']: + buff_id_uptime = round((player_data['buffUptimes'][buff_id]['uptime_ms'] / player_data['fight_time']) * 100, 2) + state_changes = player_data['buffUptimes'][buff_id]['state_changes'] + tooltip = f"{state_changes} state changes" + detail_entry = f'
{buff_id_uptime:.2f}% {tooltip}
' + + row += f" {detail_entry} |" + else: + row += f" - |" + rows.append(row) + + # Add caption row and finalize table + rows.append(f"|{caption} Table|c") + rows.append("\n\n
") + + # Convert rows to text and append to output list + tid_text = "\n".join(rows) + personal_buff_title = f"{tid_date_time}-{caption.replace(' ','-')}-{profession}" + profession = "{{"+f"{profession}"+"}}" + prof_caption = f"{profession}-Personal-Buffs" + append_tid_for_output( + create_new_tid_from_template(f"{personal_buff_title}", prof_caption, tid_text), + tid_list + ) + + def build_minions_tid(minions: dict, players: dict, caption: str, tid_date_time: str) -> None: """ Build a table of minions for each player in the log. @@ -2250,7 +2327,7 @@ def write_data_to_db(top_stats: dict, last_fight: str) -> None: print("Database updated.") -def output_top_stats_json(top_stats: dict, buff_data: dict, skill_data: dict, damage_mod_data: dict, high_scores: dict, personal_damage_mod_data: dict, fb_pages: dict, mechanics: dict, minions: dict, death_on_tag: dict, outfile: str) -> None: +def output_top_stats_json(top_stats: dict, buff_data: dict, skill_data: dict, damage_mod_data: dict, high_scores: dict, personal_damage_mod_data: dict, personal_buff_data: dict, fb_pages: dict, mechanics: dict, minions: dict, death_on_tag: dict, outfile: str) -> None: """Print the top_stats dictionary as a JSON object to the console.""" json_dict = {} @@ -2265,6 +2342,7 @@ def output_top_stats_json(top_stats: dict, buff_data: dict, skill_data: dict, da json_dict["skill_casts_by_role"] = {key: value for key, value in top_stats["skill_casts_by_role"].items()} json_dict["high_scores"] = {key: value for key, value in high_scores.items()} json_dict["personal_damage_mod_data"] = {key: value for key, value in personal_damage_mod_data.items()} + json_dict['personal_buff_data'] = {key: value for key, value in personal_buff_data.items()} json_dict["fb_pages"] = {key: value for key, value in fb_pages.items()} json_dict["mechanics"] = {key: value for key, value in mechanics.items()} json_dict["minions"] = {key: value for key, value in minions.items()} diff --git a/parser_functions.py b/parser_functions.py index 9014c1f..d6a9ec6 100644 --- a/parser_functions.py +++ b/parser_functions.py @@ -37,7 +37,9 @@ personal_damage_mod_data = { "total": [], } -personal_buff_data = {} +personal_buff_data = { + "total": [], +} players_running_healing_addon = [] @@ -432,7 +434,22 @@ def get_personal_mod_data(personal_damage_mods: dict) -> None: def get_personal_buff_data(personal_buffs: dict) -> None: - pass + """ + Populate the personal_buff_data dictionary with buffs from personal_buffs. + + Args: + personal_buffs (dict): A dictionary where keys are professions and values are lists of buff IDs. + """ + for profession, buffs in personal_buffs.items(): + if profession not in personal_buff_data: + personal_buff_data[profession] = [] + for buff_id in buffs: + # Convert the buff ID to the format used in buff_data + buff_id = "b" + str(buff_id) + if buff_id not in personal_buff_data[profession]: + personal_buff_data[profession].append(buff_id) + # Add the buff to the total list + personal_buff_data['total'].append(buff_id) def get_enemies_by_fight(fight_num: int, targets: dict) -> None: @@ -670,6 +687,7 @@ def get_buff_uptimes(fight_num: int, player: dict, group: str, stat_category: st buff_id = 'b'+str(buff['id']) buff_uptime_ms = buff['buffData'][0]['uptime'] * fight_duration / 100 buff_presence = buff['buffData'][0]['presence'] + state_changes = len(buff['states'])//2 if buff_id not in top_stats['player'][name_prof][stat_category]: top_stats['player'][name_prof][stat_category][buff_id] = {} @@ -690,6 +708,7 @@ def get_buff_uptimes(fight_num: int, player: dict, group: str, stat_category: st stat_value = buff_presence * active_time / 100 if buff_presence else buff_uptime_ms top_stats['player'][name_prof][stat_category][buff_id]['uptime_ms'] = top_stats['player'][name_prof][stat_category][buff_id].get('uptime_ms', 0) + stat_value + top_stats['player'][name_prof][stat_category][buff_id]['state_changes'] = top_stats['player'][name_prof][stat_category][buff_id].get('state_changes', 0) + state_changes top_stats['fight'][fight_num][stat_category][buff_id]['uptime_ms'] = top_stats['fight'][fight_num][stat_category][buff_id].get('uptime_ms', 0) + stat_value top_stats['overall'][stat_category][buff_id]['uptime_ms'] = top_stats['overall'][stat_category][buff_id].get('uptime_ms', 0) + stat_value top_stats['overall'][stat_category]["group"][group][buff_id]['uptime_ms'] = top_stats['overall'][stat_category]["group"][group][buff_id].get('uptime_ms', 0) + stat_value @@ -1353,6 +1372,9 @@ def parse_file(file_path, fight_num, guild_data): get_personal_mod_data(personal_damage_mods) get_damage_mods_data(damage_mod_map, personal_damage_mod_data) + #collect personal buff data + get_personal_buff_data(personal_buffs) + #collect mechanics data get_mechanics_by_fight(fight_num, mechanics_map, players, log_type) diff --git a/tw5_top_stats.py b/tw5_top_stats.py index c60a0e3..bc62ba3 100644 --- a/tw5_top_stats.py +++ b/tw5_top_stats.py @@ -221,6 +221,8 @@ #get heal stats found and output table build_healing_summary(top_stats, "Heal Stats", tid_date_time) + #get personal buffs found and output table + build_personal_buff_summary(top_stats, buff_data, personal_buff_data, "Personal Buffs", tid_date_time) #get profession damage modifiers found and output table build_personal_damage_modifier_summary(top_stats, personal_damage_mod_data, damage_mod_data, "Damage Modifiers", tid_date_time) @@ -265,7 +267,7 @@ write_tid_list_to_json(tid_list, args.output_filename) if write_all_data_to_json: - output_top_stats_json(top_stats, buff_data, skill_data, damage_mod_data, high_scores, personal_damage_mod_data, fb_pages, mechanics, minions, death_on_tag, args.json_output_filename) + output_top_stats_json(top_stats, buff_data, skill_data, damage_mod_data, high_scores, personal_damage_mod_data, personal_buff_data, fb_pages, mechanics, minions, death_on_tag, args.json_output_filename) if db_update: write_data_to_db(top_stats, top_stats['overall']['last_fight'])