import ast from pathlib import Path SKILL_FILE = ( Path(__file__).resolve().parents[2] / "core" / "character" / "GF" / "swordman_female" / "demon_slayer.py" ) def _skill_class(name: str) -> ast.ClassDef: module = ast.parse(SKILL_FILE.read_text(encoding="utf-8")) return next( node for node in module.body if isinstance(node, ast.ClassDef) and any( isinstance(item, ast.Assign) and any(isinstance(target, ast.Name) and target.id == "name" for target in item.targets) and isinstance(item.value, ast.Constant) and item.value.value == name for item in node.body ) ) def test_blade_dance_shadow_uses_final_hit_damage_not_hit_count(): skill = _skill_class("魔刃狂舞") shadow_final_hit = next( item for item in skill.body if isinstance(item, ast.Assign) and any(isinstance(target, ast.Name) and target.id == "data5" for target in item.targets) ) assert isinstance(shadow_final_hit.value, ast.Name) assert shadow_final_hit.value.id == "data2" def test_blade_dance_shadow_uses_its_own_passive_ratio(minimal_calc_config): from core.basic.character import createCharacter from core.basic.skill_effect_types import Operation, Power, SkillEffect char = createCharacter('GF.swordman_female.demon_slayer') char.calc(minimal_calc_config) passive = char.GetSkillByName('唤魔 : 弑神剑') for level in (1, 10, passive.maxLv): passive.lv = level for index in (4, 5): association = next( entry for entry in passive.associate if isinstance(entry, SkillEffect) and entry.attribute == Power(index) ) assert association.operation == Operation.ADD assert char.GetSkillByName('魔刃狂舞').ref in association.skills assert association.evaluate(passive) == passive.data3[level] / 100