Spaces:
Runtime error
Runtime error
| from base.attribute import Attribute | |
| from base.constant import * | |
| from utils.damage import * | |
| from typing import List, Union | |
| from dataclasses import dataclass | |
| class Skill: | |
| skill_id: int | |
| _skill_name: Union[List[str], str] = "" | |
| skill_level: int = 0 | |
| skill_stack: int = 1 | |
| activate: bool = True | |
| bind_skill: int = None | |
| bind_buff: int = None | |
| max_stack: int = 1 | |
| tick: int = 1 | |
| _damage_base: Union[List[int], int] = 0 | |
| _damage_rand: Union[List[int], int] = 0 | |
| _attack_power_cof: Union[List[float], float] = 0. | |
| _surplus_cof: Union[List[float], float] = 0. | |
| _weapon_damage_cof: Union[List[float], float] = 0. | |
| interval: int = 0 | |
| damage_gain: float = 1. | |
| attack_power_cof_gain: float = 1. | |
| surplus_cof_gain: float = 1. | |
| weapon_damage_cof_gain: float = 1. | |
| skill_damage_addition: int = 0 | |
| skill_pve_addition: int = 0 | |
| _skill_shield_gain: Union[List[int], int] = 0 | |
| skill_critical_strike: int = 0 | |
| skill_critical_power: int = 0 | |
| def display_name(self): | |
| return f"{self.skill_name}#{self.skill_id}-{self.skill_level}-{self.skill_stack}" | |
| def skill_name(self): | |
| if not isinstance(self._skill_name, list): | |
| return "" | |
| if self.skill_level > len(self._skill_name): | |
| return self._skill_name[-1] | |
| else: | |
| return self._skill_name[self.skill_level - 1] | |
| def skill_name(self, skill_name): | |
| if isinstance(skill_name, list): | |
| self._skill_name = skill_name | |
| else: | |
| self._skill_name = [skill_name] | |
| def damage_base(self): | |
| if not isinstance(self._damage_base, list): | |
| return 0 | |
| if self.skill_level > len(self._damage_base): | |
| damage_base = self._damage_base[-1] | |
| else: | |
| damage_base = self._damage_base[self.skill_level - 1] | |
| return damage_base * self.damage_gain | |
| def damage_base(self, damage_base): | |
| if isinstance(damage_base, list): | |
| self._damage_base = damage_base | |
| else: | |
| self._damage_base = [damage_base] | |
| def damage_rand(self): | |
| if not isinstance(self._damage_rand, list): | |
| return 0 | |
| if self.skill_level > len(self._damage_rand): | |
| damage_rand = self._damage_rand[-1] | |
| else: | |
| damage_rand = self._damage_rand[self.skill_level - 1] | |
| return damage_rand * self.damage_gain | |
| def damage_rand(self, damage_rand): | |
| if isinstance(damage_rand, list): | |
| self._damage_rand = damage_rand | |
| else: | |
| self._damage_rand = [damage_rand] | |
| def attack_power_cof(self): | |
| if not isinstance(self._attack_power_cof, list): | |
| return 0 | |
| if self.skill_level > len(self._attack_power_cof): | |
| attack_power_cof = self._attack_power_cof[-1] | |
| else: | |
| attack_power_cof = self._attack_power_cof[self.skill_level - 1] | |
| return attack_power_cof * self.attack_power_cof_gain | |
| def attack_power_cof(self, attack_power_cof): | |
| if isinstance(attack_power_cof, list): | |
| self._attack_power_cof = attack_power_cof | |
| else: | |
| self._attack_power_cof = [attack_power_cof] | |
| def surplus_cof(self): | |
| if not isinstance(self._surplus_cof, list): | |
| return 0 | |
| if self.skill_level > len(self._surplus_cof): | |
| surplus_cof = self._surplus_cof[-1] | |
| else: | |
| surplus_cof = self._surplus_cof[self.skill_level - 1] | |
| return SURPLUS_COF(surplus_cof * self.surplus_cof_gain) | |
| def surplus_cof(self, surplus_cof): | |
| if isinstance(surplus_cof, list): | |
| self._surplus_cof = surplus_cof | |
| else: | |
| self._surplus_cof = [surplus_cof] | |
| def weapon_damage_cof(self): | |
| if not isinstance(self._weapon_damage_cof, list): | |
| return 0 | |
| if self.skill_level > len(self._weapon_damage_cof): | |
| weapon_damage_cof = self._weapon_damage_cof[-1] | |
| else: | |
| weapon_damage_cof = self._weapon_damage_cof[self.skill_level - 1] | |
| return WEAPON_DAMAGE_COF(weapon_damage_cof * self.weapon_damage_cof_gain) | |
| def weapon_damage_cof(self, weapon_damage_cof): | |
| if isinstance(weapon_damage_cof, list): | |
| self._weapon_damage_cof = weapon_damage_cof | |
| else: | |
| self._weapon_damage_cof = [weapon_damage_cof] | |
| def skill_shield_gain(self): | |
| if not isinstance(self._skill_shield_gain, list): | |
| return 0 | |
| if self.skill_level > len(self._skill_shield_gain): | |
| return self._skill_shield_gain[-1] | |
| else: | |
| return self._skill_shield_gain[self.skill_level - 1] | |
| def skill_shield_gain(self, skill_shield_gain): | |
| if isinstance(skill_shield_gain, list): | |
| self._skill_shield_gain = skill_shield_gain | |
| else: | |
| self._skill_shield_gain = [skill_shield_gain] | |
| def record(self, skill_level, critical, parser): | |
| pass | |
| def __call__(self, attribute: Attribute): | |
| return 0 | |
| class BuffSkill(Skill): | |
| pass | |
| class BuffConsumeSkill(Skill): | |
| pass | |
| class DotSkill(Skill): | |
| def record(self, skill_level, critical, parser): | |
| super().record(skill_level, critical, parser) | |
| bind_skill = self.bind_skill | |
| if not parser.current_ticks[bind_skill]: | |
| parser.current_stacks[bind_skill] = 0 | |
| parser.current_ticks[bind_skill] = self.tick | |
| parser.current_stacks[bind_skill] = min(parser.current_stacks[bind_skill] + 1, self.max_stack) | |
| parser.current_snapshot[bind_skill] = parser.current_status.copy() | |
| class DotConsumeSkill(Skill): | |
| def record(self, skill_level, critical, parser): | |
| super().record(skill_level, critical, parser) | |
| bind_skill = self.bind_skill | |
| if not (last_dot := parser.current_last_dot.pop(bind_skill, None)): | |
| return | |
| skill_tuple, status_tuple = last_dot | |
| skill_id, skill_level, skill_stack = skill_tuple | |
| parser.current_ticks[skill_id] += 1 | |
| tick = min(parser.current_ticks[skill_id], self.tick) | |
| parser.current_records[(skill_id, skill_level, skill_stack * tick)][status_tuple].append( | |
| parser.current_records[skill_tuple][status_tuple].pop() | |
| ) | |
| parser.current_ticks[skill_id] -= tick | |
| class PureSkill(Skill): | |
| def __call__(self, attribute: Attribute): | |
| damage = init_result(self.damage_base, self.damage_rand, 0, 0, 0, 0, 0, 0) | |
| damage = level_reduction_result(damage, attribute.level_reduction) | |
| damage = vulnerable_result(damage, attribute.vulnerable) | |
| return damage, damage, damage, 0 | |
| class PhysicalSkill(Skill): | |
| def __call__(self, attribute: Attribute): | |
| damage = init_result( | |
| self.damage_base, self.damage_rand, | |
| self.attack_power_cof, attribute.physical_attack_power, | |
| self.weapon_damage_cof, attribute.weapon_damage, | |
| self.surplus_cof, attribute.surplus | |
| ) * self.skill_stack | |
| damage = damage_addition_result(damage, attribute.physical_damage_addition + self.skill_damage_addition) | |
| damage = overcome_result(damage, attribute.physical_overcome, | |
| attribute.level_shield_base + attribute.physical_shield_base, | |
| attribute.physical_shield_gain + self.skill_shield_gain, | |
| attribute.physical_shield_ignore, | |
| attribute.shield_constant) | |
| critical_power_gain = attribute.physical_critical_power_gain + self.skill_critical_power | |
| critical_damage = critical_result(damage, attribute.base_physical_critical_power, critical_power_gain) | |
| damage = level_reduction_result(damage, attribute.level_reduction) | |
| critical_damage = level_reduction_result(critical_damage, attribute.level_reduction) | |
| damage = strain_result(damage, attribute.base_strain, attribute.strain_gain) | |
| critical_damage = strain_result(critical_damage, attribute.base_strain, attribute.strain_gain) | |
| damage = pve_addition_result(damage, attribute.pve_addition + self.skill_pve_addition) | |
| critical_damage = pve_addition_result(critical_damage, attribute.pve_addition + self.skill_pve_addition) | |
| damage = vulnerable_result(damage, attribute.physical_vulnerable) | |
| critical_damage = vulnerable_result(critical_damage, attribute.physical_vulnerable) | |
| critical_strike = min(1, attribute.physical_critical_strike + self.skill_critical_strike / DECIMAL_SCALE) | |
| expected_damage = critical_strike * critical_damage + (1 - critical_strike) * damage | |
| return damage, critical_damage, expected_damage, critical_strike | |
| class MagicalSkill(Skill): | |
| def __call__(self, attribute: Attribute): | |
| damage = init_result( | |
| self.damage_base, self.damage_rand, | |
| self.attack_power_cof, attribute.magical_attack_power, | |
| self.weapon_damage_cof, attribute.weapon_damage, | |
| self.surplus_cof, attribute.surplus | |
| ) * self.skill_stack | |
| damage = damage_addition_result(damage, attribute.magical_damage_addition + self.skill_damage_addition) | |
| damage = overcome_result(damage, attribute.magical_overcome, | |
| attribute.level_shield_base + attribute.magical_shield_base, | |
| attribute.magical_shield_gain + self.skill_shield_gain, | |
| attribute.magical_shield_ignore, | |
| attribute.shield_constant) | |
| critical_power_gain = attribute.magical_critical_power_gain + self.skill_critical_power | |
| critical_damage = critical_result(damage, attribute.base_magical_critical_power, critical_power_gain) | |
| damage = level_reduction_result(damage, attribute.level_reduction) | |
| critical_damage = level_reduction_result(critical_damage, attribute.level_reduction) | |
| damage = strain_result(damage, attribute.base_strain, attribute.strain_gain) | |
| critical_damage = strain_result(critical_damage, attribute.base_strain, attribute.strain_gain) | |
| damage = pve_addition_result(damage, attribute.pve_addition + self.skill_pve_addition) | |
| critical_damage = pve_addition_result(critical_damage, attribute.pve_addition + self.skill_pve_addition) | |
| damage = vulnerable_result(damage, attribute.magical_vulnerable) | |
| critical_damage = vulnerable_result(critical_damage, attribute.magical_vulnerable) | |
| critical_strike = min(1, attribute.magical_critical_strike + self.skill_critical_strike / DECIMAL_SCALE) | |
| expected_damage = critical_strike * critical_damage + (1 - critical_strike) * damage | |
| return damage, critical_damage, expected_damage, critical_strike | |
| class MixingSkill(Skill): | |
| def __call__(self, attribute: Attribute): | |
| damage = init_result( | |
| self.damage_base, self.damage_rand, | |
| self.attack_power_cof, attribute.magical_attack_power, | |
| self.weapon_damage_cof, attribute.weapon_damage, | |
| self.surplus_cof, attribute.surplus | |
| ) * self.skill_stack | |
| damage = damage_addition_result(damage, attribute.magical_damage_addition + self.skill_damage_addition) | |
| damage = overcome_result(damage, attribute.magical_overcome, | |
| attribute.level_shield_base + attribute.magical_shield_base, | |
| attribute.magical_shield_gain + self.skill_shield_gain, | |
| attribute.magical_shield_ignore, | |
| attribute.shield_constant) | |
| critical_power_gain = attribute.physical_critical_power_gain + self.skill_critical_power | |
| critical_damage = critical_result(damage, attribute.base_physical_critical_power, critical_power_gain) | |
| damage = level_reduction_result(damage, attribute.level_reduction) | |
| critical_damage = level_reduction_result(critical_damage, attribute.level_reduction) | |
| damage = strain_result(damage, attribute.base_strain, attribute.strain_gain) | |
| critical_damage = strain_result(critical_damage, attribute.base_strain, attribute.strain_gain) | |
| damage = pve_addition_result(damage, attribute.pve_addition + self.skill_pve_addition) | |
| critical_damage = pve_addition_result(critical_damage, attribute.pve_addition + self.skill_pve_addition) | |
| damage = vulnerable_result(damage, attribute.magical_vulnerable) | |
| critical_damage = vulnerable_result(critical_damage, attribute.magical_vulnerable) | |
| critical_strike = min(1, attribute.physical_critical_strike + self.skill_critical_strike / DECIMAL_SCALE) | |
| expected_damage = critical_strike * critical_damage + (1 - critical_strike) * damage | |
| return damage, critical_damage, expected_damage, critical_strike | |
| class Damage(Skill): | |
| def record(self, skill_level, critical, parser): | |
| super().record(skill_level, critical, parser) | |
| skill_stack = parser.current_stacks[self.skill_id] | |
| skill_tuple = (self.skill_id, skill_level, skill_stack) | |
| status_tuple = parser.available_status(self.skill_id) | |
| parser.current_records[skill_tuple][status_tuple].append( | |
| (parser.current_frame - parser.start_frame, critical) | |
| ) | |
| return skill_tuple, status_tuple | |
| class DotDamage(Damage): | |
| def record(self, skill_level, critical, parser): | |
| skill_tuple, status_tuple = super().record(skill_level, critical, parser) | |
| parser.current_last_dot[self.skill_id] = (skill_tuple, status_tuple) | |
| parser.current_ticks[self.skill_id] -= 1 | |
| class PetDamage(Damage): | |
| pass | |
| class PureDamage(PureSkill, Damage): | |
| pass | |
| class PhysicalDamage(PhysicalSkill, Damage): | |
| def attack_power_cof(self): | |
| return PHYSICAL_ATTACK_POWER_COF(super().attack_power_cof + self.interval) | |
| class MagicalDamage(MagicalSkill, Damage): | |
| def attack_power_cof(self): | |
| return MAGICAL_ATTACK_POWER_COF(super().attack_power_cof + self.interval) | |
| class MixingDamage(MixingSkill, Damage): | |
| def attack_power_cof(self): | |
| return MAGICAL_ATTACK_POWER_COF(super().attack_power_cof + self.interval) | |
| class PhysicalDotDamage(PhysicalSkill, DotDamage): | |
| def attack_power_cof(self): | |
| return PHYSICAL_DOT_ATTACK_POWER_COF(super().attack_power_cof, self.interval) | |
| class MagicalDotDamage(MagicalSkill, DotDamage): | |
| def attack_power_cof(self): | |
| return MAGICAL_DOT_ATTACK_POWER_COF(super().attack_power_cof, self.interval) | |
| class MixingDotDamage(MixingSkill, DotDamage): | |
| def attack_power_cof(self): | |
| return MAGICAL_DOT_ATTACK_POWER_COF(super().attack_power_cof, self.interval) | |