Spaces:
Runtime error
Runtime error
| import pandas as pd | |
| from base.attribute import Attribute | |
| from base.skill import Skill, DotDamage, NpcDamage, PetDamage | |
| from utils.parser import School, Parser, CALCULATE_COLUMNS | |
| DAMAGE_COLUMNS = ["damage", "critical_damage", "critical_strike", "expected_damage"] | |
| def filter_status(status, school: School): | |
| buffs = [] | |
| for buff_id, buff_level, buff_stack in status: | |
| buff = school.buffs[buff_id] | |
| if buff.activate: | |
| buffs.append(buff) | |
| return buffs | |
| def add_buffs(current_buffs, snapshot_buffs, target_buffs, attribute: Attribute, skill: Skill): | |
| if not snapshot_buffs: | |
| for buff in current_buffs: | |
| buff.add_all(attribute, skill) | |
| elif isinstance(skill, DotDamage): | |
| for buff in snapshot_buffs: | |
| buff.add_dot(attribute, skill, True) | |
| for buff in current_buffs: | |
| buff.add_dot(attribute, skill, False) | |
| elif isinstance(skill, NpcDamage): | |
| for buff in snapshot_buffs: | |
| buff.add_all(attribute, skill) | |
| elif isinstance(skill, PetDamage): | |
| for buff in snapshot_buffs: | |
| buff.add_all(attribute, skill) | |
| for buff in target_buffs: | |
| buff.add_all(attribute, skill) | |
| def sub_buffs(current_buffs, snapshot_buffs, target_buffs, attribute: Attribute, skill: Skill): | |
| if not snapshot_buffs: | |
| for buff in current_buffs: | |
| buff.sub_all(attribute, skill) | |
| elif isinstance(skill, DotDamage): | |
| for buff in snapshot_buffs: | |
| buff.sub_dot(attribute, skill, True) | |
| for buff in current_buffs: | |
| buff.sub_dot(attribute, skill, False) | |
| elif isinstance(skill, NpcDamage): | |
| for buff in snapshot_buffs: | |
| buff.sub_all(attribute, skill) | |
| elif isinstance(skill, PetDamage): | |
| for buff in snapshot_buffs: | |
| buff.sub_all(attribute, skill) | |
| for buff in target_buffs: | |
| buff.sub_all(attribute, skill) | |
| def analyze_records(parser: Parser, duration: int, attribute: Attribute): | |
| records: pd.DataFrame = parser.current_records | |
| school = parser.current_school | |
| condition = (records.player_id == parser.current_player) & (records.time < duration) | |
| if parser.current_target: | |
| condition = condition & (records.target_id == parser.current_target) | |
| records = records[condition].copy() | |
| damage_columns = [(0 for _ in DAMAGE_COLUMNS)] * len(records) | |
| grad_attrs = list(attribute.grad_attrs) | |
| gradient_columns = [(0 for _ in grad_attrs)] * len(records) | |
| for row, indices in records.groupby(CALCULATE_COLUMNS).indices.items(): | |
| skill_id, skill_level, skill_stack, current_status, target_status, snapshot_index = row | |
| skill: Skill = school.skills[skill_id] | |
| skill.skill_level, skill.skill_stack = skill_level, skill_stack | |
| current_buffs = filter_status(current_status, school) | |
| target_buffs = filter_status(target_status, school) | |
| if snapshot_index < 0: | |
| snapshot_buffs = tuple() | |
| else: | |
| snapshot_buffs = filter_status(records.loc[snapshot_index].current_status, school) | |
| add_buffs(current_buffs, snapshot_buffs, target_buffs, attribute, skill) | |
| damage_tuple = skill(attribute) | |
| gradient_tuple = analyze_gradients(skill, attribute) | |
| for index in indices: | |
| damage_columns[index] = damage_tuple | |
| gradient_columns[index] = gradient_tuple | |
| sub_buffs(current_buffs, snapshot_buffs, target_buffs, attribute, skill) | |
| records[DAMAGE_COLUMNS] = damage_columns | |
| records[grad_attrs] = gradient_columns | |
| return records | |
| 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) | |
| _, _, _, expected_damage = skill(attribute) | |
| results.append(expected_damage) | |
| setattr(attribute, attr, origin_value) | |
| return results | |