Spaces:
Runtime error
Runtime error
File size: 6,715 Bytes
c145eab d26e0de c145eab d26e0de c145eab d26e0de c145eab d26e0de c145eab d26e0de c145eab d26e0de c145eab d26e0de c145eab d26e0de c145eab d26e0de |
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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
from typing import Dict
from gr.components.combat import CombatComponent
from assets.constant import ATTR_TYPE_TRANSLATE
# from gr.scripts.bonuses import Bonuses
# from gr.scripts.consumables import Consumables
from gr.scripts.top import Parser
from gr.scripts.equipments import Equipments
from gr.scripts.recipes import Recipes
from gr.scripts.talents import Talents
from utils.analyzer import analyze_details, Detail
import gradio as gr
FULL_SPACE = "\u3000"
def attribute_content(display_attrs, attribute):
content = []
for attr, name in display_attrs.items():
value = getattr(attribute, attr)
if isinstance(value, int):
content.append(name.ljust(10, FULL_SPACE) + str(value))
else:
content.append(name.ljust(10, FULL_SPACE) + f"{round(value * 100, 2)}%")
return "\n".join(content)
def summary_content(summary: Dict[str, Detail], total_damage):
content = []
for skill in sorted(summary, key=lambda x: summary[x].expected_damage, reverse=True):
detail = summary[skill]
critical = round(detail.critical_count, 2)
critical_rate = round(detail.critical_count / detail.count * 100, 2)
hit = round(detail.count - critical, 2)
hit_rate = round(100 - critical_rate, 2)
damage = round(detail.expected_damage, 2)
damage_rate = round(damage / total_damage * 100, 2)
content.append(
[f"{skill}/{detail.count}",
f"{hit}/{hit_rate}%", f"{critical}/{critical_rate}%", f"{damage}/{damage_rate}%"]
)
return content
def gradient_content(gradients, total_damage):
return "\n".join(
ATTR_TYPE_TRANSLATE[k].ljust(10, FULL_SPACE) + f"{round(v / total_damage * 100, 2)}%"
for k, v in gradients.items()
)
def detail_content(detail: Detail):
damage_detail = "\n".join([
"命中伤害".ljust(10) + f"{round(detail.damage)}",
"会心伤害".ljust(10) + f"{round(detail.critical_damage)}",
"期望伤害".ljust(10) + f"{round(detail.expected_damage)}",
"期望会心".ljust(10) + f"{round(detail.critical_strike * 100, 2)}%",
"实际会心".ljust(10) + f"{round(detail.actual_critical_strike * 100, 2)}%",
"统计数量".ljust(10) + f"{detail.count}"
])
damage_gradient = gradient_content(detail.gradients, detail.expected_damage)
return damage_detail, damage_gradient
def combat_script(
parser: Parser,
talents: Talents, recipes: Recipes, equipments: Equipments,
# consumables: Consumables, bonuses: Bonuses
combat_component: CombatComponent,
):
def formulate(target_level, duration, skill, status):
combat_update = {}
record = parser.current_records
school = parser.current_school
attribute = school.attribute()
attribute.target_level = target_level
for attr, value in equipments.attrs.items():
setattr(attribute, attr, getattr(attribute, attr) + value)
combat_update[combat_component.init_attribute] = gr.update(
value=attribute_content(school.display_attrs, attribute)
)
# for attr, value in consumables.attrs.items():
# setattr(attribute, attr, getattr(attribute, attr) + value)
equipment_gains = [school.gains[gain] for gain in equipments.gains]
talent_gains = [school.talent_gains[school.talent_encoder[talent]] for talent in talents.gains]
recipe_gains = [
school.recipe_gains[skill][recipe]
for i, skill in enumerate(school.recipe_gains)
for recipe in recipes.gains[i]
]
gains = equipment_gains + talent_gains + recipe_gains # + bonuses.gains
for gain in gains:
gain.add(attribute, school.skills, school.buffs)
combat_update[combat_component.final_attribute] = gr.update(
value=attribute_content(school.display_attrs, attribute)
)
total, summary, details = analyze_details(record, duration, attribute, school)
for gain in gains:
gain.sub(attribute, school.skills, school.buffs)
combat_update[combat_component.dps] = gr.update(value=round(total.expected_damage / duration))
combat_update[combat_component.gradient] = gradient_content(total.gradients, total.expected_damage)
combat_update[combat_component.details] = details
combat_update[combat_component.skill_select] = gr.update(choices=list(details))
if skill_detail := details.get(skill, {}):
combat_update[combat_component.status_select] = gr.update(choices=[""] + list(skill_detail))
if detail := skill_detail.get(status):
damage_detail, damage_gradient = detail_content(detail)
combat_update[combat_component.damage_detail] = gr.update(value=damage_detail)
combat_update[combat_component.damage_gradient] = gr.update(value=damage_gradient)
else:
combat_update[combat_component.damage_detail] = gr.update(value="")
combat_update[combat_component.damage_gradient] = gr.update(value="")
combat_update[combat_component.summary] = summary_content(summary, total.expected_damage)
return combat_update
combat_component.formulate.click(
formulate,
[combat_component.target_level, combat_component.combat_duration,
combat_component.skill_select, combat_component.status_select],
[combat_component.init_attribute, combat_component.final_attribute,
combat_component.dps, combat_component.gradient, combat_component.summary,
combat_component.details, combat_component.skill_select, combat_component.status_select,
combat_component.damage_detail, combat_component.damage_gradient
]
)
def skill_changed(skill, details):
if skill not in details:
return None
return gr.update(choices=[""] + list(details[skill]))
combat_component.skill_select.change(
skill_changed, [combat_component.skill_select, combat_component.details], combat_component.status_select
)
def status_changed(skill, status, details):
if skill not in details:
return None, None
if status not in details[skill]:
return None, None
damage_detail, damage_gradient = detail_content(details[skill][status])
return gr.update(value=damage_detail), gr.update(value=damage_gradient)
combat_component.status_select.change(
status_changed, [combat_component.skill_select, combat_component.status_select, combat_component.details],
[combat_component.damage_detail, combat_component.damage_gradient]
)
|