ysd增加甘雨、夜兰、行秋、神里绫华、阿贝多、刻晴、八重神子伤害计算

This commit is contained in:
CMHopeSunshine 2022-07-08 14:59:10 +08:00
parent 92e2ed7b6d
commit da74b2f59e
12 changed files with 1060 additions and 979 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -69,7 +69,9 @@
- 修复`60秒早报`接口bug
- 修复神里绫人被识别为绫华别名的bug
- 修复抽卡记录获取bug
+ 7.8
- `ysd`增加`甘雨、夜兰、行秋、神里绫华、阿贝多、刻晴、八重神子`伤害计算
## 丨功能列表
详见我的博客[功能列表](https://blog.cherishmoon.fun/posts/nonebot2funclist.html) <br>
@ -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`和粘贴的内容,即可开始使用<br>
获取之后不能退出账号登录状态!推荐在无痕模式下取
## 丨相关配置项
@ -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 |
## 丨其他
- 本项目仅供学习使用,禁止用于商业用途

View File

@ -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
- 增加`甘雨、夜兰、行秋、神里绫华、阿贝多、刻晴、八重神子`伤害计算

View File

@ -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照凝光的话说这「神之眼」恰是信号意为「自今日起诸事交由不普通的夜兰阁下」。"
]
}
}