Spaces:
Runtime error
Runtime error
File size: 4,665 Bytes
2452398 5825182 2452398 5825182 2452398 5825182 970efde 5825182 2452398 5825182 2452398 3ed500d 2452398 88de31c 3ed500d 2452398 5825182 2452398 5825182 970efde 3ed500d 5825182 2452398 970efde 2452398 5825182 2452398 970efde 2452398 970efde 2452398 970efde 2452398 970efde 2452398 970efde 2452398 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
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
|