Spaces:
Runtime error
Runtime error
| from base.attribute import Attribute | |
| from base.skill import Skill | |
| from utils.parser import School | |
| def filter_status(status, school: School, skill_id): | |
| buffs = [] | |
| for buff_id, buff_level, buff_stack in status: | |
| buff = school.buffs[buff_id] | |
| buff.buff_level, buff.buff_stack = buff_level, buff_stack | |
| if buff.gain_attributes or skill_id in buff.gain_skills: | |
| buffs.append(buff) | |
| return tuple(buffs) | |
| def add_buffs(current_buffs, snapshot_buffs, attribute: Attribute, skill: Skill): | |
| if not snapshot_buffs: | |
| for buff in current_buffs: | |
| buff.add_all(attribute, skill) | |
| else: | |
| for buff in snapshot_buffs: | |
| buff.add_snapshot(attribute, skill) | |
| for buff in current_buffs: | |
| buff.add_current(attribute, skill) | |
| def sub_buffs(current_buffs, snapshot_buffs, attribute: Attribute, skill: Skill): | |
| if not snapshot_buffs: | |
| for buff in current_buffs: | |
| buff.sub_all(attribute, skill) | |
| else: | |
| for buff in snapshot_buffs: | |
| buff.sub_snapshot(attribute, skill) | |
| for buff in current_buffs: | |
| buff.sub_current(attribute, skill) | |
| def analyze_details(record, duration: int, attribute: Attribute, school: School): | |
| details = {} | |
| total_damage = 0 | |
| total_gradients = {attr: 0. for attr in attribute.grad_attrs} | |
| duration *= 1000 | |
| for skill, status in record.items(): | |
| skill_id, skill_level, skill_stack = skill | |
| skill: Skill = school.skills[skill_id] | |
| skill.skill_level, skill.skill_stack = skill_level, skill_stack | |
| skill_detail = {} | |
| details[skill.display_name] = skill_detail | |
| for (current_status, snapshot_status), timeline in status.items(): | |
| hit_timeline, critical_timeline = [], [] | |
| for timestamp, critical in timeline: | |
| if critical: | |
| critical_timeline.append(timestamp) | |
| else: | |
| hit_timeline.append(timestamp) | |
| timeline = [t for t in timeline if t[0] < duration] | |
| if not timeline: | |
| continue | |
| current_buffs = filter_status(current_status, school, skill_id) | |
| snapshot_buffs = filter_status(snapshot_status, school, skill_id) | |
| add_buffs(current_buffs, snapshot_buffs, attribute, skill) | |
| damage, expected_critical_strike, critical_damage, expected_damage = skill(attribute) | |
| gradients = analyze_gradients(skill, attribute) | |
| sub_buffs(current_buffs, snapshot_buffs, attribute, skill) | |
| total_damage += expected_damage * len(timeline) | |
| for attr, residual_damage in gradients.items(): | |
| total_gradients[attr] += residual_damage * len(timeline) | |
| buffs = ",".join(buff.display_name for buff in current_buffs) | |
| if snapshot_buffs and current_buffs != snapshot_buffs: | |
| buffs += f"({','.join(buff.display_name for buff in snapshot_buffs)})" | |
| if not buffs: | |
| buffs = "~" | |
| skill_detail[buffs] = dict( | |
| damage=damage, | |
| critical_damage=critical_damage, | |
| expected_damage=expected_damage, | |
| critical_strike=len(critical_timeline) / (len(critical_timeline) + len(hit_timeline)), | |
| expected_critical_strike=expected_critical_strike, | |
| # "timeline": [round(t / 1000, 3) for t in timeline], | |
| count=len(timeline), | |
| gradients=gradients | |
| ) | |
| for attr, residual_damage in total_gradients.items(): | |
| total_gradients[attr] = round(residual_damage / total_damage * 100, 4) | |
| summary = analyze_summary(details) | |
| return total_damage, total_gradients, details, summary | |
| def analyze_summary(details): | |
| summary = {} | |
| for skill, skill_detail in details.items(): | |
| skill = skill.split("/")[0] | |
| if skill not in summary: | |
| summary[skill] = {"count": 0, "critical": 0, "damage": 0} | |
| for buff, detail in skill_detail.items(): | |
| summary[skill]["count"] += detail['count'] | |
| summary[skill]["critical"] += detail['count'] * detail['expected_critical_strike'] | |
| summary[skill]["damage"] += detail['count'] * detail['expected_damage'] | |
| return summary | |
| def analyze_gradients(skill, attribute): | |
| results = {} | |
| for attr, value in attribute.grad_attrs.items(): | |
| origin_value = getattr(attribute, attr) | |
| setattr(attribute, attr, origin_value + value) | |
| _, _, _, results[attr] = skill(attribute) | |
| setattr(attribute, attr, origin_value) | |
| return results | |