diff --git a/Paimon_Info/damage_cal/common.py b/Paimon_Info/damage_cal/common.py index 03ecb2f..ad892d7 100644 --- a/Paimon_Info/damage_cal/common.py +++ b/Paimon_Info/damage_cal/common.py @@ -1,11 +1,47 @@ from pathlib import Path - +from typing import Tuple, Dict, Optional, List, Union from ...utils.enka_util import get_artifact_suit +from PIL import Image, ImageDraw +from littlepaimon_utils.files import load_image, load_json +from littlepaimon_utils.images import get_font, draw_center_text text_font = str(Path() / 'resources' / 'LittlePaimon' / 'hywh.ttf') number_font = str(Path() / 'resources' / 'LittlePaimon' / 'number.ttf') +def udc(dm: float, + crit: Tuple[float, float], + db: float, + sl: int, + rcb: Optional[float] = 0.1, + rcd: Optional[float] = 0, + el: Optional[int] = 90, + dcr: Optional[float] = 0, + dci: Optional[float] = 0, + r: Optional[float] = 1, + ) -> List[str]: + """ + 计算伤害 + :param dm: 倍率区 + :param crit: 暴击区 + :param db: 增伤区 + :param sl: 角色等级 + :param rcb: 怪物基础抗性 + :param rcd: 抗性减少 + :param el: 怪物等级 + :param dcr: 抗性系数减少 + :param dci: 无视防御系数 + :param r: 反应最终系数 + :return: 伤害 + """ + if crit[0] > 1: + damage = dm * (1 + crit[1]) * (1 + db) * resistance_coefficient(rcb, rcd) * defense_coefficient(sl, el, dcr, dci) * r + return [str(int(damage)), str(int(damage))] + else: + damage = dm * (1 + crit[0] * crit[1]) * (1 + db) * resistance_coefficient(rcb, rcd) * defense_coefficient(sl, el, dcr, dci) * r + return [str(int(damage)), str(int(damage / (1 + crit[0] * crit[1]) * (1 + crit[1])))] + + def resistance_coefficient(base_resistance: float = 0.1, reduction_rate: float = 0): """ 计算抗性系数 @@ -22,7 +58,7 @@ def resistance_coefficient(base_resistance: float = 0.1, reduction_rate: float = return 1 - (resistance / 2) -def defense_coefficient(self_level: int, enemy_level: int = 90, reduction_rate: float = 0, ignore: float = 0): +def defense_coefficient(self_level: int = 90, enemy_level: int = 90, reduction_rate: float = 0, ignore: float = 0): """ 计算防御力系数 :param self_level: 角色自身等级 @@ -71,15 +107,178 @@ def upheaval_reaction(level: int, type: str, mastery: int = 0, extra_coefficient return base_coefficient * base_ratio * (1 + mastery_increase + extra_coefficient) * resistance -def polearm_common_fix(data: dict): +def weapon_common_fix(data: dict): """ - 对长柄武器角色的通用面板属性修正 + 对武器的通用面板属性修正 :param data: 角色数据 :return: 角色数据 """ attr = data['属性'] weapon = data['武器'] - if weapon['名称'] == '护摩之杖': + # 针对q的额外属性 + extra_q = { + '暴击率': 0, + '增伤': 0 + } + # 针对e的额外属性 + extra_e = { + '暴击率': 0, + '增伤': 0, + '额外倍率': 0 + } + # 针对a的额外属性 + extra_a = { + '普攻暴击率': 0, + '普攻增伤': 0, + '普攻额外倍率': 0, + '重击暴击率': 0, + '重击增伤': 0, + '重击额外倍率': 0, + '下落攻击暴击率': 0, + '下落攻击增伤': 0, + '下落攻击额外倍率': 0 + } + # 单手剑 + if weapon['名称'] == '波乱月白经津': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.09 + 0.03 * weapon['精炼等级']) + extra_a['普攻增伤'] += 2 * (0.15 + 0.05 * weapon['精炼等级']) + data['伤害描述'].append('波乱满层') + elif weapon['名称'] == '辰砂之纺锤': + extra_e['额外倍率'] += (attr['基础防御'] + attr['额外防御']) * (0.3 + 0.1 * weapon['精炼等级']) + elif weapon['名称'] == '腐殖之剑': + extra_e['增伤'] += 0.12 + 0.04 * weapon['精炼等级'] + extra_e['暴击率'] += 0.045 + 0.015 * weapon['精炼等级'] + elif weapon['名称'] == '苍古自由之誓': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.075 + 0.025 * weapon['精炼等级']) + data['额外攻击'] += data['基础攻击'] * (0.15 + 0.05 * weapon['精炼等级']) + extra_a['普攻增伤'] += 0.12 + 0.04 * weapon['精炼等级'] + extra_a['重击增伤'] += 0.12 + 0.04 * weapon['精炼等级'] + extra_a['下落攻击增伤'] += 0.12 + 0.04 * weapon['精炼等级'] + data['伤害描述'].append('苍古触发') + elif weapon['名称'] == '雾切之回光': + # TODO 吃不满3层的角色 + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.3 + 0.1 * weapon['精炼等级']) + data['伤害描述'].append('雾切满层') + elif weapon['名称'] == '铁蜂刺': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + 2 * (0.045 + 0.015 * weapon['精炼等级']) + data['伤害描述'].append('铁蜂刺满层') + elif weapon['名称'] == '黑岩长剑': + attr['额外攻击'] += attr['基础攻击'] * (0.09 + 0.03 * weapon['精炼等级']) + data['伤害描述'].append('黑岩1层') + elif weapon['名称'] in ['暗巷闪光', '冷刃']: + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.09 + 0.03 * weapon['精炼等级']) + elif weapon['名称'] == '飞天大御剑': + attr['额外攻击'] += attr['基础攻击'] * (0.09 + 0.03 * weapon['精炼等级']) + elif weapon['名称'] == '黎明神剑': + attr['暴击率'] += 0.115 + 0.025 * weapon['精炼等级'] + elif weapon['名称'] == '暗铁剑': + attr['额外攻击'] += attr['基础攻击'] * (0.15 + 0.05 * weapon['精炼等级']) + elif weapon['名称'] == '黑剑': + extra_a['普攻增伤'] += 0.15 + 0.05 * weapon['精炼等级'] + extra_a['重击增伤'] += 0.15 + 0.05 * weapon['精炼等级'] + elif weapon['名称'] == '铁影阔剑': + extra_a['重击增伤'] += 0.25 + 0.05 * weapon['精炼等级'] + + # 双手剑 + elif weapon['名称'] == '赤角石溃杵': + extra_a['普攻额外倍率'] += (attr['基础防御'] + attr['额外防御']) * (0.3 + 0.1 * weapon['精炼等级']) + elif weapon['名称'] == '松籁响起之时': + attr['额外攻击'] += attr['基础攻击'] * (0.09 + 0.03 * weapon['精炼等级']) + data['伤害描述'].append('松籁触发') + elif weapon['名称'] == '狼的末路': + attr['额外攻击'] += attr['基础攻击'] * (0.3 + 0.1 * weapon['精炼等级']) + data['伤害描述'].append('狼末触发') + elif weapon['名称'] == '天空之傲': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.06 + 0.02 * weapon['精炼等级']) + elif weapon['名称'] == '钟剑': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.09 + 0.03 * weapon['精炼等级']) + data['伤害描述'].append('钟剑触发') + elif weapon['名称'] == '白影剑': + attr['额外攻击'] += attr['基础攻击'] * 4 * (0.045 + 0.015 * weapon['精炼等级']) + attr['额外防御'] += attr['基础防御'] * 4 * (0.045 + 0.015 * weapon['精炼等级']) + data['伤害描述'].append('白影剑满层') + elif weapon['名称'] == '螭骨剑': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + 5 * (0.05 + 0.01 * weapon['精炼等级']) + data['伤害描述'].append('螭骨满层') + elif weapon['名称'] in ['沐浴龙血的剑', '鸦羽弓', '魔导绪论']: + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.09 + 0.03 * weapon['精炼等级']) + elif weapon['名称'] == '飞天大御剑': + attr['额外攻击'] += attr['基础攻击'] * 4 * (0.05 + 0.01 * weapon['精炼等级']) + data['伤害描述'].append('白影剑满层') + elif weapon['名称'] == '衔珠海皇': + extra_q['增伤'] += 0.09 + 0.03 * weapon['精炼等级'] + elif weapon['名称'] == '桂木斩长正': + extra_e['增伤'] += 0.045 + 0.015 * weapon['精炼等级'] + # 弓 + elif weapon['名称'] == '落霞': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.115 + 0.025 * weapon['精炼等级']) + data['伤害描述'].append('落霞最高层') + elif weapon['名称'] == '若水': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.15 + 0.05 * weapon['精炼等级']) + elif weapon['名称'] == '终末嗟叹之诗': + attr['额外攻击'] += attr['基础攻击'] * (0.15 + 0.05 * weapon['精炼等级']) + attr['元素精通'] += 75 + 25 * weapon['精炼等级'] + data['伤害描述'].append('终末触发') + elif weapon['名称'] == '冬极白星': + attr['额外攻击'] += attr['基础攻击'] * (0.36 + 0.12 * weapon['精炼等级']) + extra_q['增伤'] += 0.09 + 0.03 * weapon['精炼等级'] + extra_e['增伤'] += 0.09 + 0.03 * weapon['精炼等级'] + data['伤害描述'].append('冬极满层') + elif weapon['名称'] == '试作澹月': + attr['额外攻击'] += attr['基础攻击'] * (0.27 + 0.09 * weapon['精炼等级']) + data['伤害描述'].append('试作触发') + elif weapon['名称'] == '钢轮弓': + attr['额外攻击'] += attr['基础攻击'] * 4 * (0.03 + 0.01 * weapon['精炼等级']) + data['伤害描述'].append('钢轮弓满层') + elif weapon['名称'] == '暗巷猎手': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + 5 * (0.015 + 0.005 * weapon['精炼等级']) + data['伤害描述'].append('暗巷猎手5层') + elif weapon['名称'] == '风花之颂': + attr['额外攻击'] += attr['基础攻击'] * (0.12 + 0.04 * weapon['精炼等级']) + data['伤害描述'].append('风花触发') + elif weapon['名称'] == '绝弦': + extra_q['增伤'] += 0.18 + 0.06 * weapon['精炼等级'] + extra_e['增伤'] += 0.18 + 0.06 * weapon['精炼等级'] + elif weapon['名称'] == '幽夜华尔兹': + extra_e['增伤'] += 0.15 + 0.05 * weapon['精炼等级'] + extra_a['普攻增伤'] += 0.15 + 0.05 * weapon['精炼等级'] + elif weapon['名称'] == '掠食者': + extra_a['普攻增伤'] += 0.1 + extra_a['重击增伤'] += 0.1 + elif weapon['名称'] == '飞雷之弦振': + extra_a['普攻增伤'] += 0.3 + 0.1 * weapon['精炼等级'] + data['伤害描述'].append('飞雷满层') + elif weapon['名称'] == '破魔之弓': + extra_a['普攻增伤'] += 0.24 + 0.08 * weapon['精炼等级'] + extra_a['重击增伤'] += 0.18 + 0.06 * weapon['精炼等级'] + data['伤害描述'].append('破魔满能量') + elif weapon['名称'] == '阿莫斯之弓': + extra_a['普攻增伤'] += 0.39 + 0.13 * weapon['精炼等级'] + extra_a['重击增伤'] += 0.39 + 0.13 * weapon['精炼等级'] + data['伤害描述'].append('阿莫斯满层') + elif weapon['名称'] == '弓藏': + extra_a['普攻增伤'] += 0.3 + 0.1 * weapon['精炼等级'] + extra_a['重击增伤'] -= 0.1 + elif weapon['名称'] == '弹弓': + extra_a['普攻增伤'] += 0.3 + 0.06 * weapon['精炼等级'] + extra_a['重击增伤'] += 0.3 + 0.06 * weapon['精炼等级'] + + # 长柄武器 + elif weapon['名称'] == '白缨枪': + extra_a['普攻增伤'] += 0.18 + 0.06 * weapon['精炼等级'] + elif weapon['名称'] == '护摩之杖': attr['额外攻击'] += (attr['基础生命'] + attr['额外生命']) * (0.008 + 0.002 * weapon['精炼等级']) if '半血以下' not in data['伤害描述']: data['伤害描述'].append('半血以下') @@ -88,10 +287,6 @@ def polearm_common_fix(data: dict): for i, k in enumerate(attr['伤害加成']): attr['伤害加成'][i] = k + (0.09 + 0.03 * weapon['精炼等级']) data['伤害描述'].append('和璞鸢满层') - elif weapon['名称'] == '贯虹之槊': - attr['额外攻击'] += attr['基础攻击'] * 2 * 5 * (0.003 + 0.001 * weapon['精炼等级']) - attr['护盾强效'] += 0.15 + 0.05 * weapon['精炼等级'] - data['伤害描述'].append('贯虹带盾满层') elif weapon['名称'] == '决斗之枪': attr['额外攻击'] += attr['基础攻击'] * 0.18 + 0.06 * weapon['精炼等级'] data['伤害描述'].append('决斗单怪') @@ -103,25 +298,75 @@ def polearm_common_fix(data: dict): elif weapon['名称'] == '薙草之稻光': attr['额外攻击'] += attr['基础攻击'] * (attr['元素充能效率'] - 1) * (0.21 + 0.07 * weapon['精炼等级']) attr['元素充能效率'] += 0.25 + 0.05 * weapon['精炼等级'] - elif weapon['名称'] == '天空之脊': - attr['暴击率'] += (0.06 + 0.02 * weapon['精炼等级']) - elif weapon['名称'] == '千岩长枪': + elif weapon['名称'] == '「渔获」': + extra_q['增伤'] += 0.12 + 0.04 * weapon['精炼等级'] + extra_q['暴击率'] += 0.045 + 0.015 * weapon['精炼等级'] + # 法器 + elif weapon['名称'] == '证誓之明瞳': + attr['元素充能效率'] += 0.18 + 0.06 * weapon['精炼等级'] + elif weapon['名称'] == '神乐之真意': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.09 + 0.03 * weapon['精炼等级']) + extra_e['增伤'] += 3 * (0.09 + 0.03 * weapon['精炼等级']) + data['伤害描述'].append('神乐满层') + elif weapon['名称'] == '白辰之环': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.075 + 0.025 * weapon['精炼等级']) + data['伤害描述'].append('白辰触发') + elif weapon['名称'] == '天空之卷': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.09 + 0.03 * weapon['精炼等级']) + elif weapon['名称'] == '四风原典': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + 4 * (0.06 + 0.02 * weapon['精炼等级']) + data['伤害描述'].append('四风满层') + elif weapon['名称'] == '流浪乐章': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + (0.36 + 0.12 * weapon['精炼等级']) + data['伤害描述'].append('流浪触发增伤') + elif weapon['名称'] == '万国诸海图谱': + for i, k in enumerate(attr['伤害加成']): + attr['伤害加成'][i] = k + 2 * (0.06 + 0.02 * weapon['精炼等级']) + data['伤害描述'].append('万国满层') + elif weapon['名称'] == '暗巷的酒与诗': + attr['额外攻击'] += attr['基础攻击'] * (0.15 + 0.05 * weapon['精炼等级']) + data['伤害描述'].append('暗巷触发') + elif weapon['名称'] == '嘟嘟可故事集': + attr['额外攻击'] += attr['基础攻击'] * (0.06 + 0.02 * weapon['精炼等级']) + extra_a['重击增伤'] += 0.12 + 0.04 * weapon['精炼等级'] + elif weapon['名称'] == '翡玉法球': + attr['额外攻击'] += attr['基础攻击'] * (0.15 + 0.05 * weapon['精炼等级']) + data['伤害描述'].append('翡玉触发') + elif weapon['名称'] == '匣里日月': + extra_q['增伤'] += 0.15 + 0.05 * weapon['精炼等级'] + extra_e['增伤'] += 0.15 + 0.05 * weapon['精炼等级'] + extra_a['普攻增伤'] += 0.15 + 0.05 * weapon['精炼等级'] + + # 系列武器 + elif weapon['名称'].startswith('千岩'): attr['暴击率'] += (0.02 + 0.01 * weapon['精炼等级']) attr['额外攻击'] += attr['基础攻击'] * (0.06 + 0.01 * weapon['精炼等级']) data['伤害描述'].append('璃月人1层') - elif weapon['名称'] == '匣里灭辰': + elif weapon['名称'] in ['匣里灭辰', '匣里龙吟', '雨裁']: for i, k in enumerate(attr['伤害加成']): attr['伤害加成'][i] = k + (0.16 + 0.04 * weapon['精炼等级']) - data['伤害描述'].append('灭辰触发') - elif weapon['名称'] == '黑岩刺枪': + data['伤害描述'].append(f'{weapon["名称"][:2]}触发') + elif weapon['名称'].startswith('黑岩'): attr['额外攻击'] += attr['基础攻击'] * (0.09 + 0.03 * weapon['精炼等级']) data['伤害描述'].append('黑岩1层') + elif weapon['名称'] in ['贯虹之槊', '斫峰之刃', '尘世之锁', '无工之剑']: + attr['额外攻击'] += attr['基础攻击'] * 2 * 5 * (0.003 + 0.001 * weapon['精炼等级']) + attr['护盾强效'] += 0.15 + 0.05 * weapon['精炼等级'] + data['伤害描述'].append('武器带盾满层') + elif weapon['名称'] in ['断浪长鳍', '恶王丸', '朦云之月']: + extra_q['增伤'] += (0.0009 + 0.0003 * weapon['精炼等级']) * 240 + data['伤害描述'].append('武器被动算240能量') data['属性'] = attr - return data + return data, extra_q, extra_e, extra_a -def attr_common_fix(data: dict): +def common_fix(data: dict): """ 对武器、圣遗物的通用面板属性修正 :param data: 角色数据 @@ -131,17 +376,26 @@ def attr_common_fix(data: dict): data['伤害描述'] = [] if '护盾强效' not in data['属性']: data['属性']['护盾强效'] = 0 - if data['武器']['类型'] == '长柄武器': - data = polearm_common_fix(data) + data, extra_q, extra_e, extra_a = weapon_common_fix(data) artifacts = data['圣遗物'] attr = data['属性'] + weapon = data['武器'] suit = get_artifact_suit(artifacts) # 两件套的情况 if '逆飞的流星' in suit: attr['护盾强效'] += 0.35 + if '昔日宗室之仪' in suit: + extra_q['增伤'] += 0.2 + if '赌徒' in suit: + extra_e['增伤'] += 0.2 + if '武人' in suit: + extra_a['普攻增伤'] += 0.15 + extra_a['重击增伤'] += 0.15 if len(suit) == 2: # 四件套的情况 if suit[0][0] == suit[1][0]: + if suit[0][0] == '绝缘之旗印': + extra_q['增伤'] += 0.25 * attr['元素充能效率'] if suit[0][0] == '苍白之火': attr['额外攻击'] += attr['基础攻击'] * 0.18 attr['伤害加成'][0] += 0.25 @@ -158,8 +412,8 @@ def attr_common_fix(data: dict): attr['额外攻击'] += attr['基础攻击'] * 0.2 data['伤害描述'].append('宗室触发') elif suit[0][0] == '冰风迷途的勇士': - attr['暴击率'] += 0.4 - data['伤害描述'].append('冰套暴击40%') + attr['暴击率'] += 0.2 + data['伤害描述'].append('冰套暴击20%') elif suit[0][0] == '勇士之心': for i, k in enumerate(attr['伤害加成']): attr['伤害加成'][i] = k + 0.3 @@ -191,108 +445,183 @@ def attr_common_fix(data: dict): data['伤害描述'].append('辰砂满层') elif suit[0][0] == '被怜爱的少女': attr['受治疗加成'] += 0.2 - data['属性'] = attr - return data - - -def q_fix(data: dict): - # 武器 - attr = data['属性'] - extra_value = { - '暴击率': 0, - '增伤': 0 - } - weapon = data['武器'] - if weapon['名称'] == '「渔获」': - extra_value['增伤'] += 0.12 + 0.04 * weapon['精炼等级'] - extra_value['暴击率'] += 0.045 + 0.015 * weapon['精炼等级'] - if weapon['名称'] == '断浪长鳍': - extra_value['增伤'] += (0.0009 + 0.0003 * weapon['精炼等级']) * 240 - data['伤害描述'].append('断浪算240能量') - - # 圣遗物 - artifacts = data['圣遗物'] - suit = get_artifact_suit(artifacts) - # 两件套的情况 - if '昔日宗室之仪' in suit: - extra_value['增伤'] += 0.2 - if len(suit) == 2: - # 四件套的情况 - if suit[0][0] == suit[1][0]: - if suit[0][0] == '绝缘之旗印': - extra_value['增伤'] += 0.25 * attr['元素充能效率'] - - return data, extra_value - - -def e_fix(data: dict): - # 武器 - attr = data['属性'] - extra_value = { - '暴击率': 0, - '增伤': 0 - } - # 圣遗物 - artifacts = data['圣遗物'] - suit = get_artifact_suit(artifacts) - # 两件套的情况 - if '赌徒' in suit: - extra_value['增伤'] += 0.2 - return data, extra_value - - -def a_fix(data: dict): - # 武器 - attr = data['属性'] - extra_value = { - '普攻暴击率': 0, - '普攻增伤': 0, - '重击暴击率': 0, - '重击增伤': 0, - '下落攻击暴击率': 0, - '下落攻击增伤': 0 - } - weapon = data['武器'] - if weapon['名称'] == '白缨枪': - extra_value['普攻增伤'] += 0.18 + 0.06 * weapon['精炼等级'] - - # 圣遗物 - artifacts = data['圣遗物'] - suit = get_artifact_suit(artifacts) - # # 两件套的情况 - if '武人' in suit: - extra_value['普攻增伤'] += 0.15 - extra_value['重击增伤'] += 0.15 - if len(suit) == 2: - # 四件套的情况 - if suit[0][0] == suit[1][0]: - if suit[0][0] == '追忆之注连': - extra_value['普攻增伤'] += 0.5 - extra_value['重击增伤'] += 0.5 - extra_value['下落攻击增伤'] += 0.5 + elif suit[0][0] == '追忆之注连': + extra_a['普攻增伤'] += 0.5 + extra_a['重击增伤'] += 0.5 + extra_a['下落攻击增伤'] += 0.5 data['伤害描述'].append('追忆触发') elif suit[0][0] == '流浪大地的乐团': if weapon['类型'] in ['法器', '弓箭']: - extra_value['重击增伤'] += 0.35 + extra_a['重击增伤'] += 0.35 elif suit[0][0] == '角斗士的终幕礼': if weapon['类型'] in ['单手剑', '双手剑', '长柄武器']: - extra_value['普攻增伤'] += 0.35 + extra_a['普攻增伤'] += 0.35 elif suit[0][0] == '染血的骑士道': - extra_value['重击增伤'] += 0.5 + extra_a['重击增伤'] += 0.5 data['伤害描述'].append('染血触发') elif suit[0][0] == '沉沦之心': - extra_value['普攻增伤'] += 0.3 - extra_value['重击增伤'] += 0.3 + extra_a['普攻增伤'] += 0.3 + extra_a['重击增伤'] += 0.3 data['伤害描述'].append('沉沦触发') elif suit[0][0] == '逆飞的流星': - extra_value['普攻增伤'] += 0.4 - extra_value['重击增伤'] += 0.4 + extra_a['普攻增伤'] += 0.4 + extra_a['重击增伤'] += 0.4 data['伤害描述'].append('流星触发') elif suit[0][0] == '武人': - extra_value['普攻增伤'] += 0.25 - extra_value['重击增伤'] += 0.25 + extra_a['普攻增伤'] += 0.25 + extra_a['重击增伤'] += 0.25 data['伤害描述'].append('武人触发') elif suit[0][0] == '行者之心': - extra_value['重击暴击率'] += 0.3 + extra_a['重击暴击率'] += 0.3 + data['属性'] = attr + return data, extra_q, extra_e, extra_a - return data, extra_value + +all_skill_data = load_json(path=Path(__file__).parent.parent.parent / 'utils' / 'json_data' / 'roles_data.json') + + +def get_damage_multipiler(data: dict) -> dict: + skill_data = all_skill_data[data['名称']]['skill'] + level_q = data['天赋'][2]['等级'] - 1 + level_e = data['天赋'][1]['等级'] - 1 + level_a = data['天赋'][0]['等级'] - 1 + if data['名称'] == '钟离': + return { + '玉璋护盾': (float(skill_data['元素战技·地心']['数值']['护盾附加吸收量'][level_e].replace('%最大生命值', '')) / 100.0, + int(skill_data['元素战技·地心']['数值']['护盾基础吸收量'][level_e].replace(',', ''))), + '原岩共鸣': float(skill_data['元素战技·地心']['数值']['岩脊伤害/共鸣伤害'][level_e].split('/')[1].replace('%', '')) / 100.0, + '天星': float(skill_data['元素爆发·天星']['数值']['技能伤害'][level_q].replace('%', '')) / 100.0, + '踢枪': float(skill_data['普通攻击·岩雨']['数值']['五段伤害'][level_a].replace('%×4', '')) / 100.0 + } + if data['名称'] == '胡桃': + return { + '攻击力提高': float(skill_data['蝶引来生']['数值']['攻击力提高'][level_e].replace('%生命值上限', '')) / 100.0, + '重击': float(skill_data['普通攻击·往生秘传枪法']['数值']['重击伤害'][level_a].replace('%', '')) / 100.0, + '雪梅香': float(skill_data['蝶引来生']['数值']['血梅香伤害'][level_e].replace('%', '')) / 100.0, + '大招': float(skill_data['安神秘法']['数值']['低血量时技能伤害'][level_q].replace('%', '')) / 100.0 + } + if data['名称'] == '雷电将军': + qa = skill_data['奥义·梦想真说']['数值']['重击伤害'][level_q].split('+') + return { + '协同攻击': float(skill_data['神变·恶曜开眼']['数值']['协同攻击伤害'][level_e].replace('%', '')) / 100.0, + 'e增伤': float( + skill_data['神变·恶曜开眼']['数值']['元素爆发伤害提高'][level_e].replace('每点元素能量', '').replace('%', '')) / 100.0 * 90, + '梦想一刀基础': float(skill_data['奥义·梦想真说']['数值']['梦想一刀基础伤害'][level_q].replace('%', '')) / 100.0, + '梦想一刀愿力': float( + skill_data['奥义·梦想真说']['数值']['愿力加成'][level_q].split('%/')[0].replace('每层', '')) / 100.0 * 60, + '梦想一心重击基础': (float(qa[0].replace('%', '')) / 100.0, float(qa[1].replace('%', '')) / 100.0), + '梦想一心愿力': float( + skill_data['奥义·梦想真说']['数值']['愿力加成'][level_q].split('%/')[1].replace('%攻击力', '')) / 100.0 * 60, + '梦想一心能量': float(skill_data['奥义·梦想真说']['数值']['梦想一心能量恢复'][level_q]) + } + if data['名称'] == '魈': + a = skill_data['普通攻击·卷积微尘']['数值']['低空/高空坠地冲击伤害'][level_a].split('/') + return { + 'AX:低空下落首戳': float(a[0].replace('%', '')) / 100, + 'AX:高空下落首戳': float(a[1].replace('%', '')) / 100, + 'E:风轮两立': float(skill_data['风轮两立']['数值']['技能伤害'][level_e].replace('%', '')) / 100.0, + 'B:靖妖傩舞': float(skill_data['靖妖傩舞']['数值']['普通攻击/重击/下落攻击伤害提升'][level_q].replace('%', '')) / 100 + } + if data['名称'] == '香菱': + return { + '锅巴喷火': float(skill_data['锅巴出击']['数值']['喷火伤害'][level_e].replace('%', '')) / 100.0, + '旋火轮': float(skill_data['旋火轮']['数值']['旋火轮伤害'][level_q].replace('%', '')) / 100.0 + } + if data['名称'] == '申鹤': + return { + '冰翎': float(skill_data['仰灵威召将役咒']['数值']['伤害值提升'][level_e].replace('%', '')) / 100.0, + '大招减抗': float(skill_data['神女遣灵真诀']['数值']['抗性降低'][level_q].replace('%', '')) / 100.0, + 'e长按': float(skill_data['仰灵威召将役咒']['数值']['长按技能伤害'][level_e].replace('%', '')) / 100.0, + '大招持续': float(skill_data['神女遣灵真诀']['数值']['持续伤害'][level_q].replace('%', '')) / 100.0 + } + if data['名称'] == '刻晴': + az = skill_data['普通攻击·云来剑法']['数值']['重击伤害'][level_a].split('+') + return { + 'AZ:重击': (float(az[0].replace('%', '')) / 100.0, float(az[1].replace('%', '')) / 100.0), + 'E:战技斩击': float(skill_data['星斗归位']['数值']['斩击伤害'][level_e].replace('%', '')) / 100.0, + 'Q:大招尾刀': float(skill_data['天街巡游']['数值']['最后一击伤害'][level_q].replace('%', '')) / 100.0 + } + if data['名称'] == '可莉': + return { + '重击': float(skill_data['普通攻击·砰砰']['数值']['重击伤害'][level_a].replace('%', '')) / 100.0, + '蹦蹦炸弹': float(skill_data['蹦蹦炸弹']['数值']['蹦蹦炸弹伤害'][level_q].replace('%', '')) / 100.0, + '轰轰火花': float(skill_data['轰轰火花']['数值']['轰轰火花伤害'][level_q].replace('%', '')) / 100.0, + } + if data['名称'] == '八重神子': + e = '杀生樱伤害·肆阶' if len(data['命座']) >= 2 else '杀生樱伤害·叁阶' + return { + '重击': float(skill_data['普通攻击·狐灵食罪式']['数值']['重击伤害'][level_a].replace('%', '')) / 100.0, + '杀生樱': float(skill_data['野干役咒·杀生樱']['数值'][e][level_e].replace('%', '')) / 100.0, + '天狐霆雷': float(skill_data['大密法·天狐显真']['数值']['天狐霆雷伤害'][level_q].replace('%', '')) / 100.0, + } + if data['名称'] == '阿贝多': + return { + '阳华绽放': float(skill_data['创生法·拟造阳华']['数值']['刹那之花伤害'][level_e].replace('%防御力', '')) / 100.0, + '大招首段': float(skill_data['诞生式·大地之潮']['数值']['爆发伤害'][level_q].replace('%', '')) / 100.0 + } + if data['名称'] == '神里绫华': + return { + '重击': float(skill_data['普通攻击·神里流·倾']['数值']['重击伤害'][level_a].replace('%*3', '')) / 100.0, + '冰华伤害': float(skill_data['神里流·冰华']['数值']['技能伤害'][level_e].replace('%', '')) / 100.0, + '霜灭每段': float(skill_data['神里流·霜灭']['数值']['切割伤害'][level_q].replace('%', '')) / 100.0, + } + if data['名称'] == '行秋': + e = skill_data['古华剑·画雨笼山']['数值']['技能伤害'][level_e].split('+') + return { + '画雨笼山': (float(e[0].replace('%', '')) / 100.0, float(e[1].replace('%', '')) / 100.0), + '裁雨留虹每段': float(skill_data['古华剑·裁雨留虹']['数值']['剑雨伤害'][level_e].replace('%', '')) / 100.0 + } + if data['名称'] == '夜兰': + return { + '破局矢': float(skill_data['普通攻击·潜形隐曜弓']['数值']['破局矢伤害'][level_a].replace('%生命值上限', '')) / 100.0, + '元素战技': float(skill_data['萦络纵命索']['数值']['技能伤害'][level_e].replace('%生命值上限', '')) / 100.0, + '大招每段': float(skill_data['渊图玲珑骰']['数值']['玄掷玲珑伤害'][level_q].replace('%生命值上限*3', '')) / 100.0, + } + if data['名称'] == '甘雨': + return { + '霜华矢': (float(skill_data['普通攻击·流天射术']['数值']['霜华矢命中伤害'][level_a].replace('%', '')) / 100.0, float(skill_data['普通攻击·流天射术']['数值']['霜华矢·霜华绽发伤害'][level_a].replace('%', '')) / 100.0), + '元素战技': float(skill_data['山泽麟迹']['数值']['技能伤害'][level_e].replace('%', '')) / 100.0, + '冰棱伤害': float(skill_data['降众天华']['数值']['冰棱伤害'][level_q].replace('%', '')) / 100.0, + } + + +def draw_dmg_pic(dmg: Dict[str, Union[tuple, list]]): + """ + 绘制伤害图片 + :param dmg: 伤害字典 + :return: 伤害图片 + """ + # 读取图片资源 + mask_top = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩top.png') + mask_body = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩body.png') + mask_bottom = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩bottom.png') + height = 60 * len(dmg) - 20 + # 创建画布 + bg = Image.new('RGBA', (948, height + 80), (0, 0, 0, 0)) + bg.alpha_composite(mask_top, (0, 0)) + bg.alpha_composite(mask_body.resize((948, height)), (0, 60)) + bg.alpha_composite(mask_bottom, (0, height + 60)) + bg_draw = ImageDraw.Draw(bg) + # 绘制顶栏 + bg_draw.line((250, 0, 250, 948), (255, 255, 255, 75), 2) + bg_draw.line((599, 0, 599, 60), (255, 255, 255, 75), 2) + bg_draw.line((0, 60, 948, 60), (255, 255, 255, 75), 2) + draw_center_text(bg_draw, '伤害计算', 0, 250, 11, 'white', get_font(30, text_font)) + draw_center_text(bg_draw, '期望伤害', 250, 599, 11, 'white', get_font(30, text_font)) + draw_center_text(bg_draw, '暴击伤害', 599, 948, 11, 'white', get_font(30, text_font)) + i = 1 + for describe, dmg_list in dmg.items(): + bg_draw.line((0, 60 * i, 948, 60 * i), (255, 255, 255, 75), 2) + draw_center_text(bg_draw, describe, 0, 250, 60 * i + 13, 'white', get_font(30, text_font)) + if len(dmg_list) == 1: + if describe == '额外说明': + draw_center_text(bg_draw, dmg_list[0], 250, 948, 60 * i + 13, 'white', get_font(30, text_font)) + else: + draw_center_text(bg_draw, dmg_list[0], 250, 948, 60 * i + 16, 'white', get_font(30, number_font)) + else: + bg_draw.line((599, 60 * i, 599, 60 * (i + 1)), (255, 255, 255, 75), 2) + draw_center_text(bg_draw, dmg_list[0], 250, 599, 60 * i + 16, 'white', get_font(30, number_font)) + draw_center_text(bg_draw, dmg_list[1], 599, 948, 60 * i + 16, 'white', get_font(30, number_font)) + i += 1 + + return bg diff --git a/Paimon_Info/damage_cal/damage.py b/Paimon_Info/damage_cal/damage.py index 6ae6bab..a53b02f 100644 --- a/Paimon_Info/damage_cal/damage.py +++ b/Paimon_Info/damage_cal/damage.py @@ -1,23 +1,198 @@ -from .zhongli import draw_zhongli_dmg -from .hutao import draw_hutao_dmg -from .leishen import draw_leishen_dmg -from .xiao import draw_xiao_dmg -from .xiangling import draw_xiangling_dmg -from .shenhe import draw_shenhe_dmg +from copy import deepcopy +from pathlib import Path -# 支持的角色列表 -roles_list = { - '钟离': draw_zhongli_dmg, - '胡桃': draw_hutao_dmg, - '雷电将军': draw_leishen_dmg, - '魈': draw_xiao_dmg, - '香菱': draw_xiangling_dmg, - '申鹤': draw_shenhe_dmg -} +from littlepaimon_utils.files import load_json +from .common import common_fix, draw_dmg_pic, udc, get_damage_multipiler, growth_reaction -def get_role_dmg(role_name: str, data: dict): - if role_name in roles_list: - return roles_list[role_name](data) - else: +all_skill_data = load_json(path=Path(__file__).parent.parent.parent / 'utils' / 'json_data' / 'roles_data.json') + + +def get_role_dmg(data: dict): + dm = get_damage_multipiler(data) + if not dm: return None + dmg_data = {} + data, vq, ve, va = common_fix(deepcopy(data)) + level_role = data['等级'] + attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] + health = data['属性']['基础生命'] + data['属性']['额外生命'] + defense = data['属性']['基础防御'] + data['属性']['额外防御'] + cr = data['属性']['暴击率'] + cd = data['属性']['暴击伤害'] + db = data['属性']['伤害加成'] + cons = len(data['命座']) + # 物理, 火, 雷, 水, 草, 风, 岩, 冰 + if data['名称'] == '钟离': + data['伤害描述'].insert(0, '护盾减抗') + dmg_data['玉璋护盾'] = (str(int((health * dm['玉璋护盾'][0] + dm['玉璋护盾'][1]) * (1 + data['属性']['护盾强效']))),) + dmg_data['原岩共鸣'] = udc(dm['原岩共鸣'] * attack + (health * 0.019) if level_role >= 70 else 0, (cr + ve['暴击率'], cd), + db[6] + ve['增伤'], level_role, rcd=0.2) + dmg_data['天星伤害'] = udc(dm['天星'] * attack + (health * 0.33) if level_role >= 70 else 0, (cr + vq['暴击率'], cd), + db[6] + vq['增伤'], level_role, rcd=0.2) + a = udc(dm['踢枪'] * attack + (health * 0.0139) if level_role >= 70 else 0, (cr + va['普攻暴击率'], cd), + db[0] + va['普攻增伤'], level_role, rcd=0.2) + if data['武器']['名称'] == '流月针': + ly = udc((0.15 + 0.05 * data['武器']['精炼等级']) * attack, (cr, cd), db[0], level_role, rcd=0.2) + a[0] += '+' + ly[0] + a[1] += '+' + ly[1] + dmg_data['踢枪伤害'] = a + elif data['名称'] == '雷电将军': + data['伤害描述'].insert(0, '满愿力') + vq['增伤'] += dm['e增伤'] + dci = 0.6 if cons >= 2 else 0 + dmg_data['协同攻击'] = udc(dm['协同攻击'] * attack, (cr + ve['暴击率'], cd), db[2] + ve['增伤'], level_role, dci=dci) + dmg_data['梦想一刀'] = udc((dm['梦想一刀基础'] + dm['梦想一刀愿力']) * attack, (cr + vq['暴击率'], cd), db[2] + vq['增伤'], + level_role, dci=dci) + a1 = udc((dm['梦想一心重击基础'][0] + dm['梦想一心愿力']) * attack, (cr + vq['暴击率'], cd), db[2] + vq['增伤'], level_role, + dci=dci) + a2 = udc((dm['梦想一心重击基础'][1] + dm['梦想一心愿力']) * attack, (cr + vq['暴击率'], cd), db[2] + vq['增伤'], level_role, + dci=dci) + dmg_data['梦想一心重击'] = (a1[0] + '+' + a2[0], a1[1] + '+' + a2[1]) + extra_energy = (data['属性']['元素充能效率'] - 1) * 0.6 if level_role >= 70 else 0 + dmg_data['梦想一心能量'] = (str(round(dm['梦想一心能量'] * (1 + extra_energy) * 5, 1)),) + elif data['名称'] == '胡桃': + data['伤害描述'].insert(0, '半血以下') + zf = growth_reaction(data['属性']['元素精通'], 1.5) if '蒸发系数' not in data['属性'] else growth_reaction( + data['属性']['元素精通'], 1.5, data['属性']['蒸发系数']) + attack += dm['攻击力提高'] * health + db[1] += 0.33 if level_role >= 70 else 0 + dmg_data['裸重击'] = udc(dm['重击'] * attack, (cr + va['重击暴击率'], cd), db[1] + va['重击增伤'], level_role) + dmg_data['重击蒸发'] = udc(dm['重击'] * attack, (cr + va['重击暴击率'], cd), db[1] + va['重击增伤'], level_role, r=zf) + dmg_data['雪梅香蒸发'] = udc(dm['雪梅香'] * attack + ((health * 0.1) if cons >= 2 else 0), (cr + ve['暴击率'], cd), + db[1] + ve['增伤'], level_role, r=zf) + dmg_data['大招蒸发'] = udc(dm['大招'] * attack, (cr + vq['暴击率'], cd), + db[1] + vq['增伤'], level_role, r=zf) + elif data['名称'] == '香菱': + zf = growth_reaction(data['属性']['元素精通'], 1.5) if '蒸发系数' not in data['属性'] else growth_reaction( + data['属性']['元素精通'], 1.5, data['属性']['蒸发系数']) + rcd = 0.15 if cons >= 1 else 0 + dmg_data['锅巴喷火'] = udc(dm['锅巴喷火'] * attack, (cr + ve['暴击率'], cd), db[1] + ve['增伤'], level_role, rcd=rcd) + dmg_data['旋火轮'] = udc(dm['旋火轮'] * attack, (cr + vq['暴击率'], cd), db[1] + vq['增伤'], level_role, rcd=rcd) + dmg_data['旋火轮蒸发'] = udc(dm['旋火轮'] * attack, (cr + vq['暴击率'], cd), db[1] + vq['增伤'], level_role, rcd=rcd, r=zf) + elif data['名称'] == '魈': + va['下落攻击增伤'] += dm['靖妖傩舞'] + dmg_data = get_dmg_data(dm, attack, cr, cd, db[5], level_role, va, ve, vq) + elif data['名称'] == '申鹤': + dmg_data['冰翎加成'] = str(int(dm['冰翎'] * attack)) + db[-1] += 0.15 if level_role >= 40 else 0 + vq['增伤'] += 0.15 if level_role >= 70 else 0 + dmg_data['战技长按'] = udc(dm['e长按'] * attack, (cr + ve['暴击率'], cd), db[-1] + ve['增伤'], level_role, rcd=dm['大招减抗']) + dmg_data['大招持续伤害'] = udc(dm['大招持续'] * attack, (cr + vq['暴击率'], cd), db[-1] + vq['增伤'], level_role, + rcd=dm['大招减抗']) + elif data['名称'] == '八重神子': + ve['增伤'] += (data['属性']['元素精通'] * 0.0015) if level_role >= 70 else 0 + db[2] += 0.2 if cons >= 4 else 0 + dci = 0.6 if cons >= 6 else 0 + dmg_data['重击'] = udc(dm['重击'] * attack, (cr + va['重击暴击率'], cd), db[2] + va['重击增伤'], level_role) + dmg_data['杀生樱满阶'] = udc(dm['杀生樱'] * attack, (cr + ve['暴击率'], cd), db[2] + ve['增伤'], level_role, dci=dci) + dmg_data['天狐霆雷'] = udc(dm['天狐霆雷'] * attack, (cr + vq['暴击率'], cd), db[2] + vq['增伤'], level_role) + elif data['名称'] == '刻晴': + cr += 0.15 if level_role >= 70 else 0 + if cons == 6: + db[2] += 0.24 + data['伤害描述'].insert(0, '六命满层') + if cons >= 4: + attack += data['属性']['基础攻击'] * 0.25 + data['伤害描述'].insert(0, '四命触发') + dmg_data = get_dmg_data(dm, attack, cr, cd, db[2], level_role, va, ve, vq) + elif data['名称'] == '阿贝多': + dmg_data['阳华绽放'] = udc(dm['阳华绽放'] * defense + ve['额外倍率'], (cr + ve['暴击率'], cd), db[6] + ve['增伤'], level_role) + dmg_data['大招首段'] = udc(dm['大招首段'] * attack, (cr + vq['暴击率'], cd), db[6] + vq['增伤'], level_role) + elif data['名称'] == '神里绫华': + va['重击增伤'] += 0.3 if level_role >= 40 else 0 + db[-1] += 0.18 if level_role >= 70 else 0 + dcr = 0.3 if cons >= 4 else 0 + if cons == 6: + data['伤害描述'].insert(0, '满命触发') + va['重击增伤'] += 2.98 + a = udc(dm['重击'] * attack + va['重击额外倍率'], (cr + va['重击暴击率'], cd), db[-1] + va['重击增伤'], level_role, dcr=dcr) + dmg_data['重击'] = (a[0] + '*3', a[1] + '*3') + dmg_data['冰华伤害'] = udc(dm['冰华伤害'] * attack + ve['额外倍率'], (cr + ve['暴击率'], cd), db[-1] + ve['增伤'], level_role, dcr=dcr) + dmg_data['霜灭每段'] = udc(dm['霜灭每段'] * attack, (cr + vq['暴击率'], cd), db[-1] + vq['增伤'], level_role, dcr=dcr) + elif data['名称'] == '行秋': + db[3] += 0.2 if level_role >= 70 else 0 + rcd = 0.15 if cons >= 2 else 0 + dme1 = dm['画雨笼山'][0] * (1.5 if cons >= 4 else 1) + dme2 = dm['画雨笼山'][1] * (1.5 if cons >= 4 else 1) + e1 = udc(dme1 * attack + ve['额外倍率'], (cr + ve['暴击率'], cd), db[3] + ve['增伤'], level_role, rcd=rcd) + e2 = udc(dme2 * attack + ve['额外倍率'], (cr + ve['暴击率'], cd), db[3] + ve['增伤'], level_role, rcd=rcd) + dmg_data['画雨笼山'] = (e1[0] + '+' + e2[0], e1[1] + '+' + e2[1]) + dmg_data['裁雨留虹每段'] = udc(dm['裁雨留虹每段'] * attack, (cr + vq['暴击率'], cd), db[3] + vq['增伤'], level_role, rcd=rcd) + elif data['名称'] == '夜兰': + data['伤害描述'].insert(0, '不计算天赋增伤') + if level_role >= 40: + health += data['属性']['基础生命'] * 0.18 + data['伤害描述'].insert(0, '天赋按3元素') + dmg_data['破局矢'] = udc(dm['破局矢'] * health, (cr + va['重击暴击率'], cd), db[3] + va['重击增伤'], level_role) + dmg_data['元素战技'] = udc(dm['元素战技'] * health, (cr + ve['暴击率'], cd), db[3] + ve['增伤'], level_role) + q = udc(dm['大招每段'] * health, (cr + vq['暴击率'], cd), db[3] + vq['增伤'], level_role) + if cons >= 2: + q2 = udc(0.14 * health, (cr + vq['暴击率'], cd), db[3] + vq['增伤'], level_role) + dmg_data['大招每段'] = (q[0] + '*3+' + q2[0], q[1] + '*3+' + q2[1]) + else: + dmg_data['大招每段'] = (q[0] + '*3', q[1] + '*3') + elif data['名称'] == '甘雨': + rh = growth_reaction(data['属性']['元素精通'], 1.5) if '融化系数' not in data['属性'] else growth_reaction( + data['属性']['元素精通'], 1.5, data['属性']['融化系数']) + va['重击暴击率'] += 0.2 if level_role >= 40 else 0 + if level_role >= 70: + va['重击增伤'] += 0.2 + ve['增伤'] += 0.2 + if cons >= 4: + db[-1] += 0.25 + data['伤害描述'].insert(0, '四命满层') + rcd = 0.15 if cons >= 1 else 0 + a1 = udc(dm['霜华矢'][0] * attack, (cr + va['重击暴击率'], cd), db[-1] + va['重击增伤'], level_role, rcd=rcd) + a2 = udc(dm['霜华矢'][1] * attack, (cr + va['重击暴击率'], cd), db[-1] + va['重击增伤'], level_role, rcd=rcd) + dmg_data['霜华矢'] = (a1[0] + '+' + a2[0], a1[1] + '+' + a2[1]) + a1 = udc(dm['霜华矢'][0] * attack, (cr + va['重击暴击率'], cd), db[-1] + va['重击增伤'], level_role, rcd=rcd, r=rh) + a2 = udc(dm['霜华矢'][1] * attack, (cr + va['重击暴击率'], cd), db[-1] + va['重击增伤'], level_role, rcd=rcd, r=rh) + dmg_data['霜华矢融化'] = (a1[0] + '+' + a2[0], a1[1] + '+' + a2[1]) + dmg_data['元素战技'] = udc(dm['元素战技'] * attack, (cr + ve['暴击率'], cd), db[-1] + ve['增伤'], level_role, rcd=rcd) + dmg_data['冰棱伤害'] = udc(dm['冰棱伤害'] * attack, (cr + vq['暴击率'], cd), db[-1] + vq['增伤'], level_role, rcd=rcd) + if data['伤害描述']: + dmg_data['额外说明'] = (','.join(data['伤害描述']),) + return draw_dmg_pic(dmg_data) if dmg_data else None + + +def get_dmg_data(dm, attack, cr, cd, db, level_role, va, ve, vq): + dmg_data = {} + v = {'A': { + '暴击率': va['普攻暴击率'], + '增伤': va['普攻增伤'], + '额外倍率': va['普攻额外倍率'] + }, + 'AZ': { + '暴击率': va['重击暴击率'], + '增伤': va['重击增伤'], + '额外倍率': va['重击额外倍率'] + }, + 'AX': { + '暴击率': va['下落攻击暴击率'], + '增伤': va['下落攻击增伤'], + '额外倍率': va['下落攻击额外倍率'] + }, + 'E': { + '暴击率': ve['暴击率'], + '增伤': ve['增伤'], + '额外倍率': ve['额外倍率'] + }, + 'Q': { + '暴击率': vq['暴击率'], + '增伤': vq['增伤'], + '额外倍率': 0 + }, + } + for name, num in dm.items(): + skill_name = name.split(':')[1] + skill_type = name.split(':')[0] + if skill_type == 'B': + continue + if isinstance(num, tuple): + n1 = udc(num[0] * attack + v[skill_type]['额外倍率'], (cr + v[skill_type]['暴击率'], cd), db + v[skill_type]['增伤'], level_role) + n2 = udc(num[1] * attack + v[skill_type]['额外倍率'], (cr + v[skill_type]['暴击率'], cd), db + v[skill_type]['增伤'], level_role) + dmg_data[skill_name] = (n1[0] + '+' + n2[0], n1[1] + '+' + n2[1]) + else: + dmg_data[skill_name] = udc(num * attack + v[skill_type]['额外倍率'], (cr + v[skill_type]['暴击率'], cd), db + v[skill_type]['增伤'], level_role) + return dmg_data diff --git a/Paimon_Info/damage_cal/hutao.py b/Paimon_Info/damage_cal/hutao.py deleted file mode 100644 index 67ffedd..0000000 --- a/Paimon_Info/damage_cal/hutao.py +++ /dev/null @@ -1,148 +0,0 @@ -from copy import deepcopy -from pathlib import Path -from typing import Tuple - -from PIL import Image, ImageDraw -from littlepaimon_utils.files import load_json, load_image -from littlepaimon_utils.images import get_font, draw_center_text - -from .common import resistance_coefficient as rc, defense_coefficient as dc, attr_common_fix, q_fix, e_fix, a_fix, \ - growth_reaction, text_font, number_font - -skill_data = load_json(path=Path(__file__).parent.parent.parent / 'utils' / 'json_data' / 'roles_data.json')['胡桃']['skill'] - - -def cal_e_attack(data: dict): - """ - 计算胡桃开E后的攻击力和半血后的增伤 - :param data: 角色数据 - :return: 角色数据 - """ - health = data['属性']['基础生命'] + data['属性']['额外生命'] - skill_level = data['天赋'][1]['等级'] - 1 - percent_value = float(skill_data['蝶引来生']['数值']['攻击力提高'][skill_level].replace('%生命值上限', '')) / 100.0 - data['属性']['额外攻击'] += health * percent_value - if data['等级'] >= 70: - data['属性']['伤害加成'][1] += 0.33 - return data - - -def cal_single_attack_dmg(data: dict, extra: dict) -> Tuple[float, float]: - """ - 计算胡桃裸重击的伤害 - :param data: 角色数据 - :param extra: 针对重击的额外数值 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][0]['等级'] - 1 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['重击暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][1] + extra['重击增伤'] - percent_value = float(skill_data['普通攻击·往生秘传枪法']['数值']['重击伤害'][skill_level].replace('%', '')) / 100.0 - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc() * dc(role_level) - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def cal_e_dmg(data: dict, extra: dict) -> Tuple[float, float]: - """ - 计算胡桃裸雪梅香的伤害 - :param data: 角色数据 - :param extra: 针对元素战技的额外数值 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][1]['等级'] - 1 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][1] + extra['增伤'] - hp_dmg = 0.1 * (data['属性']['基础生命'] + data['属性']['额外生命']) if len(data['命座']) >= 2 else 0 - - percent_value = float(skill_data['蝶引来生']['数值']['血梅香伤害'][skill_level].replace('%', '')) / 100.0 - damage = (attack * percent_value + hp_dmg) * (1 + cr * cd) * dmg_bonus * rc() * dc(role_level) - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def cal_q_dmg(data: dict, extra: dict) -> Tuple[float, float]: - """ - 计算胡桃裸大招的伤害 - :param data: 角色数据 - :param extra: 针对大招的额外数值 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][2]['等级'] - 1 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][1] + extra['增伤'] - percent_value = float(skill_data['安神秘法']['数值']['低血量时技能伤害'][skill_level].replace('%', '')) / 100.0 - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc() * dc(role_level) - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def draw_hutao_dmg(data: dict): - mask_top = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩top.png') - mask_body = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩body.png') - mask_bottom = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩bottom.png') - - data = deepcopy(data) - height = 5 * 60 - 20 - data['伤害描述'] = ['半血以下'] - data = attr_common_fix(data) - data = cal_e_attack(data) - data, q_value = q_fix(data) - data, e_value = e_fix(data) - data, a_value = a_fix(data) - # 蒸发系数 - if '蒸发系数' in data['属性']: - zf = growth_reaction(data['属性']['元素精通'], 1.5, 0.15) - else: - zf = growth_reaction(data['属性']['元素精通'], 1.5) - bg = Image.new('RGBA', (948, height + 80), (0, 0, 0, 0)) - bg.alpha_composite(mask_top, (0, 0)) - bg.alpha_composite(mask_body.resize((948, height)), (0, 60)) - bg.alpha_composite(mask_bottom, (0, height + 60)) - bg_draw = ImageDraw.Draw(bg) - # 画线 - bg_draw.line((250, 0, 250, 948), (255, 255, 255, 75), 2) - bg_draw.line((599, 0, 599, 300), (255, 255, 255, 75), 2) - bg_draw.line((0, 60, 948, 60), (255, 255, 255, 75), 2) - bg_draw.line((0, 120, 948, 120), (255, 255, 255, 75), 2) - bg_draw.line((0, 180, 948, 180), (255, 255, 255, 75), 2) - bg_draw.line((0, 240, 948, 240), (255, 255, 255, 75), 2) - bg_draw.line((0, 300, 948, 300), (255, 255, 255, 75), 2) - # 顶栏 - draw_center_text(bg_draw, '伤害计算', 0, 250, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '期望伤害', 250, 599, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '暴击伤害', 599, 948, 11, 'white', get_font(30, text_font)) - - # 裸重击 - draw_center_text(bg_draw, '裸重击', 0, 250, 73, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_single_attack_dmg(data, a_value) - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 76, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 76, 'white', get_font(30, number_font)) - - # 重击蒸发 - draw_center_text(bg_draw, '重击蒸发', 0, 250, 133, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, str(int(expect_dmg * zf)), 250, 599, 136, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg * zf)), 599, 948, 136, 'white', get_font(30, number_font)) - - # 大招蒸发 - draw_center_text(bg_draw, '大招蒸发', 0, 250, 193, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_q_dmg(data, q_value) - draw_center_text(bg_draw, str(int(expect_dmg * zf)), 250, 599, 196, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg * zf)), 599, 948, 196, 'white', get_font(30, number_font)) - - # 雪梅香蒸发 - draw_center_text(bg_draw, '雪梅香蒸发', 0, 250, 253, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_e_dmg(data, e_value) - draw_center_text(bg_draw, str(int(expect_dmg * zf)), 250, 599, 256, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg * zf)), 599, 948, 256, 'white', get_font(30, number_font)) - - # 额外说明 - draw_center_text(bg_draw, '额外说明', 0, 250, 313, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, ','.join(data['伤害描述']), 250, 948, 313, 'white', get_font(30, text_font)) - return bg diff --git a/Paimon_Info/damage_cal/leishen.py b/Paimon_Info/damage_cal/leishen.py deleted file mode 100644 index e6172de..0000000 --- a/Paimon_Info/damage_cal/leishen.py +++ /dev/null @@ -1,168 +0,0 @@ -from copy import deepcopy -from pathlib import Path -from typing import Tuple - -from PIL import Image, ImageDraw -from littlepaimon_utils.files import load_json, load_image -from littlepaimon_utils.images import get_font, draw_center_text - -from .common import resistance_coefficient as rc, defense_coefficient as dc, attr_common_fix, q_fix, e_fix, a_fix, \ - text_font, number_font - -skill_data = load_json(path=Path(__file__).parent.parent.parent / 'utils' / 'json_data' / 'roles_data.json')['雷电将军']['skill'] - - -def cal_e_dmg(data: dict, extra: dict) -> Tuple[float, float]: - """ - 计算雷神单次E的伤害 - :param data: 角色数据 - :param extra: 针对元素战技的额外数值 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][1]['等级'] - 1 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - if len(data['命座']) < 2: - defense = dc(role_level) - else: - defense = dc(role_level, ignore=0.6) - dmg_bonus = 1 + data['属性']['伤害加成'][2] + extra['增伤'] - percent_value = float(skill_data['神变·恶曜开眼']['数值']['协同攻击伤害'][skill_level].replace('%', '')) / 100.0 - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc() * defense - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def cal_q_dmg(data: dict, extra: dict, num: int) -> Tuple[float, float]: - """ - 计算雷神梦想一刀的伤害 - :param data: 角色数据 - :param extra: 针对大招的额外数值 - :param num: 愿力层数 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][2]['等级'] - 1 - e_skill_level = data['天赋'][1]['等级'] - 1 - e_bonus = float( - skill_data['神变·恶曜开眼']['数值']['元素爆发伤害提高'][e_skill_level].replace('每点元素能量', '').replace('%', '')) / 100.0 * 90 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - if len(data['命座']) < 2: - defense = dc(role_level) - else: - defense = dc(role_level, ignore=0.6) - dmg_bonus = 1 + data['属性']['伤害加成'][2] + extra['增伤'] + e_bonus - percent_value = float(skill_data['奥义·梦想真说']['数值']['梦想一刀基础伤害'][skill_level].replace('%', '')) / 100.0 - num_value = float(skill_data['奥义·梦想真说']['数值']['愿力加成'][skill_level].split('%/')[0].replace('每层', '')) / 100.0 * num - damage = (attack * (percent_value + num_value)) * (1 + cr * cd) * dmg_bonus * rc() * defense - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def cal_q_a_dmg(data: dict, extra: dict, num: int) -> Tuple[Tuple[float, float], Tuple[float, float]]: - """ - 计算雷神梦想一心重击的伤害 - :param data: 角色数据 - :param extra: 针对大招的额外数值 - :param num: 愿力层数 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][2]['等级'] - 1 - e_skill_level = data['天赋'][1]['等级'] - 1 - e_bonus = float( - skill_data['神变·恶曜开眼']['数值']['元素爆发伤害提高'][e_skill_level].replace('每点元素能量', '').replace('%', '')) / 100.0 * 90 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - if len(data['命座']) < 2: - defense = dc(role_level) - else: - defense = dc(role_level, ignore=0.6) - dmg_bonus = 1 + data['属性']['伤害加成'][2] + extra['增伤'] + e_bonus - percent_value = skill_data['奥义·梦想真说']['数值']['重击伤害'][skill_level].split('+') - percent_value1 = float(percent_value[0].replace('%', '')) / 100.0 - percent_value2 = float(percent_value[1].replace('%', '')) / 100.0 - num_value = float(skill_data['奥义·梦想真说']['数值']['愿力加成'][skill_level].split('%/')[1].replace('%攻击力', '')) / 100.0 * num - damage1 = (attack * (percent_value1 + num_value)) * (1 + cr * cd) * dmg_bonus * rc() * defense - damage2 = (attack * (percent_value2 + num_value)) * (1 + cr * cd) * dmg_bonus * rc() * defense - return (damage1, damage1 / (1 + cr * cd) * (1 + cd)), (damage2, damage2 / (1 + cr * cd) * (1 + cd)) - - -def cal_q_energy(data: dict) -> float: - """ - 计算雷神大招的能量回复 - :param data: 角色数据 - :return: 能量回复 - """ - role_level = data['等级'] - if role_level >= 70: - extra_energy = (data['属性']['元素充能效率'] - 1) * 0.6 - else: - extra_energy = 0 - skill_level = data['天赋'][2]['等级'] - 1 - energy = float(skill_data['奥义·梦想真说']['数值']['梦想一心能量恢复'][skill_level]) * (1 + extra_energy) * 5 - return energy - - -def draw_leishen_dmg(data: dict): - mask_top = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩top.png') - mask_body = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩body.png') - mask_bottom = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩bottom.png') - - data = deepcopy(data) - height = 5 * 60 - 20 - data['伤害描述'] = ['满愿力'] - data = attr_common_fix(data) - data, q_value = q_fix(data) - data, e_value = e_fix(data) - data, a_value = a_fix(data) - bg = Image.new('RGBA', (948, height + 80), (0, 0, 0, 0)) - bg.alpha_composite(mask_top, (0, 0)) - bg.alpha_composite(mask_body.resize((948, height)), (0, 60)) - bg.alpha_composite(mask_bottom, (0, height + 60)) - bg_draw = ImageDraw.Draw(bg) - # 画线 - bg_draw.line((250, 0, 250, 948), (255, 255, 255, 75), 2) - bg_draw.line((599, 0, 599, 240), (255, 255, 255, 75), 2) - bg_draw.line((0, 60, 948, 60), (255, 255, 255, 75), 2) - bg_draw.line((0, 120, 948, 120), (255, 255, 255, 75), 2) - bg_draw.line((0, 180, 948, 180), (255, 255, 255, 75), 2) - bg_draw.line((0, 240, 948, 240), (255, 255, 255, 75), 2) - bg_draw.line((0, 300, 948, 300), (255, 255, 255, 75), 2) - # 顶栏 - draw_center_text(bg_draw, '伤害计算', 0, 250, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '期望伤害', 250, 599, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '暴击伤害', 599, 948, 11, 'white', get_font(30, text_font)) - - # 协同攻击 - draw_center_text(bg_draw, '协同攻击', 0, 250, 73, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_e_dmg(data, e_value) - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 76, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 76, 'white', get_font(30, number_font)) - - # 梦想一刀 - draw_center_text(bg_draw, '梦想一刀', 0, 250, 133, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_q_dmg(data, q_value, 60) - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 136, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 136, 'white', get_font(30, number_font)) - - # 梦想一心重击 - draw_center_text(bg_draw, '梦想一心重击', 0, 250, 193, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_q_a_dmg(data, q_value, 60) - draw_center_text(bg_draw, f'{int(expect_dmg[0])}+{int(expect_dmg[1])}', 250, 599, 196, 'white', - get_font(30, number_font)) - draw_center_text(bg_draw, f'{int(crit_dmg[0])}+{int(crit_dmg[1])}', 599, 948, 196, 'white', - get_font(30, number_font)) - - # 梦想一心能量回复 - draw_center_text(bg_draw, '梦想一心能量', 0, 250, 253, 'white', get_font(30, text_font)) - energy = cal_q_energy(data) - draw_center_text(bg_draw, str(round(energy, 1)), 250, 948, 256, 'white', get_font(30, number_font)) - - # 额外说明 - draw_center_text(bg_draw, '额外说明', 0, 250, 313, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, ','.join(data['伤害描述']), 250, 948, 313, 'white', get_font(30, text_font)) - return bg diff --git a/Paimon_Info/damage_cal/shenhe.py b/Paimon_Info/damage_cal/shenhe.py deleted file mode 100644 index 18dd6e1..0000000 --- a/Paimon_Info/damage_cal/shenhe.py +++ /dev/null @@ -1,122 +0,0 @@ -from copy import deepcopy -from pathlib import Path -from typing import Tuple - -from PIL import Image, ImageDraw -from littlepaimon_utils.files import load_json, load_image -from littlepaimon_utils.images import get_font, draw_center_text - -from .common import resistance_coefficient as rc, defense_coefficient as dc, attr_common_fix, q_fix, e_fix, a_fix, \ - growth_reaction, text_font, number_font - -skill_data = load_json(path=Path(__file__).parent.parent.parent / 'utils' / 'json_data' / 'roles_data.json')['申鹤'][ - 'skill'] - - -def cal_e_value(data: dict) -> float: - """ - 计算申鹤e提供的加成 - :param data: 角色数据 - :return: 角色数据 - """ - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - skill_level = data['天赋'][1]['等级'] - 1 - percent_value = float(skill_data['仰灵威召将役咒']['数值']['伤害值提升'][skill_level].replace('%', '')) / 100.0 - - return percent_value * attack - - -def cal_e_dmg(data: dict, extra: dict) -> Tuple[float, float]: - """ - 计算申鹤e技能 - :param data: 角色数据 - :param extra: 针对元素战技的额外数值 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][1]['等级'] - 1 - q_skill_level = data['天赋'][2]['等级'] - 1 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][1] + extra['增伤'] - dmg_bonus += 0.15 if role_level >= 40 else 0 - percent_value_q = float(skill_data['神女遣灵真诀']['数值']['抗性降低'][q_skill_level].replace('%', '')) / 100.0 - - percent_value = float(skill_data['仰灵威召将役咒']['数值']['长按技能伤害'][skill_level].replace('%', '')) / 100.0 - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc(0.1, percent_value_q) * dc(role_level) - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def cal_q_dmg(data: dict, extra: dict) -> Tuple[float, float]: - """ - 计算申鹤q的伤害 - :param data: 角色数据 - :param extra: 针对大招的额外数值 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][2]['等级'] - 1 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][1] + extra['增伤'] - dmg_bonus += 0.15 if role_level >= 40 else 0 - dmg_bonus += 0.15 if role_level >= 70 else 0 - percent_value = float(skill_data['神女遣灵真诀']['数值']['持续伤害'][skill_level].replace('%', '')) / 100.0 - percent_value_rc = float(skill_data['神女遣灵真诀']['数值']['抗性降低'][skill_level].replace('%', '')) / 100.0 - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc(0.1, percent_value_rc) * dc(role_level) - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def draw_shenhe_dmg(data: dict): - mask_top = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩top.png') - mask_body = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩body.png') - mask_bottom = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩bottom.png') - - data = deepcopy(data) - height = 3 * 60 - 20 - data['伤害描述'] = [] - data = attr_common_fix(data) - data, q_value = q_fix(data) - data, e_value = e_fix(data) - data, a_value = a_fix(data) - if data['伤害描述']: - height += 60 - bg = Image.new('RGBA', (948, height + 80), (0, 0, 0, 0)) - bg.alpha_composite(mask_top, (0, 0)) - bg.alpha_composite(mask_body.resize((948, height)), (0, 60)) - bg.alpha_composite(mask_bottom, (0, height + 60)) - bg_draw = ImageDraw.Draw(bg) - # 画线 - bg_draw.line((250, 0, 250, 948), (255, 255, 255, 75), 2) - bg_draw.line((599, 0, 599, 60), (255, 255, 255, 75), 2) - bg_draw.line((599, 120, 599, 240), (255, 255, 255, 75), 2) - bg_draw.line((0, 60, 948, 60), (255, 255, 255, 75), 2) - bg_draw.line((0, 120, 948, 120), (255, 255, 255, 75), 2) - bg_draw.line((0, 180, 948, 180), (255, 255, 255, 75), 2) - # 顶栏 - draw_center_text(bg_draw, '伤害计算', 0, 250, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '期望伤害', 250, 599, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '暴击伤害', 599, 948, 11, 'white', get_font(30, text_font)) - - draw_center_text(bg_draw, '冰翎加成', 0, 250, 73, 'white', get_font(30, text_font)) - expect_dmg = cal_e_value(data) - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 948, 76, 'white', get_font(30, number_font)) - - draw_center_text(bg_draw, '战技长按', 0, 250, 133, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_e_dmg(data, e_value) - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 136, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 136, 'white', get_font(30, number_font)) - - draw_center_text(bg_draw, '大招持续伤害', 0, 250, 193, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_q_dmg(data, q_value) - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 196, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 196, 'white', get_font(30, number_font)) - - # 额外说明 - if data['伤害描述']: - bg_draw.line((0, 240, 948, 240), (255, 255, 255, 75), 2) - draw_center_text(bg_draw, '额外说明', 0, 250, 253, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, ','.join(data['伤害描述']), 250, 948, 256, 'white', get_font(30, text_font)) - return bg diff --git a/Paimon_Info/damage_cal/xiangling.py b/Paimon_Info/damage_cal/xiangling.py deleted file mode 100644 index 01a1334..0000000 --- a/Paimon_Info/damage_cal/xiangling.py +++ /dev/null @@ -1,111 +0,0 @@ -from copy import deepcopy -from pathlib import Path -from typing import Tuple - -from PIL import Image, ImageDraw -from littlepaimon_utils.files import load_json, load_image -from littlepaimon_utils.images import get_font, draw_center_text - -from .common import resistance_coefficient as rc, defense_coefficient as dc, attr_common_fix, q_fix, e_fix, a_fix, \ - growth_reaction, text_font, number_font - -skill_data = load_json(path=Path(__file__).parent.parent.parent / 'utils' / 'json_data' / 'roles_data.json')['香菱']['skill'] - - -def cal_e_dmg(data: dict, extra: dict) -> Tuple[float, float]: - """ - 计算香菱锅巴的伤害 - :param data: 角色数据 - :param extra: 针对元素战技的额外数值 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][1]['等级'] - 1 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][1] + extra['增伤'] - percent_value = float(skill_data['锅巴出击']['数值']['喷火伤害'][skill_level].replace('%', '')) / 100.0 - if len(data['命座']) >= 1: - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc(0.1, 0.15) * dc(role_level) - else: - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc() * dc(role_level) - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def cal_q_dmg(data: dict, extra: dict) -> Tuple[float, float]: - """ - 计算香菱大招的伤害 - :param data: 角色数据 - :param extra: 针对大招的额外数值 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][2]['等级'] - 1 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][1] + extra['增伤'] - percent_value = float(skill_data['旋火轮']['数值']['旋火轮伤害'][skill_level].replace('%', '')) / 100.0 - if len(data['命座']) >= 1: - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc(0.1, 0.15) * dc(role_level) - else: - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc() * dc(role_level) - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def draw_xiangling_dmg(data: dict): - mask_top = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩top.png') - mask_body = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩body.png') - mask_bottom = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩bottom.png') - - data = deepcopy(data) - height = 3 * 60 - 20 - data['伤害描述'] = [] if len(data['命座']) < 1 else ['锅巴减抗'] - data = attr_common_fix(data) - data, q_value = q_fix(data) - data, e_value = e_fix(data) - data, a_value = a_fix(data) - if data['伤害描述']: - height += 60 - # 蒸发系数 - if '蒸发系数' in data['属性']: - zf = growth_reaction(data['属性']['元素精通'], 1.5, 0.15) - else: - zf = growth_reaction(data['属性']['元素精通'], 1.5) - bg = Image.new('RGBA', (948, height + 80), (0, 0, 0, 0)) - bg.alpha_composite(mask_top, (0, 0)) - bg.alpha_composite(mask_body.resize((948, height)), (0, 60)) - bg.alpha_composite(mask_bottom, (0, height + 60)) - bg_draw = ImageDraw.Draw(bg) - # 画线 - bg_draw.line((250, 0, 250, 948), (255, 255, 255, 75), 2) - bg_draw.line((599, 0, 599, 240), (255, 255, 255, 75), 2) - bg_draw.line((0, 60, 948, 60), (255, 255, 255, 75), 2) - bg_draw.line((0, 120, 948, 120), (255, 255, 255, 75), 2) - bg_draw.line((0, 180, 948, 180), (255, 255, 255, 75), 2) - # 顶栏 - draw_center_text(bg_draw, '伤害计算', 0, 250, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '期望伤害', 250, 599, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '暴击伤害', 599, 948, 11, 'white', get_font(30, text_font)) - - draw_center_text(bg_draw, '锅巴喷火', 0, 250, 73, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_e_dmg(data, e_value) - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 76, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 76, 'white', get_font(30, number_font)) - - draw_center_text(bg_draw, '旋火轮', 0, 250, 133, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_q_dmg(data, q_value) - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 136, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 136, 'white', get_font(30, number_font)) - - draw_center_text(bg_draw, '旋火轮蒸发', 0, 250, 193, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, str(int(expect_dmg * zf)), 250, 599, 196, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg * zf)), 599, 948, 196, 'white', get_font(30, number_font)) - - # 额外说明 - if data['伤害描述']: - bg_draw.line((0, 240, 948, 240), (255, 255, 255, 75), 2) - draw_center_text(bg_draw, '额外说明', 0, 250, 253, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, ','.join(data['伤害描述']), 250, 948, 256, 'white', get_font(30, text_font)) - return bg diff --git a/Paimon_Info/damage_cal/xiao.py b/Paimon_Info/damage_cal/xiao.py deleted file mode 100644 index 5536cf4..0000000 --- a/Paimon_Info/damage_cal/xiao.py +++ /dev/null @@ -1,115 +0,0 @@ -from copy import deepcopy -from pathlib import Path -from typing import Tuple - -from PIL import Image, ImageDraw -from littlepaimon_utils.files import load_json, load_image -from littlepaimon_utils.images import get_font, draw_center_text - -from .common import resistance_coefficient as rc, defense_coefficient as dc, attr_common_fix, e_fix, a_fix, text_font, \ - number_font - -skill_data = load_json(path=Path(__file__).parent.parent.parent / 'utils' / 'json_data' / 'roles_data.json')['魈']['skill'] - - -def cal_attack_dmg(data: dict, extra: dict, type: str) -> Tuple[float, float]: - """ - 计算魈下落攻击的伤害 - :param data: 角色数据 - :param extra: 针对重击的额外数值 - :param type: 类型 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][0]['等级'] - 1 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['下落攻击暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][5] + extra['下落攻击增伤'] - percent_value = skill_data['普通攻击·卷积微尘']['数值']['低空/高空坠地冲击伤害'][skill_level].split('/') - if type.startswith('低空下落'): - percent_value = float(percent_value[0].replace('%', '')) / 100 - else: - percent_value = float(percent_value[1].replace('%', '')) / 100 - if role_level >= 40: - dmg_bonus += 0.25 if '首戳' not in type else 0 - q_skill_level = data['天赋'][2]['等级'] - 1 - q_bonus = float(skill_data['靖妖傩舞']['数值']['普通攻击/重击/下落攻击伤害提升'][q_skill_level].replace('%', '')) / 100 - dmg_bonus += q_bonus - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc() * dc(role_level) - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def cal_e_dmg(data: dict, extra: dict) -> Tuple[float, float]: - """ - 计算魈元素战技的伤害 - :param data: 角色数据 - :param extra: 针对元素战技的额外数值 - :return: 期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][1]['等级'] - 1 - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][5] + extra['增伤'] - - percent_value = float(skill_data['风轮两立']['数值']['技能伤害'][skill_level].replace('%', '')) / 100.0 - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc() * dc(role_level) - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def draw_xiao_dmg(data: dict): - mask_top = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩top.png') - mask_body = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩body.png') - mask_bottom = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩bottom.png') - - data = deepcopy(data) - height = 3 * 60 - 20 - data['伤害描述'] = [] - data = attr_common_fix(data) - data, e_value = e_fix(data) - data, a_value = a_fix(data) - if data['伤害描述']: - height += 60 - - bg = Image.new('RGBA', (948, height + 80), (0, 0, 0, 0)) - bg.alpha_composite(mask_top, (0, 0)) - bg.alpha_composite(mask_body.resize((948, height)), (0, 60)) - bg.alpha_composite(mask_bottom, (0, height + 60)) - bg_draw = ImageDraw.Draw(bg) - # 画线 - bg_draw.line((250, 0, 250, 948), (255, 255, 255, 75), 2) - bg_draw.line((599, 0, 599, 300), (255, 255, 255, 75), 2) - bg_draw.line((0, 60, 948, 60), (255, 255, 255, 75), 2) - bg_draw.line((0, 120, 948, 120), (255, 255, 255, 75), 2) - bg_draw.line((0, 180, 948, 180), (255, 255, 255, 75), 2) - # 顶栏 - draw_center_text(bg_draw, '伤害计算', 0, 250, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '期望伤害', 250, 599, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '暴击伤害', 599, 948, 11, 'white', get_font(30, text_font)) - - # e - draw_center_text(bg_draw, '风轮两立', 0, 250, 73, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_e_dmg(data, e_value) - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 76, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 76, 'white', get_font(30, number_font)) - - # 重击蒸发 - draw_center_text(bg_draw, '低空下落首戳', 0, 250, 133, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_attack_dmg(data, a_value, '低空下落首戳') - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 136, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 136, 'white', get_font(30, number_font)) - - # 大招蒸发 - draw_center_text(bg_draw, '高空下落首戳', 0, 250, 193, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_attack_dmg(data, a_value, '高空下落首戳') - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 196, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 196, 'white', get_font(30, number_font)) - - # 额外说明 - if data['伤害描述']: - bg_draw.line((0, 240, 948, 240), (255, 255, 255, 75), 2) - draw_center_text(bg_draw, '额外说明', 0, 250, 256, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, ','.join(data['伤害描述']), 250, 948, 256, 'white', get_font(30, text_font)) - return bg diff --git a/Paimon_Info/damage_cal/zhongli.py b/Paimon_Info/damage_cal/zhongli.py deleted file mode 100644 index 8f33b2c..0000000 --- a/Paimon_Info/damage_cal/zhongli.py +++ /dev/null @@ -1,168 +0,0 @@ -from copy import deepcopy -from pathlib import Path -from typing import Tuple - -from PIL import Image, ImageDraw -from littlepaimon_utils.files import load_json, load_image -from littlepaimon_utils.images import get_font, draw_center_text - -from .common import resistance_coefficient as rc, defense_coefficient as dc, attr_common_fix, q_fix, e_fix, a_fix, \ - text_font, number_font - -skill_data = load_json(path=Path(__file__).parent.parent.parent / 'utils' / 'json_data' / 'roles_data.json')['钟离']['skill'] - - -def cal_shield_value(data: dict) -> float: - """ - 计算钟离的护盾值 - :param data: 角色数据 - :return: 护盾值 - """ - health = data['属性']['基础生命'] + data['属性']['额外生命'] - shield_power = data['属性']['护盾强效'] - skill_level = data['天赋'][1]['等级'] - 1 - fixed_value = int(skill_data['元素战技·地心']['数值']['护盾基础吸收量'][skill_level].replace(',', '')) - percent_value = float(skill_data['元素战技·地心']['数值']['护盾附加吸收量'][skill_level].replace('%最大生命值', '')) / 100.0 - return (health * percent_value + fixed_value) * (1 + shield_power) - - -def cal_resonance_dmg(data: dict, extra: dict) -> Tuple[float, float]: - """ - 计算共鸣伤害 - :param data: 角色数据 - :param extra: 针对元素战技的额外数值 - :return: 单次共鸣的期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][1]['等级'] - 1 - health = data['属性']['基础生命'] + data['属性']['额外生命'] - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][6] + extra['增伤'] - percent_value = float(skill_data['元素战技·地心']['数值']['岩脊伤害/共鸣伤害'][skill_level].split('/')[1].replace('%', '')) / 100.0 - if role_level >= 70: - damage = (attack * percent_value + health * 0.019) * (1 + cr * cd) * dmg_bonus * rc(0.1, 0.2) * dc(role_level) - else: - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc(0.1, 0.2) * dc(role_level) - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def cal_star_dmg(data: dict, extra: dict) -> Tuple[float, float]: - """ - 计算天星伤害 - :param data: 角色数据 - :param extra: 针对大招的额外数值 - :return: 大招天星的期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][2]['等级'] - 1 - health = data['属性']['基础生命'] + data['属性']['额外生命'] - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][6] + extra['增伤'] - percent_value = float(skill_data['元素爆发·天星']['数值']['技能伤害'][skill_level].replace('%', '')) / 100.0 - if role_level >= 70: - damage = (attack * percent_value + health * 0.33) * (1 + cr * cd) * dmg_bonus * rc(0.1, - 0.2) * dc( - role_level) - else: - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc(0.1, 0.2) * dc(role_level) - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def cal_attack_dmg(data: dict, extra: dict) -> tuple: - """ - 计算踢枪单段伤害 - :param data: 角色数据 - :param extra: 针对普攻重击等的额外数值 - :return: 踢枪的期望伤害和暴击后伤害 - """ - role_level = data['等级'] - skill_level = data['天赋'][0]['等级'] - 1 - health = data['属性']['基础生命'] + data['属性']['额外生命'] - attack = data['属性']['基础攻击'] + data['属性']['额外攻击'] - cr = data['属性']['暴击率'] + extra['普攻暴击率'] - cr_ly = data['属性']['暴击率'] - cd = data['属性']['暴击伤害'] - dmg_bonus = 1 + data['属性']['伤害加成'][0] + extra['普攻增伤'] - dmg_bonus_ly = 1 + data['属性']['伤害加成'][0] - percent_value = float(skill_data['普通攻击·岩雨']['数值']['五段伤害'][skill_level].replace('%×4', '')) / 100.0 - if role_level >= 70: - damage = (attack * percent_value + health * 0.0139) * (1 + cr * cd) * dmg_bonus * rc(0.1, 0.2) * dc(role_level) - else: - damage = (attack * percent_value) * (1 + cr * cd) * dmg_bonus * rc(0.1, 0.2) * dc(role_level) - if data['武器']['名称'] == '流月针': - ly_damage = (attack * (0.15 + 0.05 * data['武器']['精炼等级'])) * (1 + cr_ly * cd) * dmg_bonus_ly * rc(0.1, 0.2) * dc( - role_level) - return (damage, ly_damage), (damage / (1 + cr * cd) * (1 + cd), ly_damage / (1 + cr_ly * cd) * (1 + cd)) - else: - return damage, damage / (1 + cr * cd) * (1 + cd) - - -def draw_zhongli_dmg(data: dict): - mask_top = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩top.png') - mask_body = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩body.png') - mask_bottom = load_image(path=Path() / 'resources' / 'LittlePaimon' / 'player_card2' / '遮罩bottom.png') - - data = deepcopy(data) - height = 5 * 60 - 20 - data['伤害描述'] = ['护盾减抗'] - data = attr_common_fix(data) - data, q_value = q_fix(data) - data, e_value = e_fix(data) - data, a_value = a_fix(data) - bg = Image.new('RGBA', (948, height + 80), (0, 0, 0, 0)) - bg.alpha_composite(mask_top, (0, 0)) - bg.alpha_composite(mask_body.resize((948, height)), (0, 60)) - bg.alpha_composite(mask_bottom, (0, height + 60)) - bg_draw = ImageDraw.Draw(bg) - # 画线 - bg_draw.line((250, 0, 250, 948), (255, 255, 255, 75), 2) - bg_draw.line((599, 0, 599, 60), (255, 255, 255, 75), 2) - bg_draw.line((599, 120, 599, 300), (255, 255, 255, 75), 2) - bg_draw.line((0, 60, 948, 60), (255, 255, 255, 75), 2) - bg_draw.line((0, 120, 948, 120), (255, 255, 255, 75), 2) - bg_draw.line((0, 180, 948, 180), (255, 255, 255, 75), 2) - bg_draw.line((0, 240, 948, 240), (255, 255, 255, 75), 2) - bg_draw.line((0, 300, 948, 300), (255, 255, 255, 75), 2) - - # 顶栏 - draw_center_text(bg_draw, '伤害计算', 0, 250, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '期望伤害', 250, 599, 11, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, '暴击伤害', 599, 948, 11, 'white', get_font(30, text_font)) - - # 护盾值 - draw_center_text(bg_draw, '玉璋护盾', 0, 250, 73, 'white', get_font(30, text_font)) - shield = cal_shield_value(data) - draw_center_text(bg_draw, str(int(shield)), 250, 948, 76, 'white', get_font(30, number_font)) - - # 共鸣伤害 - draw_center_text(bg_draw, '共鸣伤害', 0, 250, 133, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_resonance_dmg(data, e_value) - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 136, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 136, 'white', get_font(30, number_font)) - - # 天星伤害 - draw_center_text(bg_draw, '天星伤害', 0, 250, 193, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_star_dmg(data, q_value) - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 196, 'white', get_font(30, number_font)) - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 196, 'white', get_font(30, number_font)) - - # 踢枪伤害 - draw_center_text(bg_draw, '踢枪伤害', 0, 250, 253, 'white', get_font(30, text_font)) - expect_dmg, crit_dmg = cal_attack_dmg(data, a_value) - if isinstance(expect_dmg, tuple): - draw_center_text(bg_draw, f'{int(expect_dmg[0])}+{int(expect_dmg[1])}', 250, 599, 256, 'white', get_font(30, number_font)) - else: - draw_center_text(bg_draw, str(int(expect_dmg)), 250, 599, 256, 'white', get_font(30, number_font)) - if isinstance(crit_dmg, tuple): - draw_center_text(bg_draw, f'{int(crit_dmg[0])}+{int(crit_dmg[1])}', 599, 948, 256, 'white', get_font(30, number_font)) - else: - draw_center_text(bg_draw, str(int(crit_dmg)), 599, 948, 256, 'white', get_font(30, number_font)) - - # 额外说明 - draw_center_text(bg_draw, '额外说明', 0, 250, 313, 'white', get_font(30, text_font)) - draw_center_text(bg_draw, ','.join(data['伤害描述']), 250, 948, 313, 'white', get_font(30, text_font)) - return bg diff --git a/Paimon_Info/draw_role_card.py b/Paimon_Info/draw_role_card.py index e3a7eb0..afca193 100644 --- a/Paimon_Info/draw_role_card.py +++ b/Paimon_Info/draw_role_card.py @@ -27,7 +27,7 @@ def get_font(size, font='hywh.ttf'): async def draw_role_card(uid, data): bg_card = load_image(res_path / 'player_card2' / f'背景_{data["元素"]}.png', mode='RGBA') - dmg_img = get_role_dmg(data['名称'], data) + dmg_img = get_role_dmg(data) if dmg_img: bg = Image.new('RGBA', (1080, 1920 + dmg_img.size[1] + 20), (0, 0, 0, 0)) bg_card_center = bg_card.crop((0, 730, 1080, 1377)).resize((1080, dmg_img.size[1] + 667)) diff --git a/README.md b/README.md index e5a42ad..4fcc27a 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,9 @@ - 修复`60秒早报`接口bug - 修复神里绫人被识别为绫华别名的bug - 修复抽卡记录获取bug - ++ 7.8 + - `ysd`增加`甘雨、夜兰、行秋、神里绫华、阿贝多、刻晴、八重神子`伤害计算 + ## 丨功能列表 详见我的博客[功能列表](https://blog.cherishmoon.fun/posts/nonebot2funclist.html)
@@ -83,10 +85,8 @@ + 安装和启用派蒙 - git clone方式 - ```bash # 在nonebot根目录运行: - # 1、克隆派蒙源码 git clone https://github.com/CMHopeSunshine/LittlePaimon @@ -99,11 +99,8 @@ pip install -r requirements.txt ``` ### 我不熟悉NoneBot2 -**详细部署教程:** -- [Linux](https://blog.cherishmoon.fun/posts/nonebot2deploy.html#linux) -- [安卓系统](https://blog.cherishmoon.fun/posts/nonebot2deploy.html#%E5%9C%A8%E5%AE%89%E5%8D%93%E6%89%8B%E6%9C%BA%E4%B8%8A%E9%83%A8%E7%BD%B2) -- [Windows](https://blog.cherishmoon.fun/posts/nonebot2deploy.html#windows) +- [详细部署教程](https://blog.cherishmoon.fun/posts/nonebot2deploy.html) ### 添加公共cookie @@ -115,7 +112,8 @@ javascript:(function(){prompt(document.domain,document.cookie)})(); ``` -复制得到的cookie,向小派蒙发送`添加公共ck`和粘贴的内容,即可开始使用 +复制得到的cookie,向小派蒙发送`添加公共ck`和粘贴的内容,即可开始使用
+获取之后不能退出账号登录状态!推荐在无痕模式下取 ## 丨相关配置项 @@ -213,18 +211,19 @@ paimon_speak_continuously_max_len = 3 | 赞助者(排名不分先后) | 金额 | |----------------|-----| | 深海 | 10 | -| 夜空koi | 30 | +| 夜空koi | 60 | | 情话 | 20 | | 爱发电用户_Mfms | 15 | | 米特建木 | 10 | | 永远的皇珈骑士 | 30 | -| 小兔和鹿 | 30 | +| 小兔和鹿 | 50 | | el psy congroo | 20 | | SCU_OP | 30 | | 南絮ヽ | 30 | | 夜空koi我老婆 | 30 | | 昔。 | 5 | | dix | 20 | +| 凤御白 | 30 | ## 丨其他 - 本项目仅供学习使用,禁止用于商业用途 diff --git a/UPDATE_LOG.md b/UPDATE_LOG.md index 9adddc2..9e53cf2 100644 --- a/UPDATE_LOG.md +++ b/UPDATE_LOG.md @@ -63,21 +63,17 @@ - 伤害计算新增`魈` + 7.3 - 重构部分代码 - - ~~修改了插件加载方式~~ - - 不改了,回档了,依旧是用`nonebot.load_plugins` - **修改静态资源和用户数据目录** - 理论上会**自动迁移**,但`git pull`更新可能会将资源删除,所以最好**手动迁移,同时备份** - 1、将派蒙的`res`文件夹改名`LittlePaimon`,移到nonebot根目录的`resources`中(没有`resources`就新建一个) - 2、将派蒙的`user_data`文件夹移到nonebot根目录的`data/LittlePaimon`目录中(同理,没有就新建) - 静态资源改为启动时自动下载 - - ~~上传至`pypi`~~ - - ~~意味着你可以通过pip等包管理工具来下载派蒙,例子见下面的部署方法~~ - - ~~上面的修改基本上都是为了上传`pypi`,以及减少仓库体积~~ - - pip安装的话加载时存在导包问题,无法正确加载,~~算了吧~~ + 7.4 - 回档部分7.3的修改 - `ysd`新增`香菱、申鹤`伤害计算 - 修复`60秒早报`接口bug - 修复神里绫人被识别为绫华别名的bug - 修复抽卡记录获取bug ++ 7.8 + - 增加`甘雨、夜兰、行秋、神里绫华、阿贝多、刻晴、八重神子`伤害计算 diff --git a/utils/json_data/roles_data.json b/utils/json_data/roles_data.json index 4822276..5d737d9 100644 --- a/utils/json_data/roles_data.json +++ b/utils/json_data/roles_data.json @@ -21255,5 +21255,419 @@ "须弥教令院的学者曾对璃月进行民俗研究,将结果写成一本名为《琉璃岩间国土纪行》的书,须弥、璃月各存一版。其中,璃月留存的版本更名为《匣中琉璃云间月》,删去了不少巫术、神秘的部分。\n《空游饿鬼布施法》,则是仅存于须弥教令院馆藏的完整版之一节。\n文中提到,「仙众夜叉」虽有大神通大威德,仍为自身业障所困,间有大恐惧大痛苦之劫难,此乃空游饿鬼之苦,千万年不灭。\n文中列有多种安抚夜叉仙人的方法,包括食物供奉、妙音布施等等。如此为之,夜叉必会心生欢喜,甘愿为人守护平安。\n仙中贵族夜叉擅长战斗,常以战将之姿亲赴战场。然而,近千年来战乱过多,使得夜叉一族几近灭亡。如今,璃月地区仍保有巨大的降魔夜叉破损造像,只是面容均已损毁殆尽。\n顺带一提,须弥学者文笔诘屈聱牙,书中内容又过分艰深,导致《匣中琉璃云间月》的人气完全无法匹敌《提瓦特浏览指南》与艾尔·马斯克所著的各国人文风土志略。", "仙人全称是「三眼五显仙人」。「三眼」所指,正是天生双目之外的「神之眼」。那么仙人获眼与世人被天空岛垂青,究竟是否遵循着同种道理?\n魈已记不清得到神之眼的时刻了。对人类来说,这理应是终身难忘的瞬间;对他而言,却只是日后无穷战斗的开始。\n真正令魈难忘的,则是另一种时刻。\n人世节日多为庆典,只是鲜少有人记得节日背后的故事。\n这些日子,大多数是吃人怪物被圣众降服之日。人们模仿其作为,举行驱逐妖怪的仪式以纪念英雄事迹,如此习俗,逐渐演变为欢庆的节日。\n璃月各地遭摩拉克斯镇压的魔神,在半梦半醒之间,偶尔会爆发出规模异常的怨憎与残渣。其中,以海灯节之夜的爆发最为巨大。\n魈受命进行「靖妖傩舞」,于海灯节当晚彻夜厮杀。因此,他尤为厌恶海灯节。魈并不觉得战斗艰险。因他的努力,璃月港最终保住了平安。人们点起海灯,赐福的灯光照亮夜空与近海。\n如此时刻,魈心中也有一股特别的情感随之升起。\n寂寞?安心?抑或是,对未来的恐惧?少年身姿的仙人扪心自问,却得不出答案。" ] + }, + "夜兰":{ + "name": "夜兰", + "title": "兰生幽谷", + "region": "璃月", + "sex": "女", + "star": "5", + "type": "限定UP", + "element": "水", + "weapon": "弓", + "date": "2022年05月31日", + "tag": "加血、伤害提升、派遣、快速移动、协同攻击", + "birthday": "4月20日", + "mission": "幽客之章", + "introduce": "自称供职于总务司的神秘人士,却又是总务司名录里的「不存在之人」。", + "destiny_name": "幽客座", + "destiny": { + "与谋者,以局入局": "萦络纵命索的可使用次数增加1次。", + "入彀者,多多益善": "「玄掷玲珑」协同攻击时,会发射一枚额外的水箭,造成相当于夜兰生命值上限14%的水元素伤害。该效果每1.8秒至多触发一次。", + "晃盅者,琼畟药骰": "渊图玲珑骰的技能等级提高3级。至多提升至15级。", + "诓惑者,接树移花": "依照「络命丝」标记的敌人数量,每次标记将在爆发时使队伍中所有角色的生命值上限提高10%,持续25秒。通过这种方式,生命值上限至多获得40%提升。", + "坐庄者,三仙戏法": "萦络纵命索的技能等级提高3级。至多提升至15级。", + "取胜者,大小通吃": "施放渊图玲珑骰后,夜兰将进入「运筹帷幄」状态:夜兰的普通攻击将转为发生特殊的「破局矢」。这种箭矢具有与破局矢近似的特性,造成的伤害视为重击伤害,能造成破局矢156%的伤害。「运筹帷幄」状态至多持续20秒,将在夜兰发射5枚箭矢后移除。" + }, + "attribute": { + "hp": { + "1": "1125", + "20": "2918", + "40": "5810", + "50": "7472", + "60": "9374", + "70": "11056", + "80": "12749", + "90": "14450" + }, + "atk": { + "1": "19", + "20": "49", + "40": "98", + "50": "126", + "60": "158", + "70": "187", + "80": "215", + "90": "244" + }, + "def": { + "1": "43", + "20": "111", + "40": "220", + "50": "283", + "60": "355", + "70": "419", + "80": "483", + "90": "548" + }, + "attribute": "暴击率", + "attributes": { + "1": "0%", + "20": "0%", + "40": "0%", + "50": "4.8%", + "60": "9.6%", + "70": "9.6%", + "80": "14.4%", + "90": "19.2%" + } + }, + "skill": { + "普通攻击·潜形隐曜弓": { + "描述": "普通攻击\n进行至多四段的连续弓箭射击。\n重击\n进行伤害更高、更为精准的瞄准射击。\n瞄准时,流水会在箭矢上持续积聚。聚满了激流的箭矢会造成水元素伤害。\n破局\n脱离战斗状态5秒后,夜兰将获得「破局」状态,使下一次满蓄力瞄准射击所需的蓄力时间减少80%,并将在满蓄力时转为发射「破局矢」。破局矢将基于夜兰的生命值上限造成水元素范围伤害。\n下落攻击\n\n从空中射出箭雨,并迅速下坠冲击地面,在落地时造成范围伤害。", + "数值": { + "一段伤害": [ + "40.7%", + "44.0%", + "47.3%", + "52.0%", + "55.3%", + "59.1%", + "64.3%", + "69.5%", + "74.7%", + "80.4%", + "86.1%", + "", + "", + "", + "" + ], + "二段伤害": [ + "39.0%", + "42.2%", + "45.4%", + "49.9%", + "53.1%", + "56.8%", + "61.7%", + "66.7%", + "71.7%", + "77.2%", + "82.6%", + "", + "", + "", + "" + ], + "三段伤害": [ + "51.6%", + "55.8%", + "60.0%", + "66.0%", + "70.2%", + "75.0%", + "81.6%", + "88.2%", + "94.8%", + "102.0%", + "109.2%", + "", + "", + "", + "" + ], + "四段伤害": [ + "32.5%+32.5%", + "35.2%+35.2%", + "37.8%+37.8%", + "41.6%+41.6%", + "44.2%+44.2%", + "47.3%+47.3%", + "51.4%+51.4%", + "55.6%+55.6%", + "59.7%+59.7%", + "64.3%+64.3%", + "68.8%+68.8%", + "", + "", + "", + "" + ], + "瞄准射击": [ + "43.9%", + "47.4%", + "51.0%", + "56.1%", + "59.7%", + "63.8%", + "69.4%", + "75.0%", + "80.6%", + "86.7%", + "92.8%", + "", + "", + "", + "" + ], + "满蓄力瞄准射击": [ + "124%", + "133%", + "143%", + "155%", + "164%", + "174%", + "186%", + "198%", + "211%", + "223%", + "236%", + "", + "", + "", + "" + ], + "破局矢伤害": [ + "11.58%生命值上限", + "12.44%生命值上限", + "13.31%生命值上限", + "14.47%生命值上限", + "15.34%生命值上限", + "16.21%生命值上限", + "17.36%生命值上限", + "18.52%生命值上限", + "19.68%生命值上限", + "20.84%生命值上限", + "21.99%生命值上限", + "", + "", + "", + "" + ], + "下坠期间伤害": [ + "56.8%", + "61.5%", + "66.1%", + "72.7%", + "77.3%", + "82.6%", + "89.8%", + "97.1%", + "104.4%", + "112.3%", + "120.3%", + "", + "", + "", + "" + ], + "低空/高空坠地冲击伤害": [ + "114%/142%", + "123%/153%", + "132%/165%", + "145%/182%", + "154%/193%", + "165%/206%", + "180%/224%", + "194%/243%", + "209%/261%", + "225%/281%", + "240%/300%", + "", + "", + "", + "" + ] + } + }, + "萦络纵命索": { + "描述": "牵引「络命丝」疾走,缠络标记途径的敌人。\n疾走结束时,「络命丝」将会爆发,基于夜兰的生命值上限,对标记的敌人造成水元素伤害。\n点按\n快速向前疾走一段距离。\n长按\n持续疾走,并在该状态下提高夜兰的抗打断能力。\n期间,夜兰可以控制疾走的方向,并能通过再次施放技能,提前结束疾走状态。\n此外,「络命丝」爆发时,依照标记敌人的数量,夜兰将有概率获得「破局」状态:每个标记的敌人能使概率提升34%。\n\n直到她勾指扯线,恶党贼寇之辈、阴谋诡计之徒才会发现,自己已是在劫难逃。", + "数值": { + "技能伤害": [ + "22.6%生命值上限", + "24.3%生命值上限", + "26.0%生命值上限", + "28.3%生命值上限", + "30.0%生命值上限", + "31.7%生命值上限", + "33.9%生命值上限", + "36.2%生命值上限", + "38.4%生命值上限", + "40.7%生命值上限", + "43.0%生命值上限", + "45.2%生命值上限", + "48.1%生命值上限", + "", + "" + ], + "长按最大持续时间": [ + "3.0秒", + "3.0秒", + "3.0秒", + "3.0秒", + "3.0秒", + "3.0秒", + "3.0秒", + "3.0秒", + "3.0秒", + "3.0秒", + "3.0秒", + "3.0秒", + "3.0秒", + "", + "" + ], + "冷却时间": [ + "10.0秒", + "10.0秒", + "10.0秒", + "10.0秒", + "10.0秒", + "10.0秒", + "10.0秒", + "10.0秒", + "10.0秒", + "10.0秒", + "10.0秒", + "10.0秒", + "10.0秒", + "", + "" + ] + } + }, + "渊图玲珑骰": { + "描述": "造成水元素范围伤害,并凝聚出「玄掷玲珑」,协助进行战斗。\n玄掷玲珑\n将跟随角色,并在以下情况下,进行协同攻击,基于夜兰的生命值上限造成水元素伤害:\n·队伍中自己的当前场上角色进行普通攻击时,每1秒至多触发一次;\n·夜兰自己的「络命丝」爆发并命中敌人时,将进行一次协同攻击。\n\n「嗜赌可不行哦。作为大庄家,我拿大小来比喻一下吧。你用一个骰子,怎么赢得过我的七个骰子呢?」", + "数值": { + "技能伤害": [ + "7.31%生命值上限", + "7.86%生命值上限", + "8.40%生命值上限", + "9.14%生命值上限", + "9.68%生命值上限", + "10.23%生命值上限", + "10.96%生命值上限", + "11.69%生命值上限", + "12.42%生命值上限", + "13.15%生命值上限", + "13.89%生命值上限", + "14.62%生命值上限", + "15.53%生命值上限", + "", + "" + ], + "玄掷玲珑伤害": [ + "4.87%生命值上限*3", + "5.24%生命值上限*3", + "5.60%生命值上限*3", + "6.09%生命值上限*3", + "6.48%生命值上限*3", + "6.82%生命值上限*3", + "7.31%生命值上限*3", + "7.80%生命值上限*3", + "8.28%生命值上限*3", + "8.77%生命值上限*3", + "9.26%生命值上限*3", + "9.74%生命值上限*3", + "10.35%生命值上限*3", + "", + "" + ], + "持续时间": [ + "15.0秒", + "15.0秒", + "15.0秒", + "15.0秒", + "15.0秒", + "15.0秒", + "15.0秒", + "15.0秒", + "15.0秒", + "15.0秒", + "15.0秒", + "15.0秒", + "15.0秒", + "", + "" + ], + "冷却时间": [ + "18.0秒", + "18.0秒", + "18.0秒", + "18.0秒", + "18.0秒", + "18.0秒", + "18.0秒", + "18.0秒", + "18.0秒", + "18.0秒", + "18.0秒", + "18.0秒", + "18.0秒", + "", + "" + ], + "元素能量": [ + "70", + "70", + "70", + "70", + "70", + "70", + "70", + "70", + "70", + "70", + "70", + "70", + "70", + "", + "" + ] + } + }, + "猜先有方": "队伍中存在1/2/3/4种元素类型的角色时,夜兰的生命值上限提升6%/12%/18%/30%。", + "妙转随心": "「玄掷玲珑」存在期间,能使队伍中自己的当前场上角色造成的伤害提高1%,并且每1秒进一步提高3.5%,至多使角色造成的伤害提高50%。\n\n效果存在期间重新释放渊图玲珑骰,将移除原有的上述效果。", + "长考一着": "在璃月执行时长为20小时的探索派遣任务时,获得的将奖励增加25%。" + }, + "cv": { + "cn": "徐慧", + "jp": "远藤绫", + "kr": "玟我", + "en": "劳拉·波斯特" + }, + "food": { + "name": "沾露虾仁", + "star": "3星", + "type": "提升护盾", + "effect": "队伍中所有角色护盾强效提升35%,持续300秒。", + "introduce": "夜兰的特色料理。食材选用的是由翘英庄送到茶室的新茶沾露,配合现捕的河虾快速炒制。观之,色泽雅丽;闻之,茶香幽远;尝之,软嫩弹牙…等等,她怎么又端了个辣椒碟上来?", + "ingredient_list": [ + { + "name": "虾仁", + "num": "4" + }, + { + "name": "面粉", + "num": "3" + }, + { + "name": "金鱼草", + "num": "3" + } + ], + "normal": "清炒虾仁" + }, + "story": [ + "璃月总务司的工作公开透明,上至玉京台高官,下至八门基层雇员,都在政务名录中留有基本信息。\n唯独自称就职于此的夜兰是个例外。多数同僚都没听过她的大名,名录中亦查无此人。\n这一点倒是跟夜兰本人的风格相当符合——神出鬼没,变幻无常。\n她犹如一条幽灵,常以不同面目出现在各色事件中心,又赶在风暴停歇前消失无踪。\n偶尔,会有一方势力得到她的协助,但就在他们沾沾自喜时,同样的协助很快又出现在另外一方身上。\n吃过亏的人无不对此咬牙切齿,可即便如此,也始终没人能看透她的意图,更无法摸清她的立场。\n有人认为,她是服务于某个神秘势力的密探,擅长推波助澜并从中获利。\n更有人咬定,她只是个狂热的无序者,没有什么组织,更没有什么像样的目的。\n即使有,那也不过是把水搅得更浑,把火烧得更旺,再把所有人拉进她所创造的疯狂世界罢了。\n众说纷纭中,有关她的事都成了谜。真相究竟如何,或许只能由夜兰本人解答。\n不过非常可惜,这同样不是一件易事。在她乐于见到谁之前,对方永远也无法找到她。", + "璃月港药铺内偶尔会不定期地出现一类奇怪的伤患。\n有时是须弥雇佣兵,有时是枫丹冒险家,有时是自称意外落水脑袋撞到礁石的蒙德钓鱼佬…\n这些人年纪不同,身份各异,打天南地北来,却有同样一个怪癖——对疼痛稍稍有些成瘾。\n他们喜欢按压淤青时的钝痛,也爱好草药敷上伤口时的刺痛。\n甚至在一些痛苦较强的治疗过程中,他们也不介意是否用了麻药。\n新手药师们大多惊诧于伤患过人的忍耐力,由是被转移了注意力,没注意到那些上门求医的伤患从头到尾都是同一人。\n上述那些,全是夜兰乔装后的模样。依靠高超的伪装技巧,她总是避人耳目。\n至于身上的伤,当然是来自于她永不停歇的危险行动了。\n虽说做着稀奇的工作,但夜兰对世界并不是那么好奇。\n她当然会像普通人一样吃饭睡觉生活,但鲜少有东西能够真正引起如今的她的兴趣。\n长袖善舞,并非是有玩弄人心的爱好;博览群书,倒也不是乐于与书为友。\n即使她走南闯北,到过诸多国度,对远方与旅行本身却也无甚兴趣。\n在夜兰看来,完成必须之事,不能被叫做兴趣。\n甚至有时,她更乐意用掷骰子来决定如何打发时间。\n就好比,寻常的饭食已无法唤醒一个嗜辣之人的味蕾,唯有辛辣的料理才能令她高兴。\n「平淡即麻木,激烈即清醒。」\n抱着如此理念,她选择了更加尖锐的生活方式,隐秘地游走各处。\n与危险、秘密和强烈的成就感为伍…唯有如此,她才能感受到自己的存在是如此真实。", + "摘下所有面具,夜兰的真实身份,正是直属于天权星凝光的特别情报官。\n单以情报官称呼她或许还不够精准。这几个字,只能形容她的工作,不能概括她与天权的关联。\n夜兰从心底里认为,自己不能算是任何人的下属,她和凝光的合作比起上下级关系,更像是交易,或者说…达成了某种契约。\n她能为凝光取来一切从危险之花结出的情报之果,索求的回报,却只是危险与成就感本身。\n这场合作缘何而起,并不为人所知。\n唯一确定的是,夜兰的足迹早已印入璃月之外的土地。\n提瓦特大陆上的其他国度,甚至是危机重重的深渊…\n每处深藏奥秘的险窟,都可能成为兰花盛开的花圃。\n天星每念之处,恰有幽客巡游。", + "夜兰常巡游徘徊在层岩巨渊一带,凝视最深处的黑暗。\n她出身于古老世家,她的祖先曾在此地抗击巨大灾厄。\n那一战,令千万人泣血,更有仙众夜叉埋骨于此。恶战过后,幸存者寥寥无几。两位祖先一死一生,活下来的那个竟也变得疯癫,这给夜兰的家族蒙上了一层阴霾。\n夜兰一直想知道当年究竟发生了什么,虽然理智告诉她不该靠近那里,但身体却愈加被吸引。\n仿佛血脉中藏着一种说不清道不明的不详,它在召唤她前往巨渊。\n或许未来有一天,她会坠入那片黑暗吧?当年缠绕在祖先身上的灾厄,也将降临在她身上。\n她想,大概这就是自己性格稍显怪异的源头。血脉里那份不详,令她感觉不到恐惧,让她渴望危险。\n她一直这样想着,直到长大成人,直到层岩巨渊封印解开的那天。\n在诸多伙伴的帮助下,祖先的事迹清晰展现在她的眼前。\n那是一个堪称分水岭的时刻——\n那之前,她仅仅是一只凭借被危险吸引的本能迈入黑暗的野兽。\n那之后,她才真正找到了这本能的真正意义。那些潜伏在她血脉中,不停召唤她的东西,令她忧虑,却也指引她。\n它是怒吼了五百年的英雄之血。\n不会恐惧,因为勇气令她坚定;渴望危险,因为英雄骨血不甘平庸。\n终有一天,她将走上和祖先相同的道路。\n她是英雄的后人,亦将成为后人的英雄。", + "总务司手中握有一份特别关注名录。\n列在其中的人不多,但无一不是身负本领的能人异士——\n豪情无双的武装船队领袖;神通广大的异乡旅者。\n甚至还包括了部分隐居世外但依旧威名赫赫的仙人···\n这些人可以轻易在璃月搅起无边风云,即使他们并没有那般意图。\n为防意外,总务司仍然把更多的目光放在了他们身上。\n而在这份名录之外,另有一份保密等级更高的秘密情报名录。\n这份名录中的人,才是真真正正威胁到璃月的危险角色。\n里面究竟写下了哪些名字呢?\n有愚人众的诸位执行官吗?或者是神秘的深渊势力?br>\n还是说,甚至连神明也登记在册了呢?七星之外,恐怕只有夜兰才能回答这个问题,因为她就是这两份名录的编纂者。\n这样的工作成果令她愉悦,她日复一日地完善名录,就像乌鸦日复一日地往窝中衔回亮晶晶的小宝贝。\n两种收集癖的区别在于,乌鸦只用扑扑翅膀就能完成的事,夜兰需要付出多少鲜血和汗水则不可知。\n但好在这件事上,她也完全不计较成本。她相信自己无论付出多少,都远不及”这些情报的价值。\n总有一天它们会派上用场——璃月绝不会再像五百年前那样,在对危险一无所知的情况下陷入灾厄。\n有她在,璃月就不会毫无准备。", + "别在岩上茶室玩骰子。\n如果你实在想玩,请和熟悉的人一起。\n如果有陌生女人向你发出邀请,请无视她。\n这是来自行家的忠告。\n除非想跟一天的好心情说再见,否则,你不应和那个可怕女人过招。\n这位茶室常胜将军正是夜兰。岩上茶室之主——她的另一重身份。\n那时她刚从异国回来,恰逢璃月度过漩涡之魔神带来的危机。此事过后,原本占据岩上茶室的愚人众均遭清洗出局。借此机会,夜兰入主岩上茶室,将这里改造为隐秘办事处。\n一方面,茶室来客鱼龙混杂,是极好的情报来源;另一方面,她不介意偶尔放松一下,扮作熟客,喝两口茶,玩两把骰子。\n危险的本质是不定数。在夜兰眼中,玩骰子亦是如此。\n每次猜三划五都是一场微型的冒险,每次呼幺喝六都能收获一些零星的刺激。哪怕只是极轻微的挑战,她也乐此不疲。\n作为一名情报工作者,她更自信于手腕,相信自己能从对方眼神中读取信息,或是轻振手腕,掷出不合规则却合心意的点数。\n假如胜负仍是五五之数,那便只有一种可能——是对手在出千。\n不要试图讲道理。岩上茶室里没有道理可讲,那个女人更没有。\n还是乖乖地在「输家」和「该死的老千」中选一个吧。\n都不想选?那何不让一切回到最初呢?\n——别在岩上茶室玩骰子。", + "夜兰的情报生涯里,有一次值得铭记的特殊经历,兼具了失败与成功。\n说失败,是因为在那次行动中,她损失了一只名为「幽奇腕阑」的祖传玉镯。\n玉镯内印有家族术法,可以传递简单的讯息。但这类小型法器需要成对使用,互为照应,如今剩下一只,仅能当作装饰。\n而说成功是因为对手同样没能在她那里讨得好处。这位对手,来头却也相当不小,乃是当今愚人众执行官第九席——「富人」。\n「富人」暗中布下的一条隐蔽商路被夜兰渗透,货物遭到拦截。其中最为珍稀的一件藏品,也被夜兰当作玉镯的赔偿拿走了。\n古有异种魔兽,取其皮毛制成大氅,能值千金,且因数量稀少,总是有价无市。\n魔兽实力强大,虽已于数百年前死去,遗骨残骸却经年不腐,皮毛更有异香阵阵。\n这件本欲呈给女皇的献礼,却被夜兰中途截走。\n不仅如此,夜兰还拒绝了至冬人为陛下精心选择的款式。\n她直接取下兽皮,混以璃月苧麻,自制了一件新式带袖霞帔。\n一连串的事件,说大可大,说小也可小。无非二字:得失。\n得到,失去,失去,得到,一如夜兰的人生。\n而她毫不介意,乐在其中。", + "夜兰不总是独自行动。许久以前,她身边也有肝胆相照的同僚。\n有那么一小部分人,出于各种原因,选择与夜兰一同潜入黑暗。\n但在那时,夜兰还没有完全认清——诡计、诱饵、陷阱…光靠她擅长的这些事,未必就能应对一切。\n自制力强的敌人不会吃下诱饵,狡诈奸猾的敌人不会落入阴谋,实力骇人的敌人不会为陷阱所困。\n因而,他们付出代价。相继有人消失在前行的路上,虽说选择这条路的人早已有此觉悟…\n但在某次深渊调查任务结束,夜兰身边再无一人时,她终于还是停下了,长久地停步。\n直到某天,凝光亲自寻到了她栖身的木屋。\n「这么久不回璃月港,应是遇到什么事了罢。若想退出,倒也情有可原。」\n凝光立在门外,神态并不轻松,谈吐却仍自在。\n「但无妨。用人不疑,我愿意相信你是在这里寻找出路。退与进,本都是路。」\n门内一片死寂,无人回应。许久,才听见一句回答从背后传来——\n「你我都犯了一个错误。我们所做的事,不应波及普通人。」\n「普通人?」\n凝光才想到什么,只见一束靛青色光芒破空飞来,堪堪悬在她脑后。\n箭矢控制得极有分寸,很快化作玉珠似的水滴散落,落地前便散作华光。\n凝光回头,见夜兰自远处走来,手中提着一张弓,指尖还滴着血。\n一个弓手,定是全力,日夜磨练,才会十指带血。\n但凝光同样明白,夜兰这般个性,定是遭遇了非常人能遇的挫折,下定了非常人能做的决心,才会重新闭关习武。\n似是要给凝光一个答案,夜兰张弓搭箭,瞄准远处山头。\n一箭既出,如飞雷,似白虹,有贯天之势。霎那间,山间泉水翻涌躁动,被无形的力量呼唤着,化作数道水箭盘旋而上。\n数箭交错,汇于半空,顷刻炸出一片水幕,犹如夏夜骤雨。\n雨后却无飞蝶或虹彩,仅有一道泛着淡彩的光柱降落到夜兰手中。\n照凝光的话说,这「神之眼」恰是信号,意为:「自今日起,诸事交由不普通的夜兰阁下」。" + ] } } \ No newline at end of file