Skip to content

Commit

Permalink
Handle logs with no fight - Fade example
Browse files Browse the repository at this point in the history
  • Loading branch information
Drevarr committed Dec 2, 2024
1 parent 759cb24 commit d9e7073
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 84 deletions.
112 changes: 38 additions & 74 deletions DPSS_Stats.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import math
DPSStats = {}

stacking_uptime_Table = {}

def moving_average(data, window_size):
num_elements = len(data)
Expand Down Expand Up @@ -68,9 +68,8 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config
if skip_fight[player_prof_name]:
continue

DPSStats_prof_name = player_prof_name + " " + player_role
if DPSStats_prof_name not in DPSStats:
DPSStats[DPSStats_prof_name] = {
if player_prof_name not in DPSStats:
DPSStats[player_prof_name] = {
"account": player["account"],
"name": player["name"],
"profession": player["profession"],
Expand All @@ -95,23 +94,23 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config

player_damage = damagePS[player_prof_name]

DPSStats[DPSStats_prof_name]["duration"] += fight_time
DPSStats[DPSStats_prof_name]["combatTime"] += combat_time
DPSStats[DPSStats_prof_name]["Damage_Total"] += player_damage[fight_ticks - 1]
DPSStats[DPSStats_prof_name]["Squad_Damage_Total"] += squad_damage_total
DPSStats[player_prof_name]["duration"] += fight_time
DPSStats[player_prof_name]["combatTime"] += combat_time
DPSStats[player_prof_name]["Damage_Total"] += player_damage[fight_ticks - 1]
DPSStats[player_prof_name]["Squad_Damage_Total"] += squad_damage_total

for statsTarget in player["statsTargets"]:
DPSStats[DPSStats_prof_name]["Downs"] += statsTarget[0]['downed']
DPSStats[DPSStats_prof_name]["Kills"] += statsTarget[0]['killed']
DPSStats[player_prof_name]["Downs"] += statsTarget[0]['downed']
DPSStats[player_prof_name]["Kills"] += statsTarget[0]['killed']

for damage_dist in player['totalDamageDist'][0]:
if damage_dist['id'] in siege_skill_ids:
if damage_dist['id'] in config.siege_skill_ids:
UsedOffensiveSiege[player_prof_name] = True

if "minions" in player:
for minion in player["minions"]:
for minion_damage_dist in minion["totalDamageDist"][0]:
if minion_damage_dist['id'] in siege_skill_ids:
if minion_damage_dist['id'] in config.siege_skill_ids:
UsedOffensiveSiege[player_prof_name] = True

# Coordination_Damage: Damage weighted by coordination with squad
Expand All @@ -132,7 +131,7 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config

squad_damage_percent = squad_damage_on_tick / squad_damage_ma_total

DPSStats[DPSStats_prof_name]["Coordination_Damage"] += player_damage_on_tick * squad_damage_percent * fight.duration
DPSStats[player_prof_name]["Coordination_Damage"] += player_damage_on_tick * squad_damage_percent * fight.duration

# Chunk damage: Damage done within X seconds of target down
for index, target in enumerate(fight_json['targets']):
Expand All @@ -155,13 +154,11 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config
player_prof_name = "{{"+player['profession']+"}} "+player['name']
if skip_fight[player_prof_name]:
continue

DPSStats_prof_name = player_prof_name

damage_on_target = player["targetDamage1S"][index][0]
player_damage = damage_on_target[downIndex] - damage_on_target[startIndex]

DPSStats[DPSStats_prof_name]["Chunk_Damage"][chunk_damage_seconds] += player_damage
DPSStats[player_prof_name]["Chunk_Damage"][chunk_damage_seconds] += player_damage
squad_damage_on_target += player_damage

if chunk_damage_seconds == 5:
Expand All @@ -171,9 +168,7 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config
for player in fight_json['players']:
player_prof_name = "{{"+player['profession']+"}} "+player['name']

DPSStats_prof_name = player_prof_name

DPSStats[DPSStats_prof_name]["Chunk_Damage_Total"][chunk_damage_seconds] += squad_damage_on_target
DPSStats[player_prof_name]["Chunk_Damage_Total"][chunk_damage_seconds] += squad_damage_on_target

# Carrion damage: damage to downs that die
for index, target in enumerate(fight_json['targets']):
Expand All @@ -192,11 +187,10 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config
if skip_fight[player_prof_name]:
continue

DPSStats_prof_name = player_prof_name
damage_on_target = player["targetDamage1S"][index][0]
carrion_damage = damage_on_target[dmgEnd] - damage_on_target[dmgStart]

DPSStats[DPSStats_prof_name]["Carrion_Damage"] += carrion_damage
DPSStats[player_prof_name]["Carrion_Damage"] += carrion_damage
total_carrion_damage += carrion_damage

for i in range(dmgStart, dmgEnd):
Expand All @@ -206,10 +200,8 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config
player_prof_name = "{{"+player['profession']+"}} "+player['name']
if skip_fight[player_prof_name]:
continue

player_role = player_roles[player_prof_name]
DPSStats_prof_name = player_prof_name + " " + player_role
DPSStats[DPSStats_prof_name]["Carrion_Damage_Total"] += total_carrion_damage

DPSStats[player_prof_name]["Carrion_Damage_Total"] += total_carrion_damage

# Burst damage: max damage done in n seconds
for player in fight_json['players']:
Expand All @@ -218,12 +210,11 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config
# Exclude Dragon Banner from Burst stats
continue

DPSStats_prof_name = player_prof_name
player_damage = damagePS[player_prof_name]
for i in range(1, CHUNK_DAMAGE_SECONDS):
for fight_tick in range(i, fight_ticks):
dmg = player_damage[fight_tick] - player_damage[fight_tick - i]
DPSStats[DPSStats_prof_name]["Burst_Damage"][i] = max(dmg, DPSStats[DPSStats_prof_name]["Burst_Damage"][i])
DPSStats[player_prof_name]["Burst_Damage"][i] = max(dmg, DPSStats[player_prof_name]["Burst_Damage"][i])

# Ch5Ca Burst damage: max damage done in n seconds
for player in fight_json['players']:
Expand All @@ -232,7 +223,6 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config
# Exclude Dragon Banner from Burst stats
continue

DPSStats_prof_name = player_prof_name
player_damage_ps = Ch5CaDamage1S[player_prof_name]
player_damage = [0] * len(player_damage_ps)
player_damage[0] = player_damage_ps[0]
Expand All @@ -241,30 +231,30 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config
for i in range(1, CHUNK_DAMAGE_SECONDS):
for fight_tick in range(i, fight_ticks):
dmg = player_damage[fight_tick] - player_damage[fight_tick - i]
DPSStats[DPSStats_prof_name]["Ch5Ca_Burst_Damage"][i] = max(dmg, DPSStats[DPSStats_prof_name]["Ch5Ca_Burst_Damage"][i])
DPSStats[player_prof_name]["Ch5Ca_Burst_Damage"][i] = max(dmg, DPSStats[player_prof_name]["Ch5Ca_Burst_Damage"][i])

return DPSStats

def calculate_stacking_uptimes(fight_json, fight, players_running_healing_addon, config, combat_time, fight_time):
# Track Stacking Buff Uptimes
damage_with_buff_buffs = ['stability', 'protection', 'aegis', 'might', 'fury', 'resistance', 'resolution', 'quickness', 'swiftness', 'alacrity', 'vigor', 'regeneration']
for player in fight_json['players']:
player_prof_name = "{{"+player['profession']+"}} "+player['name']
if skip_fight[player_prof_name]:
continue

player_role = player_roles[player_prof_name]
DPSStats_prof_name = player_prof_name + " " + player_role
if DPSStats_prof_name not in stacking_uptime_Table:
stacking_uptime_Table[DPSStats_prof_name] = {}
stacking_uptime_Table[DPSStats_prof_name]["account"] = player['account']
stacking_uptime_Table[DPSStats_prof_name]["name"] = player['name']
stacking_uptime_Table[DPSStats_prof_name]["profession"] = player['profession']
stacking_uptime_Table[DPSStats_prof_name]["role"] = player_role
stacking_uptime_Table[DPSStats_prof_name]["duration_might"] = 0
stacking_uptime_Table[DPSStats_prof_name]["duration_stability"] = 0
stacking_uptime_Table[DPSStats_prof_name]["might"] = [0] * 26
stacking_uptime_Table[DPSStats_prof_name]["stability"] = [0] * 26
stacking_uptime_Table[DPSStats_prof_name]["firebrand_pages"] = {}
if player_prof_name not in stacking_uptime_Table:
stacking_uptime_Table[player_prof_name] = {}
stacking_uptime_Table[player_prof_name]["account"] = player['account']
stacking_uptime_Table[player_prof_name]["name"] = player['name']
stacking_uptime_Table[player_prof_name]["profession"] = player['profession']
stacking_uptime_Table[player_prof_name]["duration_might"] = 0
stacking_uptime_Table[player_prof_name]["duration_stability"] = 0
stacking_uptime_Table[player_prof_name]["might"] = [0] * 26
stacking_uptime_Table[player_prof_name]["stability"] = [0] * 26
stacking_uptime_Table[player_prof_name]["firebrand_pages"] = {}
for buff_name in damage_with_buff_buffs:
stacking_uptime_Table[DPSStats_prof_name]["damage_with_"+buff_name] = [0] * 26 if buff_name == 'might' else [0] * 2
stacking_uptime_Table[player_prof_name]["damage_with_"+buff_name] = [0] * 26 if buff_name == 'might' else [0] * 2

player_damage = damagePS[player_prof_name]
player_damage_per_tick = [player_damage[0]]
Expand All @@ -287,7 +277,7 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config
if buff_name in ['stability', 'might']:
uptime = state_end - state_start
total_time += uptime
stacking_uptime_Table[DPSStats_prof_name][buff_name][min(stacks, 25)] += uptime
stacking_uptime_Table[player_prof_name][buff_name][min(stacks, 25)] += uptime

if buff_name in damage_with_buff_buffs:
start_sec = state_start / 1000
Expand Down Expand Up @@ -328,36 +318,10 @@ def calculate_dps_stats(fight_json, fight, players_running_healing_addon, config
damage_with_stacks += player_damage_per_tick[next_start_sec_int] * (next_start_sec_rem)

if buff_name == 'might':
stacking_uptime_Table[DPSStats_prof_name]["damage_with_"+buff_name][min(stacks, 25)] += damage_with_stacks
stacking_uptime_Table[player_prof_name]["damage_with_"+buff_name][min(stacks, 25)] += damage_with_stacks
else:
stacking_uptime_Table[DPSStats_prof_name]["damage_with_"+buff_name][min(stacks, 1)] += damage_with_stacks
stacking_uptime_Table[player_prof_name]["damage_with_"+buff_name][min(stacks, 1)] += damage_with_stacks

if buff_name in ['stability', 'might']:
stacking_uptime_Table[DPSStats_prof_name]["duration_"+buff_name] += total_time

if player_prof_name not in FB_Pages:
FB_Pages[player_prof_name] = {}
FB_Pages[player_prof_name]["account"] = player['account']
FB_Pages[player_prof_name]["name"] = player['name']
FB_Pages[player_prof_name]["fightTime"] = 0
FB_Pages[player_prof_name]["firebrand_pages"] = {}

# Track Firebrand Buffs
tome1_skill_ids = ["41258", "40635", "42449", "40015", "42898"]
tome2_skill_ids = ["45022", "40679", "45128", "42008", "42925"]
tome3_skill_ids = ["42986", "41968", "41836", "40988", "44455"]
tome_skill_ids = [
*tome1_skill_ids,
*tome2_skill_ids,
*tome3_skill_ids,
]

if player['profession'] == "Firebrand" and "rotation" in player:
FB_Pages[player_prof_name]["fightTime"] += player['activeTimes'][0]/1000
for rotation_skill in player['rotation']:
skill_id = str(rotation_skill['id'])
if skill_id in tome_skill_ids:
pages_data = FB_Pages[player_prof_name]["firebrand_pages"]
pages_data[skill_id] = pages_data.get(skill_id, 0) + len(rotation_skill['skills'])

return DPSStats
stacking_uptime_Table[player_prof_name]["duration_"+buff_name] += total_time

10 changes: 10 additions & 0 deletions config_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,16 @@
54941, 54953, 21615, 23267, 18792, 18793, 25533, 27927, 30765, 34797
]

siege_skill_ids = [
*arrow_cart_skill_ids,
*trebuchet_skill_ids,
*catapult_skill_ids,
*cannon_skill_ids,
*burning_oil_skill_ids,
*dragon_banner_skill_ids,
*golem_skills,
]

exclude_skill_ids = [
*arrow_cart_skill_ids,
*trebuchet_skill_ids,
Expand Down
23 changes: 15 additions & 8 deletions output_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ def build_tag_summary(top_stats):
tag_summary[commander]["fight_time"] += fight_data["fight_durationMS"]
tag_summary[commander]["enemy_killed"] += fight_data["enemy_killed"]
tag_summary[commander]["enemy_downed"] += fight_data["enemy_downed"]
tag_summary[commander]["squad_downed"] += fight_data["defenses"]["downCount"]
tag_summary[commander]["squad_deaths"] += fight_data["defenses"]["deadCount"]
tag_summary[commander]["squad_downed"] += fight_data.get("defenses", {}).get("downCount", 0)
tag_summary[commander]["squad_deaths"] += fight_data.get("defenses", {}).get("deadCount", 0)

return tag_summary, tag_list

Expand Down Expand Up @@ -416,14 +416,20 @@ def build_fight_summary(top_stats: dict, caption: str, tid_date_time : str) -> N
fight_link = f"[[{fight_data['fight_date']} - {fight_data['fight_end']} - {abbrv}|{fight_data['fight_link']}]]"

# Build the row
damage_taken = fight_data['defenses']['damageTaken'] or 1
damage_taken = fight_data['defenses'].get('damageTaken', 1)
downed = fight_data['statsTargets'].get('downed', 0)
killed = fight_data['statsTargets'].get('killed', 0)
def_down = fight_data['defenses'].get('downCount', 0)
def_dead = fight_data['defenses'].get('deadCount', 0)
dmg_out = fight_data['dpsTargets'].get('damage', 0)
def_barrier = fight_data['defenses'].get('damageBarrier', 0)
row += f"|{fight_num} |{fight_link} | {fight_data['fight_duration']}| {fight_data['squad_count']} | {fight_data['non_squad_count']} | {fight_data['enemy_count']} "
row += f"| {fight_data['enemy_Red']}/{fight_data['enemy_Green']}/{fight_data['enemy_Blue']} | {fight_data['statsTargets']['downed']} | {fight_data['statsTargets']['killed']} "
row += f"| {fight_data['defenses']['downCount']} | {fight_data['defenses']['deadCount']} | {fight_data['dpsTargets']['damage']:,}| {fight_data['defenses']['damageTaken']:,}"
row += f"| {fight_data['defenses']['damageBarrier']:,}| {(fight_data['defenses']['damageBarrier'] / damage_taken * 100):.2f}%| {fight_shield_damage:,}"
row += f"| {fight_data['enemy_Red']}/{fight_data['enemy_Green']}/{fight_data['enemy_Blue']} | {downed} | {killed} "
row += f"| {def_down} | {def_dead} | {dmg_out:,}| {damage_taken:,}"
row += f"| {def_barrier:,}| {(def_barrier / damage_taken * 100):.2f}%| {fight_shield_damage:,}"
# Calculate the shield damage percentage
if fight_data['dpsTargets']['damage']:
shield_damage_pct = (fight_shield_damage / fight_data['dpsTargets']['damage'] * 100)
if dmg_out:
shield_damage_pct = (fight_shield_damage / dmg_out * 100)
else:
shield_damage_pct = 0
row += f"| {shield_damage_pct:.2f}%|"
Expand Down Expand Up @@ -724,6 +730,7 @@ 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"]:
Expand Down
9 changes: 7 additions & 2 deletions parser_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,7 @@ def parse_file(file_path, fight_num, guild_data):
fight_name = json_data['fightName']
fight_link = json_data['uploadLinks'][0]
dist_to_com = []
player_in_combat = 0

enemy_engaged_count = sum(1 for enemy in targets if not enemy['isFake'])

Expand Down Expand Up @@ -1325,6 +1326,10 @@ def parse_file(file_path, fight_num, guild_data):
'enemy_Unk': 0,
}

for stat_cat in json_stats:
top_stats['fight'][fight_num].setdefault(stat_cat, {})
top_stats['overall'].setdefault(stat_cat, {})

#get commander data
commander_tag_positions, dead_tag_mark, dead_tag = get_commander_tag_data(json_data)

Expand Down Expand Up @@ -1442,8 +1447,8 @@ def parse_file(file_path, fight_num, guild_data):

# Initialize dictionaries for player, fight, and overall stats if they don't exist
top_stats['player'].setdefault(name_prof, {}).setdefault(stat_cat, {})
top_stats['fight'][fight_num].setdefault(stat_cat, {})
top_stats['overall'].setdefault(stat_cat, {})
#top_stats['fight'][fight_num].setdefault(stat_cat, {})
#top_stats['overall'].setdefault(stat_cat, {})

# format: player[stat_category][0][stat]
if stat_cat in ['defenses', 'support', 'statsAll']:
Expand Down

0 comments on commit d9e7073

Please sign in to comment.