Compare commits
143 Commits
Backup
...
GenshinUID
Author | SHA1 | Date | |
---|---|---|---|
c8035ddbd2 | |||
271d29c8ef | |||
2e0a2df4a2 | |||
12ad30f44f | |||
3bfc5d1d19 | |||
6c63d87e28 | |||
73c49de621 | |||
36c5cf910c | |||
5e117556ae | |||
f62a53ef5e | |||
b70a9a01f6 | |||
62b4593ef9 | |||
facbfde165 | |||
919f33449a | |||
3207c02eab | |||
48c3f05af0 | |||
434106c933 | |||
024a1debd7 | |||
71bc1135d1 | |||
3156e18083 | |||
77586e0a08 | |||
2b6e03505d | |||
019308146f | |||
8deea2a879 | |||
2afc633f64 | |||
46d672fc2c | |||
70a2eee1c0 | |||
011d158b7d | |||
ec9e51dc35 | |||
99820423c3 | |||
d454fe5bfe | |||
5e1555ff21 | |||
6d8ddf5033 | |||
cfb19604cc | |||
4126bfc48a | |||
c246a5165f | |||
8b59b9f371 | |||
0caf3c605a | |||
1308dc7ec9 | |||
10a2cc7bc7 | |||
f77195dee6 | |||
c11d79e672 | |||
2df9eef519 | |||
4cbb7afacb | |||
9b73ea2ebf | |||
719779f226 | |||
b3e85d04c8 | |||
35b06d2b1d | |||
5a469cc46c | |||
595cf50af4 | |||
cd7ad11fc3 | |||
65c705cddf | |||
d4667a7446 | |||
70438d55f0 | |||
1eb0592d0e | |||
24611c63e9 | |||
6d6ec3b8f1 | |||
872d39dbf5 | |||
1af2565237 | |||
70f3a7a513 | |||
5bcdd57bfe | |||
5dc2154073 | |||
4bc1f15335 | |||
24349d5e24 | |||
8d2959544b | |||
696034acc2 | |||
8530e690fd | |||
a370d65ecb | |||
5eccdc246a | |||
3ea4f0898a | |||
e7f992491d | |||
e462ccf60e | |||
a5c6f9c260 | |||
e7d6a709d4 | |||
4805e306b1 | |||
86b95f0891 | |||
ce3c1e7b07 | |||
b8358b064c | |||
3cfec0e799 | |||
7a5380e27f | |||
2e70e18b2d | |||
56ae609c94 | |||
c4669d72ec | |||
1c2b80cba5 | |||
172b4ef263 | |||
f3c94c2b4d | |||
e552b8b89d | |||
e6f3d61995 | |||
7c9a901d00 | |||
b5a67757fc | |||
c658ec1f2c | |||
515ee27ab2 | |||
df317e5183 | |||
23a9d47961 | |||
eb8411fa3a | |||
53a6358c20 | |||
38cfe192e7 | |||
88cf977de4 | |||
ee0270cc08 | |||
eb24ca088a | |||
f3d958f555 | |||
46e9654870 | |||
fb41af1183 | |||
7c6f3811ae | |||
d06c586325 | |||
525c6791f9 | |||
ae0c66b056 | |||
2a864fb118 | |||
a0874f0077 | |||
40bd69f6ba | |||
acf6e7ead3 | |||
97381b916d | |||
218a35e24d | |||
622cbdda8c | |||
bdb3e6287d | |||
9e33e21f5b | |||
3a0c6c44af | |||
d823089dfc | |||
cfc755dc0a | |||
8fd1ad6e8f | |||
02f3595ede | |||
22c54fafe6 | |||
cd134222e2 | |||
a2313d7f93 | |||
017333c05d | |||
969d306b64 | |||
d98d95e53a | |||
8cfeafc85a | |||
bd7e96524e | |||
7cb518f9b6 | |||
73e128c082 | |||
02d6e85756 | |||
3f561b0e88 | |||
a110618754 | |||
3faf460b50 | |||
4e326368a2 | |||
b80464a8ca | |||
d26849207a | |||
a2b1f47256 | |||
60cb1943fc | |||
d652a96f9e | |||
dbe8ebf6bc | |||
f762d81105 |
3
.gitignore
vendored
@ -1 +1,2 @@
|
||||
/.idea/
|
||||
/.idea/
|
||||
mihoyo_libs/mihoyo_bbs/bg/**
|
63
README.md
@ -12,30 +12,32 @@
|
||||
<a><img src="https://s2.loli.net/2022/02/01/QlS4piWXw5rZO3D.png"></a>
|
||||
</p>
|
||||
|
||||
|
||||
## 丨我该如何安装该插件?
|
||||
|
||||
+ 如果你使用的是[Go-cqhttp](https://github.com/Mrs4s/go-cqhttp) & [HoshinoBot](https://github.com/Ice-Cirno/HoshinoBot),**安装方法查看[此处](https://github.com/KimigaiiWuyi/GenshinUID/wiki#%E4%B8%A8%E5%AE%89%E8%A3%85hoshinobot-)**。
|
||||
+ 如果你使用的是[Go-cqhttp](https://github.com/Mrs4s/go-cqhttp) & [NoneBot2](https://github.com/nonebot/nonebot2),**安装方法查看[此处](https://github.com/KimigaiiWuyi/GenshinUID/wiki#%E4%B8%A8%E5%AE%89%E8%A3%85nonebot2)**。(**开发者正在使用**)
|
||||
+ 如果你使用的是[Go-cqhttp](https://github.com/Mrs4s/go-cqhttp)
|
||||
& [HoshinoBot](https://github.com/Ice-Cirno/HoshinoBot),**安装方法查看[此处](https://github.com/KimigaiiWuyi/GenshinUID/wiki#%E4%B8%A8%E5%AE%89%E8%A3%85hoshinobot-)**。
|
||||
+ 如果你使用的是[Go-cqhttp](https://github.com/Mrs4s/go-cqhttp)
|
||||
& [NoneBot2](https://github.com/nonebot/nonebot2),**安装方法查看[此处](https://github.com/KimigaiiWuyi/GenshinUID/wiki#%E4%B8%A8%E5%AE%89%E8%A3%85nonebot2)**。(**开发者正在使用**)
|
||||
|
||||
+ 如果你想在QQ官方的频道Bot使用此插件,你需要**做好以下准备**:
|
||||
- 拥有QQ频道机器人的开发者账号(类型:私域)
|
||||
- 拥有已经备案好的服务器地址(视情况后期官方放开本地图片发送而定)
|
||||
- **腾讯频道Bot官方的文档**,查看[此处](https://bot.q.qq.com/wiki/#)
|
||||
- 安装方法:基于官方的[PythonSDK](https://github.com/tencent-connect/botpy),本插件的安装方法可自行摸索。
|
||||
- 拥有QQ频道机器人的开发者账号(类型:私域)
|
||||
- 拥有已经备案好的服务器地址(视情况后期官方放开本地图片发送而定)
|
||||
- **腾讯频道Bot官方的文档**,查看[此处](https://bot.q.qq.com/wiki/#)
|
||||
- 安装方法:基于官方的[PythonSDK](https://github.com/tencent-connect/botpy),本插件的安装方法可自行摸索。
|
||||
|
||||
## 丨我该如何获取Cookies?[#92](https://github.com/KimigaiiWuyi/GenshinUID/issues/92)([@RemKeeper](https://github.com/RemKeeper))
|
||||
|
||||
```
|
||||
var cookie=document.cookie;
|
||||
```js
|
||||
var cookie = document.cookie;
|
||||
var Str_Num = cookie.indexOf('_MHYUUID=');
|
||||
cookie ='添加 '+cookie.substring(Str_Num);
|
||||
var ask=confirm('Cookie:'+cookie+'\n\n按确认,然后粘贴发送给机器人');
|
||||
if(ask==true)
|
||||
{copy(cookie);
|
||||
msg=cookie}
|
||||
else
|
||||
{msg='Cancel'}
|
||||
cookie = '添加 ' + cookie.substring(Str_Num);
|
||||
var ask = confirm('Cookie:' + cookie + '\n\n按确认,然后粘贴发送给机器人');
|
||||
if (ask == true) {
|
||||
copy(cookie);
|
||||
msg = cookie
|
||||
} else {
|
||||
msg = 'Cancel'
|
||||
}
|
||||
```
|
||||
|
||||
1. 复制上面全部代码,然后打开https://bbs.mihoyo.com/ys/
|
||||
@ -46,11 +48,18 @@ else
|
||||
**警告:Cookies属于个人隐私,其效用相当于账号密码,请勿随意公开!**
|
||||
|
||||
## 丨获取米游社Stoken([AutoMihoyoBBS](https://github.com/Womsxd/AutoMihoyoBBS#%E8%8E%B7%E5%8F%96%E7%B1%B3%E6%B8%B8%E7%A4%BECookie))
|
||||
|
||||
**前提**:已经添加过米游社Cookies,并且已经绑定过uid(仅用于米游社币的获取)
|
||||
```sh
|
||||
var cookie=document.cookie;
|
||||
var ask=confirm('Cookie:'+cookie+'\n\nDo you want to copy the cookie to the clipboard?');
|
||||
if(ask==true){copy("添加 stoken" + cookie);msg=cookie}else{msg='Cancel'}
|
||||
|
||||
```js
|
||||
var cookie = document.cookie;
|
||||
var ask = confirm('Cookie:' + cookie + '\n\nDo you want to copy the cookie to the clipboard?');
|
||||
if (ask == true) {
|
||||
copy("添加 stoken" + cookie);
|
||||
msg = cookie
|
||||
} else {
|
||||
msg = 'Cancel'
|
||||
}
|
||||
```
|
||||
|
||||
1. 复制上面全部代码,然后打开http://user.mihoyo.com/
|
||||
@ -65,8 +74,13 @@ if(ask==true){copy("添加 stoken" + cookie);msg=cookie}else{msg='Cancel'}
|
||||
- [PaimonBot](https://github.com/XiaoMiku01/PaimonBot) - 插件原始代码来自于它
|
||||
- [YuanShen_User_Info](https://github.com/Womsxd/YuanShen_User_Info) - 米游社API来自于它
|
||||
- *[MiniGG](https://www.minigg.cn/)* - Wiki API来自于它
|
||||
- [@MingxuanGame](https://github.com/MingxuanGame) - [Nonebot2-beta1](https://github.com/KimigaiiWuyi/GenshinUID/tree/nonebot2-beta1)分支新建与维护
|
||||
- [@shirokurakana](https://github.com/shirokurakana) - [Nonebot2-beta1分支的修复与优化](https://github.com/KimigaiiWuyi/GenshinUID/pull/118)
|
||||
- [@MingxuanGame](https://github.com/MingxuanGame)
|
||||
- [Nonebot2-beta1](https://github.com/KimigaiiWuyi/GenshinUID/tree/nonebot2-beta1)分支新建与维护
|
||||
- [@shirokurakana](https://github.com/shirokurakana)
|
||||
- [Nonebot2-beta1分支的修复与优化](https://github.com/KimigaiiWuyi/GenshinUID/pull/118)
|
||||
- [@猫冬](https://bbs.mihoyo.com/ys/accountCenter/postList?id=74019947) - 原神攻略的**授权**使用
|
||||
- [@blue菌hehe](https://bbs.mihoyo.com/ys/accountCenter/postList?id=160367110) - 参考面板的**授权**使用
|
||||
- [@Enka.Network](https://enka.shinshin.moe/) - 展柜面板的数据来源
|
||||
- [@AMEKENN](https://github.com/AMEKENN) - 米游社签到部分的代码指导
|
||||
- [@lgc233](https://github.com/lgc2333) - 众多优秀PR贡献
|
||||
- [@RemKeeper](https://github.com/RemKeeper) - 简易Cookies获取文档
|
||||
@ -76,8 +90,9 @@ if(ask==true){copy("添加 stoken" + cookie);msg=cookie}else{msg='Cancel'}
|
||||
|
||||
## 丨其他
|
||||
|
||||
+ 如果对本插件有功能建议&Bug报告,欢迎提Issuse & Pr,每一条都会详细看过
|
||||
+ 如果对本插件有功能建议&Bug报告,欢迎提Issue & Pr,每一条都会详细看过
|
||||
+ 如果本插件对你有帮助,不要忘了点个Star~
|
||||
+ 本项目仅供学习使用,请勿用于商业用途
|
||||
+ [爱发电](https://afdian.net/@KimigaiiWuyi)
|
||||
+ [GPL-3.0 License](https://github.com/KimigaiiWuyi/GenshinUID/blob/main/LICENSE) © [@KimigaiiWuyi](https://github.com/KimigaiiWuyi)
|
||||
+ [GPL-3.0 License](https://github.com/KimigaiiWuyi/GenshinUID/blob/main/LICENSE)
|
||||
© [@KimigaiiWuyi](https://github.com/KimigaiiWuyi)
|
||||
|
5769
enkaToData/data/AvatarExcelConfigData.json
Normal file
8434
enkaToData/data/AvatarSkillExcelConfigData.json
Normal file
6948
enkaToData/data/AvatarTalentExcelConfigData.json
Normal file
2194
enkaToData/data/DisplayItemExcelConfigData.json
Normal file
116347
enkaToData/data/ReliquaryExcelConfigData.json
Normal file
7819
enkaToData/data/WeaponExcelConfigData.json
Normal file
239679
enkaToData/data/textMap.json
Normal file
BIN
enkaToData/data/参考面板2.7(上).xlsx
Normal file
154
enkaToData/dataToMap.py
Normal file
@ -0,0 +1,154 @@
|
||||
import asyncio
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import httpx
|
||||
|
||||
R_PATH = Path(__file__).parents[0]
|
||||
MAP_PATH = R_PATH / 'map'
|
||||
DATA_PATH = R_PATH / 'data'
|
||||
|
||||
version = '2.8.0'
|
||||
|
||||
avatarName2Element_fileName = f'avatarName2Element_mapping_{version}.json'
|
||||
weaponHash2Name_fileName = f'weaponHash2Name_mapping_{version}.json'
|
||||
weaponHash2Type_fileName = f'weaponHash2Type_mapping_{version}.json'
|
||||
skillId2Name_fileName = f'skillId2Name_mapping_{version}.json'
|
||||
talentId2Name_fileName = f'talentId2Name_mapping_{version}.json'
|
||||
avatarId2Name_fileName = f'avatarId2Name_mapping_{version}.json'
|
||||
|
||||
artifact2attr_fileName = f'artifact2attr_mapping_{version}.json'
|
||||
icon2Name_fileName = f'icon2Name_mapping_{version}.json'
|
||||
|
||||
with open(DATA_PATH / 'textMap.json', "r", encoding='UTF-8') as f:
|
||||
raw_data = json.load(f)
|
||||
|
||||
|
||||
async def avatarId2NameJson() -> None:
|
||||
with open(DATA_PATH / 'AvatarExcelConfigData.json', "r", encoding='UTF-8') as f:
|
||||
avatar_data = json.load(f)
|
||||
|
||||
temp = {}
|
||||
for i in avatar_data:
|
||||
temp[str(i['id'])] = raw_data[str(i['nameTextMapHash'])]
|
||||
|
||||
with open(MAP_PATH / avatarId2Name_fileName, 'w', encoding='UTF-8') as file:
|
||||
json.dump(temp, file, ensure_ascii=False)
|
||||
|
||||
|
||||
async def avatarName2ElementJson() -> None:
|
||||
with open(MAP_PATH / avatarId2Name_fileName, "r", encoding='UTF-8') as f:
|
||||
avatarId2Name = json.load(f)
|
||||
|
||||
temp = {}
|
||||
elementMap = {'风': 'Anemo', '岩': 'Geo', '草': 'Dendro', '火': 'Pyro', '水': 'Hydro', '冰': 'Cryo', '雷': 'Electro'}
|
||||
for i in list(avatarId2Name.values()):
|
||||
data = json.loads(httpx.get('https://info.minigg.cn/characters?query={}'.format(i)).text)
|
||||
if 'errcode' in data:
|
||||
pass
|
||||
else:
|
||||
temp[i] = elementMap[data['element']]
|
||||
|
||||
with open(MAP_PATH / avatarName2Element_fileName, 'w', encoding='UTF-8') as file:
|
||||
json.dump(temp, file, ensure_ascii=False)
|
||||
|
||||
|
||||
async def weaponHash2NameJson() -> None:
|
||||
with open(DATA_PATH / 'WeaponExcelConfigData.json', "r", encoding='UTF-8') as f:
|
||||
weapon_data = json.load(f)
|
||||
|
||||
temp = {}
|
||||
for i in weapon_data:
|
||||
temp[str(i['nameTextMapHash'])] = raw_data[str(i['nameTextMapHash'])]
|
||||
|
||||
with open(MAP_PATH / weaponHash2Name_fileName, 'w', encoding='UTF-8') as file:
|
||||
json.dump(temp, file, ensure_ascii=False)
|
||||
|
||||
|
||||
async def weaponHash2TypeJson() -> None:
|
||||
with open(DATA_PATH / 'WeaponExcelConfigData.json', "r", encoding='UTF-8') as f:
|
||||
weapon_data = json.load(f)
|
||||
|
||||
temp = {}
|
||||
for i in weapon_data:
|
||||
if i['weaponType'] == 'WEAPON_POLE':
|
||||
weaponType = "长柄武器"
|
||||
elif i['weaponType'] == 'WEAPON_BOW':
|
||||
weaponType = "弓"
|
||||
elif i['weaponType'] == 'WEAPON_SWORD_ONE_HAND':
|
||||
weaponType = "单手剑"
|
||||
elif i['weaponType'] == 'WEAPON_CLAYMORE':
|
||||
weaponType = "双手剑"
|
||||
elif i['weaponType'] == 'WEAPON_CATALYST':
|
||||
weaponType = "法器"
|
||||
else:
|
||||
weaponType = ""
|
||||
temp[str(i['nameTextMapHash'])] = weaponType
|
||||
|
||||
with open(MAP_PATH / weaponHash2Type_fileName, 'w', encoding='UTF-8') as file:
|
||||
json.dump(temp, file, ensure_ascii=False)
|
||||
|
||||
|
||||
async def skillId2NameJson() -> None:
|
||||
with open(DATA_PATH / 'AvatarSkillExcelConfigData.json', "r", encoding='UTF-8') as f:
|
||||
skill_data = json.load(f)
|
||||
|
||||
temp = {'Name': {}, 'Icon': {}}
|
||||
for i in skill_data:
|
||||
temp['Name'][str(i['id'])] = raw_data[str(i['nameTextMapHash'])]
|
||||
temp['Icon'][str(i['id'])] = i['skillIcon']
|
||||
|
||||
with open(MAP_PATH / skillId2Name_fileName, 'w', encoding='UTF-8') as file:
|
||||
json.dump(temp, file, ensure_ascii=False)
|
||||
|
||||
|
||||
async def talentId2NameJson() -> None:
|
||||
with open(DATA_PATH / 'AvatarTalentExcelConfigData.json', "r", encoding='UTF-8') as f:
|
||||
talent_data = json.load(f)
|
||||
|
||||
temp = {'Name': {}, 'Icon': {}}
|
||||
for i in talent_data:
|
||||
temp['Name'][str(i['talentId'])] = raw_data[str(i['nameTextMapHash'])]
|
||||
temp['Icon'][str(i['talentId'])] = i['icon']
|
||||
|
||||
with open(MAP_PATH / talentId2Name_fileName, 'w', encoding='UTF-8') as file:
|
||||
json.dump(temp, file, ensure_ascii=False)
|
||||
|
||||
async def artifact2attrJson() -> None:
|
||||
with open(DATA_PATH / 'ReliquaryExcelConfigData.json', "r", encoding='UTF-8') as f:
|
||||
reliquary_data = json.load(f)
|
||||
|
||||
with open(DATA_PATH / 'DisplayItemExcelConfigData.json', "r", encoding='UTF-8') as f:
|
||||
Display_data = json.load(f)
|
||||
|
||||
temp = {}
|
||||
for i in reliquary_data:
|
||||
temp[str(i['icon'])] = raw_data[str(i['nameTextMapHash'])]
|
||||
|
||||
with open(MAP_PATH / icon2Name_fileName, 'w', encoding='UTF-8') as file:
|
||||
json.dump(temp, file, ensure_ascii=False)
|
||||
|
||||
temp2 = {}
|
||||
for i in Display_data:
|
||||
if i['icon'].startswith('UI_RelicIcon'):
|
||||
temp2[raw_data[str(i['nameTextMapHash'])]] = '_'.join(i['icon'].split('_')[:-1])
|
||||
|
||||
temp3 = {}
|
||||
for i in temp:
|
||||
for k in temp2:
|
||||
if i.startswith(temp2[k]):
|
||||
temp3[temp[i]] = k
|
||||
|
||||
with open(MAP_PATH / artifact2attr_fileName, 'w', encoding='UTF-8') as file:
|
||||
json.dump(temp3, file, ensure_ascii=False)
|
||||
|
||||
async def main():
|
||||
await avatarId2NameJson()
|
||||
await avatarName2ElementJson()
|
||||
await weaponHash2NameJson()
|
||||
await skillId2NameJson()
|
||||
await talentId2NameJson()
|
||||
await weaponHash2TypeJson()
|
||||
await artifact2attrJson()
|
||||
|
||||
asyncio.run(main())
|
162
enkaToData/dmgCalc/artifacts_effect.json
Normal file
@ -0,0 +1,162 @@
|
||||
{
|
||||
"勇士": {
|
||||
"2": "",
|
||||
"4": "dmgBonus+30"
|
||||
},
|
||||
"辰砂往生录": {
|
||||
"2": "",
|
||||
"4": "attack+48"
|
||||
},
|
||||
"来歆余响": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"华馆梦醒形骸记": {
|
||||
"2": "",
|
||||
"4": "dmgBonus+24;defense+24"
|
||||
},
|
||||
"海染砗磲": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"绝缘之旗印": {
|
||||
"2": "",
|
||||
"4": "Q:dmgBonus+75%25%ce"
|
||||
},
|
||||
"追忆之注连": {
|
||||
"2": "",
|
||||
"4": "ABC:dmgBonus+50"
|
||||
},
|
||||
"千岩牢固": {
|
||||
"2": "",
|
||||
"4": "attack+20;shieldBouns+30"
|
||||
},
|
||||
"苍白之火": {
|
||||
"2": "",
|
||||
"4": "attack+18;physicalDmgBonus+25"
|
||||
},
|
||||
"平息鸣雷的尊者": {
|
||||
"2": "",
|
||||
"4": "dmgBonus+35"
|
||||
},
|
||||
"炽烈的炎之魔女": {
|
||||
"2": "",
|
||||
"4": "a+15;dmgBonus+22.5"
|
||||
},
|
||||
"流浪大地的乐团": {
|
||||
"2": "",
|
||||
"4": "B:dmgBonus+35"
|
||||
},
|
||||
"染血的骑士道": {
|
||||
"2": "",
|
||||
"4": "B:dmgBonus+50"
|
||||
},
|
||||
"被怜爱的少女": {
|
||||
"2": "",
|
||||
"4": "healBouns+20"
|
||||
},
|
||||
"角斗士的终幕礼": {
|
||||
"2": "",
|
||||
"4": "A:dmgBonus+35"
|
||||
},
|
||||
"渡过烈火的贤人": {
|
||||
"2": "",
|
||||
"4": "dmgBonus+35"
|
||||
},
|
||||
"悠古的磐岩": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"如雷的盛怒": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"沉沦之心": {
|
||||
"2": "",
|
||||
"4": "AB:dmgBonus+30"
|
||||
},
|
||||
"逆飞的流星": {
|
||||
"2": "",
|
||||
"4": "AB:dmgBonus+40"
|
||||
},
|
||||
"昔日宗室之仪": {
|
||||
"2": "Q:dmgBonus+20",
|
||||
"4": "attack+20"
|
||||
},
|
||||
"翠绿之影": {
|
||||
"2": "",
|
||||
"4": "g+60"
|
||||
},
|
||||
"冰风迷途的勇士": {
|
||||
"2": "",
|
||||
"4": "critrate+40"
|
||||
},
|
||||
"勇士之心": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"教官": {
|
||||
"2": "",
|
||||
"4": "em+120"
|
||||
},
|
||||
"流放者": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"战狂": {
|
||||
"2": "",
|
||||
"4": "critrate+24"
|
||||
},
|
||||
"武人": {
|
||||
"2": "AB:dmgBonus+15",
|
||||
"4": "AB:dmgBonus+25"
|
||||
},
|
||||
"学士": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"赌徒": {
|
||||
"2": "E:dmgBonus+20",
|
||||
"4": ""
|
||||
},
|
||||
"奇迹": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"行者之心": {
|
||||
"2": "",
|
||||
"4": "B:critrate+30"
|
||||
},
|
||||
"守护之心": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"幸运儿": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"冒险家": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"游医": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"祭冰之人": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"祭雷之人": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"祭火之人": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
},
|
||||
"祭水之人": {
|
||||
"2": "",
|
||||
"4": ""
|
||||
}
|
||||
}
|
218
enkaToData/dmgCalc/avatarName2SkillAdd_mapping_2.8.0.json
Normal file
@ -0,0 +1,218 @@
|
||||
{
|
||||
"旅行者": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"胡桃": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"托马": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"宵宫": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"烟绯": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"可莉": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"迪卢克": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"辛焱": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"安柏": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"香菱": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"班尼特": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"珊瑚宫心海": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"达达利亚": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"行秋": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"莫娜": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"芭芭拉": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"申鹤": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"神里绫华": [
|
||||
3,
|
||||
"E"
|
||||
],
|
||||
"优菈": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"甘雨": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"凯亚": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"重云": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"七七": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"迪奥娜": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"罗莎莉亚": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"埃洛伊": [
|
||||
null,
|
||||
null
|
||||
],
|
||||
"八重神子": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"雷电将军": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"九条裟罗": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"刻晴": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"雷泽": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"菲谢尔": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"丽莎": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"北斗": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"雷主": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"早柚": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"枫原万叶": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"魈": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"温迪": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"琴": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"砂糖": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"风主": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"荒泷一斗": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"五郎": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"阿贝多": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"钟离": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"诺艾尔": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"凝光": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"岩主": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"云堇": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"神里绫人": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"夜兰": [
|
||||
"Q",
|
||||
"E"
|
||||
],
|
||||
"久岐忍": [
|
||||
"E",
|
||||
"Q"
|
||||
],
|
||||
"鹿野院平藏": [
|
||||
"E",
|
||||
"Q"
|
||||
]
|
||||
}
|
7426
enkaToData/dmgCalc/char_action.json
Normal file
214
enkaToData/dmgCalc/char_skill_effect.json
Normal file
@ -0,0 +1,214 @@
|
||||
{
|
||||
"神里绫华": {
|
||||
"50": "AB:dmgBonus+30",
|
||||
"70": "dmgBonus+18"
|
||||
},
|
||||
"琴": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"旅行者": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"丽莎": {
|
||||
"50": "",
|
||||
"70": "d+15"
|
||||
},
|
||||
"芭芭拉": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"凯亚": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"迪卢克": {
|
||||
"50": "",
|
||||
"70": "ABCE:dmgBonus+20"
|
||||
},
|
||||
"雷泽": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"安柏": {
|
||||
"50": "Q:critrate+10",
|
||||
"70": "attack+15"
|
||||
},
|
||||
"温迪": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"香菱": {
|
||||
"50": "",
|
||||
"70": "attack+10"
|
||||
},
|
||||
"北斗": {
|
||||
"50": "",
|
||||
"70": "AB:dmgBonus+15"
|
||||
},
|
||||
"行秋": {
|
||||
"50": "",
|
||||
"70": "dmgBonus+20"
|
||||
},
|
||||
"魈": {
|
||||
"50": "dmgBonus+15",
|
||||
"70": "E:dmgBonus+15"
|
||||
},
|
||||
"凝光": {
|
||||
"50": "",
|
||||
"70": "dmgBonus+12"
|
||||
},
|
||||
"可莉": {
|
||||
"50": "B:dmgBonus+50",
|
||||
"70": ""
|
||||
},
|
||||
"钟离": {
|
||||
"50": "",
|
||||
"70": "ABC:addDmg+1.39%hp;E:addDmg+1.9%hp;Q:addDmg+33%hp"
|
||||
},
|
||||
"菲谢尔": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"班尼特": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"达达利亚": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"诺艾尔": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"七七": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"重云": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"甘雨": {
|
||||
"50": "B:critrate+20",
|
||||
"70": "dmgBonus+20"
|
||||
},
|
||||
"阿贝多": {
|
||||
"50": "E:dmgBonus+12",
|
||||
"70": "em+125"
|
||||
},
|
||||
"迪奥娜": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"莫娜": {
|
||||
"50": "",
|
||||
"70": "dmgBonus+20%ce"
|
||||
},
|
||||
"刻晴": {
|
||||
"50": "",
|
||||
"70": "Q:critrate+15;ce+15"
|
||||
},
|
||||
"砂糖": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"辛焱": {
|
||||
"50": "",
|
||||
"70": "physicalDmgBonus+15"
|
||||
},
|
||||
"罗莎莉亚": {
|
||||
"50": "E:critrate+12",
|
||||
"70": ""
|
||||
},
|
||||
"胡桃": {
|
||||
"50": "",
|
||||
"70": "dmgBonus+33"
|
||||
},
|
||||
"枫原万叶": {
|
||||
"50": "",
|
||||
"70": "dmgBonus+0.04%em"
|
||||
},
|
||||
"烟绯": {
|
||||
"50": "B:dmgBonus+15",
|
||||
"70": "B:addDmg+80%attack"
|
||||
},
|
||||
"宵宫": {
|
||||
"50": "dmgBonus+20",
|
||||
"70": ""
|
||||
},
|
||||
"托马": {
|
||||
"50": "",
|
||||
"70": "E:addDmg+2.2%hp"
|
||||
},
|
||||
"优菈": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"雷电将军": {
|
||||
"50": "",
|
||||
"70": "dmgBonus+0.4%ce"
|
||||
},
|
||||
"早柚": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"珊瑚宫心海": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"五郎": {
|
||||
"50": "defense+25",
|
||||
"70": "E:addDmg+156%defense;Q:addDmg+15.6%defense"
|
||||
},
|
||||
"九条裟罗": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"荒泷一斗": {
|
||||
"50": "",
|
||||
"70": "荒泷逆袈裟连斩伤害:addDmg+35%defense;荒泷逆袈裟终结伤害:addDmg+35%defense"
|
||||
},
|
||||
"八重神子": {
|
||||
"50": "",
|
||||
"70": "E:dmgBonus+0.15%em"
|
||||
},
|
||||
"夜兰": {
|
||||
"50": "hp+12",
|
||||
"70": "dmgBonus+15"
|
||||
},
|
||||
"埃洛伊": {
|
||||
"50": "attack+16",
|
||||
"70": "BEQ:dmgBonus+35"
|
||||
},
|
||||
"申鹤": {
|
||||
"50": "dmgBonus+15",
|
||||
"70": "Q:dmgBonus+15"
|
||||
},
|
||||
"云堇": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"久岐忍": {
|
||||
"50": "",
|
||||
"70": "dmgBonus+25%em"
|
||||
},
|
||||
"神里绫人": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"阿葵丽雅": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"瑶瑶": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
},
|
||||
"鹿野院平藏": {
|
||||
"50": "",
|
||||
"70": ""
|
||||
}
|
||||
}
|
426
enkaToData/dmgCalc/char_talent_effect.json
Normal file
@ -0,0 +1,426 @@
|
||||
{
|
||||
"神里绫华": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "d+30",
|
||||
"5": "",
|
||||
"6": "B:dmgBonus+298"
|
||||
},
|
||||
"琴": {
|
||||
"1": "E:dmgBonus+40",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"旅行者": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"丽莎": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"芭芭拉": {
|
||||
"1": "",
|
||||
"2": "dmgBonus+15",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"凯亚": {
|
||||
"1": "AB:critrate+15",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"迪卢克": {
|
||||
"1": "dmgBonus+15",
|
||||
"2": "attack+30",
|
||||
"3": "",
|
||||
"4": "E:dmgBonus+40",
|
||||
"5": "",
|
||||
"6": "A:dmgBonus+30"
|
||||
},
|
||||
"雷泽": {
|
||||
"1": "dmgBonus+10",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "d+15",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"安柏": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "attack+15"
|
||||
},
|
||||
"温迪": {
|
||||
"1": "",
|
||||
"2": "r+12",
|
||||
"3": "",
|
||||
"4": "dmgBonus+25",
|
||||
"5": "",
|
||||
"6": "r+20"
|
||||
},
|
||||
"香菱": {
|
||||
"1": "r+15",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "EQ:dmgBonus+15"
|
||||
},
|
||||
"北斗": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "r+15"
|
||||
},
|
||||
"行秋": {
|
||||
"1": "",
|
||||
"2": "r+15",
|
||||
"3": "",
|
||||
"4": "E:dmgBonus+50",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"魈": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "defense+100",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"凝光": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"可莉": {
|
||||
"1": "",
|
||||
"2": "d+23",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "dmgBonus+10"
|
||||
},
|
||||
"钟离": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"菲谢尔": {
|
||||
"1": "A:addDmg+22%attack",
|
||||
"2": "召唤伤害:addDmg+200%attack",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"班尼特": {
|
||||
"1": "",
|
||||
"2": "ce+30",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "dmgBonus+15"
|
||||
},
|
||||
"达达利亚": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"诺艾尔": {
|
||||
"1": "",
|
||||
"2": "B:dmgBonus+15",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "attack+50%defense"
|
||||
},
|
||||
"七七": {
|
||||
"1": "",
|
||||
"2": "AB:dmgBonus+15",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"重云": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "Q:dmgBonus+15"
|
||||
},
|
||||
"甘雨": {
|
||||
"1": "r+15",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "dmgBonus+15",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"阿贝多": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "C:dmgBonus+30",
|
||||
"5": "",
|
||||
"6": "dmgBonus+17"
|
||||
},
|
||||
"迪奥娜": {
|
||||
"1": "",
|
||||
"2": "E:dmgBonus+15;shieldBouns+15",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "em+200"
|
||||
},
|
||||
"莫娜": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "B:dmgBonus+180"
|
||||
},
|
||||
"刻晴": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "attack+25",
|
||||
"5": "",
|
||||
"6": "dmgBonus+18"
|
||||
},
|
||||
"砂糖": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"辛焱": {
|
||||
"1": "",
|
||||
"2": "Q:critrate+100",
|
||||
"3": "",
|
||||
"4": "r+15",
|
||||
"5": "",
|
||||
"6": "B:attack+50%defense"
|
||||
},
|
||||
"罗莎莉亚": {
|
||||
"1": "A:dmgBonus+10",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "r+20"
|
||||
},
|
||||
"胡桃": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"枫原万叶": {
|
||||
"1": "",
|
||||
"2": "em+200",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "ABC:dmgBonus+0.2%em"
|
||||
},
|
||||
"烟绯": {
|
||||
"1": "",
|
||||
"2": "B:critrate+20",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "B:dmgBonus+10"
|
||||
},
|
||||
"宵宫": {
|
||||
"1": "attack+20",
|
||||
"2": "dmgBonus+25",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "A:dmgBonus+30"
|
||||
},
|
||||
"托马": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "ABC:dmgBonus+15"
|
||||
},
|
||||
"优菈": {
|
||||
"1": "dmgBonus+30",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "Q:dmgBonus+25",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"雷电将军": {
|
||||
"1": "",
|
||||
"2": "Q:ignoreDef+60",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"早柚": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "Q:addDmg+0.2%em"
|
||||
},
|
||||
"珊瑚宫心海": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "dmgBonus+40"
|
||||
},
|
||||
"五郎": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"九条裟罗": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": "critdmg+60"
|
||||
},
|
||||
"荒泷一斗": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "attack+20;defense+20",
|
||||
"5": "",
|
||||
"6": "B:critdmg+70"
|
||||
},
|
||||
"八重神子": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "dmgBonus+20",
|
||||
"5": "",
|
||||
"6": "E:ignoreDef+60"
|
||||
},
|
||||
"夜兰": {
|
||||
"1": "",
|
||||
"2": "Q:addDmg+14%hp",
|
||||
"3": "",
|
||||
"4": "hp+40",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"埃洛伊": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"申鹤": {
|
||||
"1": "",
|
||||
"2": "EQ:critdmg+15",
|
||||
"3": "",
|
||||
"4": "E:dmgBonus+105",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"云堇": {
|
||||
"1": "",
|
||||
"2": "A:dmgBonus+15",
|
||||
"3": "",
|
||||
"4": "defense+20",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"久岐忍": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "ABC:addDmg+9.7%hp",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"神里绫人": {
|
||||
"1": "E:dmgBonus+40",
|
||||
"2": "hp+50",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"阿葵丽雅": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"瑶瑶": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": "",
|
||||
"6": ""
|
||||
},
|
||||
"鹿野院平藏": {
|
||||
"1": "",
|
||||
"2": "A:dmgBonus+15",
|
||||
"3": "",
|
||||
"4": "defense+20",
|
||||
"5": "",
|
||||
"6": ""
|
||||
}
|
||||
}
|
421
enkaToData/dmgCalc/dmgCalc.py
Normal file
@ -0,0 +1,421 @@
|
||||
from pathlib import Path
|
||||
from typing import List, Optional, Tuple
|
||||
import json
|
||||
from PIL import Image, ImageDraw, ImageFont, ImageChops
|
||||
|
||||
DMG_PATH = Path(__file__).parents[0]
|
||||
DMG_TEXT_PATH = DMG_PATH / 'texture2d'
|
||||
|
||||
version = '2.8.0'
|
||||
avatarName2SkillAdd_fileName = f'avatarName2SkillAdd_mapping_{version}.json'
|
||||
|
||||
with open(DMG_PATH / avatarName2SkillAdd_fileName, "r", encoding='UTF-8') as f:
|
||||
avatarName2SkillAdd = json.load(f)
|
||||
|
||||
with open(DMG_PATH / 'char_action.json', "r", encoding='UTF-8') as f:
|
||||
char_action = json.load(f)
|
||||
|
||||
with open(DMG_PATH / 'artifacts_effect.json', "r", encoding='UTF-8') as f:
|
||||
artifacts_effect_map = json.load(f)
|
||||
|
||||
with open(DMG_PATH / 'weapons_effect.json', "r", encoding='UTF-8') as f:
|
||||
weapons_effect_map = json.load(f)
|
||||
|
||||
with open(DMG_PATH / 'char_talent_effect.json', "r", encoding='UTF-8') as f:
|
||||
char_talent_effect_map = json.load(f)
|
||||
|
||||
with open(DMG_PATH / 'char_skill_effect.json', "r", encoding='UTF-8') as f:
|
||||
char_skill_effect_map = json.load(f)
|
||||
|
||||
dmgBar_1 = Image.open(DMG_TEXT_PATH / 'dmgBar_1.png')
|
||||
dmgBar_2 = Image.open(DMG_TEXT_PATH / 'dmgBar_2.png')
|
||||
|
||||
|
||||
def genshin_font_origin(size: int) -> ImageFont:
|
||||
return ImageFont.truetype(str(DMG_TEXT_PATH / 'yuanshen_origin.ttf'), size=size)
|
||||
|
||||
|
||||
async def draw_dmgCacl_img(raw_data: dict) -> Image:
|
||||
char_name = raw_data['avatarName']
|
||||
char_level = int(raw_data['avatarLevel'])
|
||||
weaponName = raw_data['weaponInfo']['weaponName']
|
||||
weaponType = raw_data['weaponInfo']['weaponType']
|
||||
weaponAffix = raw_data['weaponInfo']['weaponAffix']
|
||||
|
||||
skillList = raw_data['avatarSkill']
|
||||
a_skill_name = skillList[0]['skillName'].replace('普通攻击·', '')
|
||||
prop = {}
|
||||
prop['A_skill_level'] = skillList[0]['skillLevel']
|
||||
e_skill_name = skillList[1]['skillName']
|
||||
prop['E_skill_level'] = skillList[1]['skillLevel']
|
||||
q_skill_name = skillList[-1]['skillName']
|
||||
prop['Q_skill_level'] = skillList[-1]['skillLevel']
|
||||
|
||||
enemy_level = char_level
|
||||
skill_add = avatarName2SkillAdd[char_name]
|
||||
for skillAdd_index in range(0, 2):
|
||||
if len(raw_data['talentList']) >= 3 + skillAdd_index * 2:
|
||||
if skill_add[skillAdd_index] == 'E':
|
||||
prop['E_skill_level'] += 3
|
||||
elif skill_add[skillAdd_index] == 'Q':
|
||||
prop['Q_skill_level'] += 3
|
||||
|
||||
fight_prop = raw_data['avatarFightProp']
|
||||
prop['basehp'] = fight_prop['baseHp']
|
||||
prop['baseattack'] = fight_prop['baseAtk']
|
||||
prop['basedefense'] = fight_prop['baseDef']
|
||||
|
||||
prop['hp'] = fight_prop['hp']
|
||||
prop['attack'] = fight_prop['atk']
|
||||
prop['defense'] = fight_prop['def']
|
||||
prop['em'] = fight_prop['elementalMastery']
|
||||
prop['critrate'] = fight_prop['critRate']
|
||||
prop['critdmg'] = fight_prop['critDmg']
|
||||
prop['ce'] = fight_prop['energyRecharge']
|
||||
prop['physicalDmgBonus'] = physicalDmgBonus = fight_prop['physicalDmgBonus']
|
||||
prop['dmgBonus'] = dmgBonus = fight_prop['dmgBonus']
|
||||
prop['healBouns'] = fight_prop['healBonus']
|
||||
prop['shieldBouns'] = 0
|
||||
|
||||
if char_name not in char_action:
|
||||
faild_img = Image.new('RGBA', (950, 1))
|
||||
return faild_img, 0
|
||||
power_list = char_action[char_name]
|
||||
|
||||
for prop_attr in [
|
||||
'dmgBonus',
|
||||
'critrate',
|
||||
'critdmg',
|
||||
'addDmg',
|
||||
'd',
|
||||
'r',
|
||||
'ignoreDef',
|
||||
]:
|
||||
if prop_attr in ['addDmg', 'd', 'r', 'ignoreDef']:
|
||||
prop['{}'.format(prop_attr)] = 0
|
||||
for prop_limit in ['A', 'B', 'C', 'E', 'Q']:
|
||||
prop['{}_{}'.format(prop_limit, prop_attr)] = 0
|
||||
|
||||
for prop_limit in ['A', 'B', 'C', 'E', 'Q']:
|
||||
if weaponType == '法器' or char_name in ['荒泷一斗', '刻晴', '诺艾尔']:
|
||||
prop['{}_dmgBonus'.format(prop_limit)] = dmgBonus
|
||||
elif weaponType == '弓':
|
||||
if prop_limit in ['A', 'C']:
|
||||
prop['{}_dmgBonus'.format(prop_limit)] = physicalDmgBonus
|
||||
elif prop_limit in ['B', 'E', 'Q']:
|
||||
prop['{}_dmgBonus'.format(prop_limit)] = dmgBonus
|
||||
else:
|
||||
if prop_limit in ['A', 'B', 'C']:
|
||||
prop['{}_dmgBonus'.format(prop_limit)] = physicalDmgBonus
|
||||
elif prop_limit in ['E', 'Q']:
|
||||
prop['{}_dmgBonus'.format(prop_limit)] = dmgBonus
|
||||
|
||||
prop['hp_green'] = fight_prop['addHp']
|
||||
prop['attack_green'] = fight_prop['addAtk']
|
||||
prop['defense_green'] = fight_prop['addDef']
|
||||
|
||||
prop['r'] = 0.1
|
||||
prop['a'] = 0
|
||||
prop['g'] = 0
|
||||
prop['k'] = 1
|
||||
|
||||
# 计算圣遗物套装
|
||||
if 'equipSets' in raw_data:
|
||||
equipSets = raw_data['equipSets']
|
||||
else:
|
||||
artifact_set_list = []
|
||||
for i in raw_data['equipList']:
|
||||
artifact_set_list.append(i['aritifactSetsName'])
|
||||
equipSetList = set(artifact_set_list)
|
||||
equipSets = {'type': '', 'set': ''}
|
||||
for equip in equipSetList:
|
||||
if artifact_set_list.count(equip) >= 4:
|
||||
equipSets['type'] = '4'
|
||||
equipSets['set'] = equip
|
||||
break
|
||||
elif artifact_set_list.count(equip) == 1:
|
||||
pass
|
||||
elif artifact_set_list.count(equip) >= 2:
|
||||
equipSets['type'] += '2'
|
||||
equipSets['set'] += '|' + equip
|
||||
|
||||
if equipSets['set'].startswith('|'):
|
||||
equipSets['set'] = equipSets['set'][1:]
|
||||
all_effect = []
|
||||
|
||||
# 计算圣遗物buff
|
||||
if equipSets['type'] == '4':
|
||||
all_effect.append(artifacts_effect_map[equipSets['set']]['4'])
|
||||
elif equipSets['type'] == '2':
|
||||
all_effect.append(artifacts_effect_map[equipSets['set']]['2'])
|
||||
elif equipSets['type'] == '22':
|
||||
if equipSets['set'][-2] == '之':
|
||||
first_artifact = equipSets['set'][-3:]
|
||||
else:
|
||||
first_artifact = equipSets['set'][-2:]
|
||||
second_artifact = equipSets['set'][:2]
|
||||
temp = []
|
||||
temp_number = 0
|
||||
for artifacts_single_effect in artifacts_effect_map:
|
||||
if first_artifact in artifacts_single_effect:
|
||||
temp_number += 1
|
||||
temp.append(artifacts_effect_map[artifacts_single_effect]['2'])
|
||||
if temp_number >= 2:
|
||||
break
|
||||
all_effect.extend(temp)
|
||||
|
||||
# 计算武器buff
|
||||
weapon_effet = weapons_effect_map[weaponName][str(weaponAffix)]
|
||||
all_effect.append(weapon_effet)
|
||||
|
||||
# 计算技能buff
|
||||
for talent in char_talent_effect_map[char_name]:
|
||||
if int(talent) <= len(raw_data['talentList']):
|
||||
all_effect.append(char_talent_effect_map[char_name][talent])
|
||||
else:
|
||||
break
|
||||
|
||||
# 计算角色buff
|
||||
for skill in char_skill_effect_map[char_name]:
|
||||
if int(skill) <= char_level:
|
||||
all_effect.append(char_skill_effect_map[char_name][skill])
|
||||
else:
|
||||
break
|
||||
|
||||
power_effect = ''
|
||||
if 'effect' in power_list:
|
||||
for skill_effect_single in power_list['effect']:
|
||||
skill_effect_name = skill_effect_single['name']
|
||||
skill_effect_value = skill_effect_single['value']
|
||||
skill_effect = skill_effect_single['effect']
|
||||
skill_effect_level = prop['{}_skill_level'.format(skill_effect_name)]
|
||||
skill_effect_value_detail = skill_effect_value[skill_effect_level]
|
||||
if skill_effect[-1] == '}':
|
||||
skill_effect_value_detail = skill_effect_value_detail.replace('%', '')
|
||||
add_limit = skill_effect.split(':')
|
||||
if len(add_limit) == 1:
|
||||
for i in power_list:
|
||||
if i == 'effect':
|
||||
pass
|
||||
else:
|
||||
power_list[i]['power_name'] = (
|
||||
'开{}后 '.format(skill_effect_name)
|
||||
+ power_list[i]['power_name']
|
||||
)
|
||||
else:
|
||||
for i in power_list:
|
||||
if i == 'effect':
|
||||
pass
|
||||
else:
|
||||
add_type = i[0]
|
||||
if '重击' in i or '蓄力' in i:
|
||||
add_type = 'B'
|
||||
elif '冲击伤害' in i:
|
||||
add_type = 'C'
|
||||
if add_type in add_limit[0]:
|
||||
power_list[i]['power_name'] = (
|
||||
'开{}后 '.format(skill_effect_name)
|
||||
+ power_list[i]['power_name']
|
||||
)
|
||||
power_effect = skill_effect.format(skill_effect_value_detail)
|
||||
all_effect.append(power_effect)
|
||||
del power_list['effect']
|
||||
|
||||
sp = []
|
||||
# 计算全部的buff,添加入属性
|
||||
if all_effect:
|
||||
all_effect = ';'.join(all_effect)
|
||||
all_effect_list = all_effect.split(';')
|
||||
for effect in all_effect_list:
|
||||
if effect == '':
|
||||
continue
|
||||
|
||||
effect_limit = ''
|
||||
if ':' in effect:
|
||||
pass
|
||||
else:
|
||||
effect = ':' + effect
|
||||
|
||||
effect_limit = effect.split(':')[0]
|
||||
effect_attr = effect.split(':')[1].split('+')[0]
|
||||
effect_value = effect.split(':')[1].split('+')[-1]
|
||||
|
||||
base_check = True
|
||||
if '%' in effect_value:
|
||||
effect_value_base_on_attr = effect_value.split('%')[-1]
|
||||
effect_value_base_on_value = '%'.join(effect_value.split('%')[:-1])
|
||||
if '%' in effect_value_base_on_value:
|
||||
effect_value_base_on_max_value = effect_value_base_on_value.split(
|
||||
'%'
|
||||
)[0]
|
||||
effect_value_base_on_value = effect_value_base_on_value.split('%')[
|
||||
-1
|
||||
]
|
||||
effect_now_value = (
|
||||
float(effect_value_base_on_value)
|
||||
* prop[effect_value_base_on_attr]
|
||||
)
|
||||
effect_value = (
|
||||
float(effect_value_base_on_max_value)
|
||||
if effect_now_value >= float(effect_value_base_on_max_value)
|
||||
else effect_now_value
|
||||
)
|
||||
else:
|
||||
effect_value = (
|
||||
float(effect_value_base_on_value)
|
||||
* prop[effect_value_base_on_attr]
|
||||
)
|
||||
base_check = False
|
||||
|
||||
if effect_attr != 'em':
|
||||
effect_value = float(effect_value) / 100
|
||||
if effect_attr in ['hp', 'attack', 'defense'] and base_check:
|
||||
effect_value += effect_value * prop['base{}'.format(effect_attr)]
|
||||
else:
|
||||
effect_value = float(effect_value)
|
||||
|
||||
if effect_limit:
|
||||
if '\u4e00' <= effect_limit[0] <= '\u9fff':
|
||||
sp.append(
|
||||
{
|
||||
'effect_name': effect_limit,
|
||||
'effect_attr': effect_attr,
|
||||
'effect_value': effect_value,
|
||||
}
|
||||
)
|
||||
else:
|
||||
for limit in effect_limit:
|
||||
prop['{}_{}'.format(limit, effect_attr)] += effect_value
|
||||
else:
|
||||
prop['{}'.format(effect_attr)] += effect_value
|
||||
|
||||
w = 950
|
||||
h = 40 * (len(power_list) + 1)
|
||||
result_img = Image.new('RGBA', (w, h), (0, 0, 0, 0))
|
||||
for i in range(0, len(power_list) + 1):
|
||||
if i % 2 == 0:
|
||||
result_img.paste(dmgBar_1, (0, i * 40))
|
||||
else:
|
||||
result_img.paste(dmgBar_2, (0, i * 40))
|
||||
|
||||
result_draw = ImageDraw.Draw(result_img)
|
||||
|
||||
text_color = (255, 255, 255)
|
||||
title_color = (255, 255, 100)
|
||||
text_size = genshin_font_origin(28)
|
||||
result_draw.text((45, 22), '角色动作', title_color, text_size, anchor='lm')
|
||||
result_draw.text((460, 22), '暴击伤害', title_color, text_size, anchor='lm')
|
||||
result_draw.text((695, 22), '期望伤害', title_color, text_size, anchor='lm')
|
||||
|
||||
for index, power_name in enumerate(power_list):
|
||||
attack_type = power_name[0]
|
||||
if '重击' in power_name or '瞄准射击' in power_name:
|
||||
attack_type = 'B'
|
||||
elif '冲击伤害' in power_name:
|
||||
attack_type = 'C'
|
||||
elif '段' in power_name and '伤害' in power_name:
|
||||
attack_type = 'A'
|
||||
|
||||
sp_dmgBonus = 0
|
||||
sp_addDmg = 0
|
||||
|
||||
if sp:
|
||||
for sp_single in sp:
|
||||
if sp_single['effect_name'] == power_name[1:]:
|
||||
if sp_single['effect_attr'] == 'dmgBouns':
|
||||
sp_dmgBonus += sp_single['effect_value']
|
||||
elif sp_single['effect_attr'] == 'addDmg':
|
||||
sp_addDmg += sp_single['effect_value']
|
||||
|
||||
if '攻击' in power_list[power_name]['type']:
|
||||
effect_prop = prop['attack']
|
||||
elif '生命值' in power_list[power_name]['type']:
|
||||
effect_prop = prop['hp']
|
||||
elif '防御' in power_list[power_name]['type']:
|
||||
effect_prop = prop['defense']
|
||||
power = power_list[power_name]['value'][
|
||||
prop['{}_skill_level'.format(power_name[0])]
|
||||
]
|
||||
power_plus = power_list[power_name]['plus']
|
||||
|
||||
power_percent, power_value = await power_to_value(power, power_plus)
|
||||
|
||||
dmgBonus_cal = prop['{}_dmgBonus'.format(attack_type)] + sp_dmgBonus
|
||||
critdmg_cal = prop['critdmg'] + prop['{}_critdmg'.format(attack_type)]
|
||||
critrate_cal = prop['critrate'] + prop['{}_critrate'.format(attack_type)]
|
||||
d_cal = (char_level + 100) / (
|
||||
(char_level + 100)
|
||||
+ (1 - prop['{}_d'.format(attack_type)])
|
||||
* (1 - prop['{}_ignoreDef'.format(attack_type)])
|
||||
* (enemy_level + 100)
|
||||
)
|
||||
r = 1 - prop['r']
|
||||
e_dmg = prop['k'] * (1 + (2.78 * prop['em']) / (prop['em'] + 1400) + prop['a'])
|
||||
add_dmg = prop['{}_addDmg'.format(attack_type)] + sp_addDmg
|
||||
|
||||
if '治疗' in power_name:
|
||||
crit_dmg = avg_dmg = (effect_prop * power_percent + power_value) * (
|
||||
1 + prop['healBouns']
|
||||
)
|
||||
elif '护盾' in power_name:
|
||||
crit_dmg = avg_dmg = (effect_prop * power_percent + power_value) * (
|
||||
1 + prop['shieldBouns']
|
||||
)
|
||||
elif '提升' in power_name or '提高' in power_name:
|
||||
continue
|
||||
else:
|
||||
crit_dmg = (effect_prop * power_percent + power_value) * (
|
||||
1 + critdmg_cal
|
||||
) * (1 + dmgBonus_cal) * d_cal * r + add_dmg
|
||||
avg_dmg = (
|
||||
(crit_dmg - add_dmg) * critrate_cal
|
||||
+ (1 - critrate_cal)
|
||||
* (effect_prop * power_percent + power_value)
|
||||
* (1 + dmgBonus_cal)
|
||||
* d_cal
|
||||
* r
|
||||
+ add_dmg
|
||||
)
|
||||
|
||||
result_draw.text(
|
||||
(45, 22 + (index + 1) * 40),
|
||||
power_list[power_name]['power_name'],
|
||||
text_color,
|
||||
text_size,
|
||||
anchor='lm',
|
||||
)
|
||||
result_draw.text(
|
||||
(460, 22 + (index + 1) * 40),
|
||||
str(round(crit_dmg)),
|
||||
text_color,
|
||||
text_size,
|
||||
anchor='lm',
|
||||
)
|
||||
result_draw.text(
|
||||
(695, 22 + (index + 1) * 40),
|
||||
str(round(avg_dmg)),
|
||||
text_color,
|
||||
text_size,
|
||||
anchor='lm',
|
||||
)
|
||||
|
||||
return result_img, len(power_list) + 2
|
||||
|
||||
|
||||
async def power_to_value(power: str, power_plus: int) -> List:
|
||||
"""
|
||||
将power转换为value
|
||||
"""
|
||||
if '+' in power:
|
||||
power_percent = (float(power.split('+')[0].replace('%', '')) / 100) * power_plus
|
||||
power_value = power.split('+')[1]
|
||||
if '%' in power_value:
|
||||
power_percent += float(power_value.replace('%', '')) / 100 * power_plus
|
||||
power_value = 0
|
||||
else:
|
||||
power_value = float(power_value)
|
||||
else:
|
||||
power_percent = float(power.replace('%', '')) / 100 * power_plus
|
||||
power_value = 0
|
||||
|
||||
return power_percent, power_value
|
BIN
enkaToData/dmgCalc/texture2d/dmgBar_1.png
Normal file
After Width: | Height: | Size: 899 B |
BIN
enkaToData/dmgCalc/texture2d/dmgBar_2.png
Normal file
After Width: | Height: | Size: 890 B |
BIN
enkaToData/dmgCalc/texture2d/yuanshen_origin.ttf
Normal file
940
enkaToData/dmgCalc/weapons_effect.json
Normal file
@ -0,0 +1,940 @@
|
||||
{
|
||||
"恶王丸": {
|
||||
"1": "Q:dmgBonus+40",
|
||||
"2": "Q:dmgBonus+50",
|
||||
"3": "Q:dmgBonus+60",
|
||||
"4": "Q:dmgBonus+70",
|
||||
"5": "Q:dmgBonus+80"
|
||||
},
|
||||
"暗巷猎手": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"天目影打刀": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"阿莫斯之弓": {
|
||||
"1": "AB:dmgBonus+52",
|
||||
"2": "AB:dmgBonus+65",
|
||||
"3": "AB:dmgBonus+78",
|
||||
"4": "AB:dmgBonus+91",
|
||||
"5": "AB:dmgBonus+104"
|
||||
},
|
||||
"学徒笔记": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"若水": {
|
||||
"1": "dmgBonus+20",
|
||||
"2": "dmgBonus+25",
|
||||
"3": "dmgBonus+30",
|
||||
"4": "dmgBonus+35",
|
||||
"5": "dmgBonus+40"
|
||||
},
|
||||
"风鹰剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"新手长枪": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"黑岩绯玉": {
|
||||
"1": "attack+36",
|
||||
"2": "attack+45",
|
||||
"3": "attack+54",
|
||||
"4": "attack+63",
|
||||
"5": "attack+72"
|
||||
},
|
||||
"黑岩长剑": {
|
||||
"1": "attack+36",
|
||||
"2": "attack+45",
|
||||
"3": "attack+54",
|
||||
"4": "attack+63",
|
||||
"5": "attack+72"
|
||||
},
|
||||
"黑岩刺枪": {
|
||||
"1": "attack+36",
|
||||
"2": "attack+45",
|
||||
"3": "attack+54",
|
||||
"4": "attack+63",
|
||||
"5": "attack+72"
|
||||
},
|
||||
"黑岩斩刀": {
|
||||
"1": "attack+36",
|
||||
"2": "attack+45",
|
||||
"3": "attack+54",
|
||||
"4": "attack+63",
|
||||
"5": "attack+72"
|
||||
},
|
||||
"黑岩战弓": {
|
||||
"1": "attack+36",
|
||||
"2": "attack+45",
|
||||
"3": "attack+54",
|
||||
"4": "attack+63",
|
||||
"5": "attack+72"
|
||||
},
|
||||
"黑缨枪": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"沐浴龙血的剑": {
|
||||
"1": "dmgBonus+12",
|
||||
"2": "dmgBonus+15",
|
||||
"3": "dmgBonus+18",
|
||||
"4": "dmgBonus+21",
|
||||
"5": "dmgBonus+24"
|
||||
},
|
||||
"息灾": {
|
||||
"1": "attack+19.2",
|
||||
"2": "attack+24",
|
||||
"3": "attack+28.8",
|
||||
"4": "attack+33.6",
|
||||
"5": "attack+38.4"
|
||||
},
|
||||
"辰砂之纺锤": {
|
||||
"1": "E:addDmg+40%defense",
|
||||
"2": "E:addDmg+50%defense",
|
||||
"3": "E:addDmg+60%defense",
|
||||
"4": "E:addDmg+70%defense",
|
||||
"5": "E:addDmg+80%defense"
|
||||
},
|
||||
"钢轮弓": {
|
||||
"1": "attack+16",
|
||||
"2": "attack+20",
|
||||
"3": "attack+24",
|
||||
"4": "attack+28",
|
||||
"5": "attack+32"
|
||||
},
|
||||
"冷刃": {
|
||||
"1": "dmgBonus+12",
|
||||
"2": "dmgBonus+15",
|
||||
"3": "dmgBonus+18",
|
||||
"4": "dmgBonus+21",
|
||||
"5": "dmgBonus+24"
|
||||
},
|
||||
"流月针": {
|
||||
"1": "AB:addDmg+20%attack",
|
||||
"2": "AB:addDmg+25%attack",
|
||||
"3": "AB:addDmg+30%attack",
|
||||
"4": "AB:addDmg+35%attack",
|
||||
"5": "AB:addDmg+40%attack"
|
||||
},
|
||||
"暗铁剑": {
|
||||
"1": "attack+20",
|
||||
"2": "attack+25",
|
||||
"3": "attack+30",
|
||||
"4": "attack+35",
|
||||
"5": "attack+40"
|
||||
},
|
||||
"决斗之枪": {
|
||||
"1": "attack+24",
|
||||
"2": "attack+30",
|
||||
"3": "attack+36",
|
||||
"4": "attack+42",
|
||||
"5": "attack+48"
|
||||
},
|
||||
"以理服人": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"嘟嘟可故事集": {
|
||||
"1": "B:dmgBonus+16;attack+8",
|
||||
"2": "B:dmgBonus+20;attack+10",
|
||||
"3": "B:dmgBonus+24;attack+12",
|
||||
"4": "B:dmgBonus+28;attack+14",
|
||||
"5": "B:dmgBonus+32;attack+16"
|
||||
},
|
||||
"匣里灭辰": {
|
||||
"1": "dmgBonus+20",
|
||||
"2": "dmgBonus+24",
|
||||
"3": "dmgBonus+28",
|
||||
"4": "dmgBonus+32",
|
||||
"5": "dmgBonus+36"
|
||||
},
|
||||
"龙脊长枪": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"无锋剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"终末嗟叹之诗": {
|
||||
"1": "em+100;attack+20",
|
||||
"2": "em+125;attack+25",
|
||||
"3": "em+150;attack+30",
|
||||
"4": "em+175;attack+35",
|
||||
"5": "em+200;attack+40"
|
||||
},
|
||||
"翡玉法球": {
|
||||
"1": "attack+20",
|
||||
"2": "attack+25",
|
||||
"3": "attack+30",
|
||||
"4": "attack+35",
|
||||
"5": "attack+40"
|
||||
},
|
||||
"薙草之稻光": {
|
||||
"1": "ce+30",
|
||||
"2": "ce+35",
|
||||
"3": "ce+40",
|
||||
"4": "ce+45",
|
||||
"5": "ce+50"
|
||||
},
|
||||
"不灭月华": {
|
||||
"1": "A:addDmg+1%hp",
|
||||
"2": "A:addDmg+1.5%hp",
|
||||
"3": "A:addDmg+2%hp",
|
||||
"4": "A:addDmg+2.5%hp",
|
||||
"5": "A:addDmg+3%hp"
|
||||
},
|
||||
"昭心": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"落霞": {
|
||||
"1": "dmgBonus+10",
|
||||
"2": "dmgBonus+12.5",
|
||||
"3": "dmgBonus+15",
|
||||
"4": "dmgBonus+17.5",
|
||||
"5": "dmgBonus+20"
|
||||
},
|
||||
"西风秘典": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"西风大剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"西风长枪": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"西风剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"西风猎弓": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"铁影阔剑": {
|
||||
"1": "B:dmgBonus+30",
|
||||
"2": "B:dmgBonus+35",
|
||||
"3": "B:dmgBonus+40",
|
||||
"4": "B:dmgBonus+45",
|
||||
"5": "B:dmgBonus+50"
|
||||
},
|
||||
"腐殖之剑": {
|
||||
"1": "E:dmgBonus+16;E:critrate+6",
|
||||
"2": "E:dmgBonus+20;E:critrate+7.5",
|
||||
"3": "E:dmgBonus+24;E:critrate+9",
|
||||
"4": "E:dmgBonus+28;E:critrate+10.5",
|
||||
"5": "E:dmgBonus+32;E:critrate+12"
|
||||
},
|
||||
"吃虎鱼刀": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"苍古自由之誓": {
|
||||
"1": "dmgBonus+10;ABC:dmgBonus+16;attack+20",
|
||||
"2": "dmgBonus+12.5;ABC:dmgBonus+20;attack+25",
|
||||
"3": "dmgBonus+15;ABC:dmgBonus+24;attack+30",
|
||||
"4": "dmgBonus+17.5;ABC:dmgBonus+28;attack+35",
|
||||
"5": "dmgBonus+20;ABC:dmgBonus+32;attack+40"
|
||||
},
|
||||
"忍冬之果": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"白辰之环": {
|
||||
"1": "dmgBonus+10",
|
||||
"2": "dmgBonus+12.5",
|
||||
"3": "dmgBonus+15",
|
||||
"4": "dmgBonus+17.5",
|
||||
"5": "dmgBonus+20"
|
||||
},
|
||||
"钺矛": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"破魔之弓": {
|
||||
"1": "A:dmgBonus+32;B:dmgBonus+24",
|
||||
"2": "A:dmgBonus+40;B:dmgBonus+30",
|
||||
"3": "A:dmgBonus+48;B:dmgBonus+36",
|
||||
"4": "A:dmgBonus+56;B:dmgBonus+42",
|
||||
"5": "A:dmgBonus+64;B:dmgBonus+48"
|
||||
},
|
||||
"波乱月白经津": {
|
||||
"1": "A:dmgBonus+40",
|
||||
"2": "A:dmgBonus+50",
|
||||
"3": "A:dmgBonus+60",
|
||||
"4": "A:dmgBonus+70",
|
||||
"5": "A:dmgBonus+80"
|
||||
},
|
||||
"黎明神剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"猎弓": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"铁尖枪": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"铁蜂刺": {
|
||||
"1": "dmgBonus+6",
|
||||
"2": "dmgBonus+7.5",
|
||||
"3": "dmgBonus+9",
|
||||
"4": "dmgBonus+10.5",
|
||||
"5": "dmgBonus+12"
|
||||
},
|
||||
"神乐之真意": {
|
||||
"1": "E:dmgBonus+36;dmgBonus+12",
|
||||
"2": "E:dmgBonus+45;dmgBonus+15",
|
||||
"3": "E:dmgBonus+54;dmgBonus+18",
|
||||
"4": "E:dmgBonus+63;dmgBonus+21",
|
||||
"5": "E:dmgBonus+72;dmgBonus+24"
|
||||
},
|
||||
"桂木斩长正": {
|
||||
"1": "E:dmgBonus+6",
|
||||
"2": "E:dmgBonus+7.5",
|
||||
"3": "E:dmgBonus+9",
|
||||
"4": "E:dmgBonus+10.5",
|
||||
"5": "E:dmgBonus+12"
|
||||
},
|
||||
"喜多院十文字": {
|
||||
"1": "E:dmgBonus+6",
|
||||
"2": "E:dmgBonus+7.5",
|
||||
"3": "E:dmgBonus+9",
|
||||
"4": "E:dmgBonus+10.5",
|
||||
"5": "E:dmgBonus+12"
|
||||
},
|
||||
"匣里龙吟": {
|
||||
"1": "dmgBonus+20",
|
||||
"2": "dmgBonus+24",
|
||||
"3": "dmgBonus+28",
|
||||
"4": "dmgBonus+32",
|
||||
"5": "dmgBonus+36"
|
||||
},
|
||||
" 千岩古剑": {
|
||||
"1": "attack+21;critrate+9",
|
||||
"2": "attack+24;critrate+12",
|
||||
"3": "attack+27;critrate+15",
|
||||
"4": "attack+30;critrate+18",
|
||||
"5": "attack+33;critrate+21"
|
||||
},
|
||||
"千岩长枪": {
|
||||
"1": "attack+21;critrate+9",
|
||||
"2": "attack+24;critrate+12",
|
||||
"3": "attack+27;critrate+15",
|
||||
"4": "attack+30;critrate+18",
|
||||
"5": "attack+33;critrate+21"
|
||||
},
|
||||
"四风原典": {
|
||||
"1": "dmgBonus+32",
|
||||
"2": "dmgBonus+40",
|
||||
"3": "dmgBonus+48",
|
||||
"4": "dmgBonus+56",
|
||||
"5": "dmgBonus+64"
|
||||
},
|
||||
"衔珠海皇": {
|
||||
"1": "Q:dmgBonus+12",
|
||||
"2": "Q:dmgBonus+15",
|
||||
"3": "Q:dmgBonus+18",
|
||||
"4": "Q:dmgBonus+21",
|
||||
"5": "Q:dmgBonus+24"
|
||||
},
|
||||
"魔导绪论": {
|
||||
"1": "dmgBonus+12",
|
||||
"2": "dmgBonus+15",
|
||||
"3": "dmgBonus+18",
|
||||
"4": "dmgBonus+21",
|
||||
"5": "dmgBonus+24"
|
||||
},
|
||||
"万国诸海图谱": {
|
||||
"1": "dmgBonus+16",
|
||||
"2": "dmgBonus+20",
|
||||
"3": "dmgBonus+24",
|
||||
"4": "dmgBonus+28",
|
||||
"5": "dmgBonus+32"
|
||||
},
|
||||
"尘世之锁": {
|
||||
"1": "shieldBouns+20;attack+20",
|
||||
"2": "shieldBouns+25;attack+25",
|
||||
"3": "shieldBouns+30;attack+30",
|
||||
"4": "shieldBouns+35;attack+35",
|
||||
"5": "shieldBouns+40;attack+40"
|
||||
},
|
||||
"信使": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"雾切之回光": {
|
||||
"1": "dmgBonus+28",
|
||||
"2": "dmgBonus+35",
|
||||
"3": "dmgBonus+42",
|
||||
"4": "dmgBonus+49",
|
||||
"5": "dmgBonus+56"
|
||||
},
|
||||
"幽夜华尔兹": {
|
||||
"1": "AE:dmgBonus+20",
|
||||
"2": "AE:dmgBonus+25",
|
||||
"3": "AE:dmgBonus+30",
|
||||
"4": "AE:dmgBonus+35",
|
||||
"5": "AE:dmgBonus+40"
|
||||
},
|
||||
"曚云之月": {
|
||||
"1": "Q:dmgBonus+40",
|
||||
"2": "Q:dmgBonus+50",
|
||||
"3": "Q:dmgBonus+60",
|
||||
"4": "Q:dmgBonus+70",
|
||||
"5": "Q:dmgBonus+80"
|
||||
},
|
||||
"证誓之明瞳": {
|
||||
"1": "ce+24",
|
||||
"2": "ce+30",
|
||||
"3": "ce+36",
|
||||
"4": "ce+42",
|
||||
"5": "ce+48"
|
||||
},
|
||||
"佣兵重剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"异世界行记": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"口袋魔导书": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"冬极白星": {
|
||||
"1": "EQ:dmgBonus+12;attack+48",
|
||||
"2": "EQ:dmgBonus+15;attack+60",
|
||||
"3": "EQ:dmgBonus+18;attack+72",
|
||||
"4": "EQ:dmgBonus+21;attack+84",
|
||||
"5": "EQ:dmgBonus+24;attack+96"
|
||||
},
|
||||
"掠食者": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"磐岩结绿": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"和璞鸢": {
|
||||
"1": "attack+22.4;dmgBonus+12",
|
||||
"2": "attack+27.3;dmgBonus+15",
|
||||
"3": "attack+32.2;dmgBonus+18",
|
||||
"4": "attack+37.1;dmgBonus+21",
|
||||
"5": "attack+42;dmgBonus+24"
|
||||
},
|
||||
"试作金珀": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"试作古华": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"试作澹月": {
|
||||
"1": "attack+36",
|
||||
"2": "attack+45",
|
||||
"3": "attack+54",
|
||||
"4": "attack+63",
|
||||
"5": "attack+72"
|
||||
},
|
||||
"试作斩岩": {
|
||||
"1": "attack+16;defense+16",
|
||||
"2": "attack+20;defense+20",
|
||||
"3": "attack+24;defense+24",
|
||||
"4": "attack+28;defense+28",
|
||||
"5": "attack+32;defense+32"
|
||||
},
|
||||
"试作星镰": {
|
||||
"1": "AB:dmgBonus+16",
|
||||
"2": "AB:dmgBonus+20",
|
||||
"3": "AB:dmgBonus+24",
|
||||
"4": "AB:dmgBonus+28",
|
||||
"5": "AB:dmgBonus+32"
|
||||
},
|
||||
"雨裁": {
|
||||
"1": "dmgBonus+20",
|
||||
"2": "dmgBonus+24",
|
||||
"3": "dmgBonus+28",
|
||||
"4": "dmgBonus+32",
|
||||
"5": "dmgBonus+36"
|
||||
},
|
||||
"鸦羽弓": {
|
||||
"1": "dmgBonus+12",
|
||||
"2": "dmgBonus+15",
|
||||
"3": "dmgBonus+18",
|
||||
"4": "dmgBonus+21",
|
||||
"5": "dmgBonus+24"
|
||||
},
|
||||
"反曲弓": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"赤角石溃杵": {
|
||||
"1": "AB:addDmg+40%defense",
|
||||
"2": "AB:addDmg+50%defense",
|
||||
"3": "AB:addDmg+60%defense",
|
||||
"4": "AB:addDmg+70%defense",
|
||||
"5": "AB:addDmg+80%defense"
|
||||
},
|
||||
"宗室长弓": {
|
||||
"1": "critrate+14",
|
||||
"2": "critrate+16",
|
||||
"3": "critrate+18",
|
||||
"4": "critrate+22",
|
||||
"5": "critrate+24"
|
||||
},
|
||||
"宗室大剑": {
|
||||
"1": "critrate+14",
|
||||
"2": "critrate+16",
|
||||
"3": "critrate+18",
|
||||
"4": "critrate+22",
|
||||
"5": "critrate+24"
|
||||
},
|
||||
"宗室秘法录": {
|
||||
"1": "critrate+14",
|
||||
"2": "critrate+16",
|
||||
"3": "critrate+18",
|
||||
"4": "critrate+22",
|
||||
"5": "critrate+24"
|
||||
},
|
||||
"宗室长剑": {
|
||||
"1": "critrate+14",
|
||||
"2": "critrate+16",
|
||||
"3": "critrate+18",
|
||||
"4": "critrate+22",
|
||||
"5": "critrate+24"
|
||||
},
|
||||
"宗室猎枪": {
|
||||
"1": "critrate+14",
|
||||
"2": "critrate+16",
|
||||
"3": "critrate+18",
|
||||
"4": "critrate+22",
|
||||
"5": "critrate+24"
|
||||
},
|
||||
"弓藏": {
|
||||
"1": "A:dmgBonus+40",
|
||||
"2": "A:dmgBonus+50",
|
||||
"3": "A:dmgBonus+60",
|
||||
"4": "A:dmgBonus+70",
|
||||
"5": "A:dmgBonus+80"
|
||||
},
|
||||
"祭礼弓": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"祭礼残章": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"祭礼大剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"祭礼剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"历练的猎弓": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"螭骨剑": {
|
||||
"1": "dmgBonus+30",
|
||||
"2": "dmgBonus+35",
|
||||
"3": "dmgBonus+40",
|
||||
"4": "dmgBonus+45",
|
||||
"5": "dmgBonus+50"
|
||||
},
|
||||
"神射手之誓": {
|
||||
"1": "B:dmgBonus+24",
|
||||
"2": "B:dmgBonus+30",
|
||||
"3": "B:dmgBonus+36",
|
||||
"4": "B:dmgBonus+42",
|
||||
"5": "B:dmgBonus+48"
|
||||
},
|
||||
"银剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"飞天大御剑": {
|
||||
"1": "attack+24",
|
||||
"2": "attack+28",
|
||||
"3": "attack+32",
|
||||
"4": "attack+36",
|
||||
"5": "attack+40"
|
||||
},
|
||||
"飞天御剑": {
|
||||
"1": "attack+12",
|
||||
"2": "attack+15",
|
||||
"3": "attack+18",
|
||||
"4": "attack+21",
|
||||
"5": "attack+24"
|
||||
},
|
||||
"天空之卷": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"天空之刃": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"天空之翼": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"天空之傲": {
|
||||
"1": "dmgBonus+8",
|
||||
"2": "dmgBonus+10",
|
||||
"3": "dmgBonus+12",
|
||||
"4": "dmgBonus+14",
|
||||
"5": "dmgBonus+16"
|
||||
},
|
||||
"天空之脊": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"弹弓": {
|
||||
"1": "AB:dmgBonus+36",
|
||||
"2": "AB:dmgBonus+42",
|
||||
"3": "AB:dmgBonus+48",
|
||||
"4": "AB:dmgBonus+54",
|
||||
"5": "AB:dmgBonus+60"
|
||||
},
|
||||
"雪葬的星银": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"匣里日月": {
|
||||
"1": "AEQ:dmgBonus+20",
|
||||
"2": "AEQ:dmgBonus+25",
|
||||
"3": "AEQ:dmgBonus+30",
|
||||
"4": "AEQ:dmgBonus+35",
|
||||
"5": "AEQ:dmgBonus+40"
|
||||
},
|
||||
"松籁响起之时": {
|
||||
"1": "attack+20",
|
||||
"2": "attack+25",
|
||||
"3": "attack+30",
|
||||
"4": "attack+35",
|
||||
"5": "attack+40"
|
||||
},
|
||||
"护摩之杖": {
|
||||
"1": "attack+1.8%hp",
|
||||
"2": "attack+2.2%hp",
|
||||
"3": "attack+2.6%hp",
|
||||
"4": "attack+3.0%hp",
|
||||
"5": "attack+3.4%hp"
|
||||
},
|
||||
"斫峰之刃": {
|
||||
"1": "shieldBouns+20;attack+20",
|
||||
"2": "shieldBouns+25;attack+25",
|
||||
"3": "shieldBouns+30;attack+30",
|
||||
"4": "shieldBouns+35;attack+35",
|
||||
"5": "shieldBouns+40;attack+40"
|
||||
},
|
||||
"降临之剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"暗巷闪光": {
|
||||
"1": "dmgBonus+12",
|
||||
"2": "dmgBonus+15",
|
||||
"3": "dmgBonus+18",
|
||||
"4": "dmgBonus+21",
|
||||
"5": "dmgBonus+24"
|
||||
},
|
||||
"钟剑": {
|
||||
"1": "dmgBonus+12",
|
||||
"2": "dmgBonus+15",
|
||||
"3": "dmgBonus+18",
|
||||
"4": "dmgBonus+21",
|
||||
"5": "dmgBonus+24"
|
||||
},
|
||||
"黑剑": {
|
||||
"1": "AB:dmgBonus+20",
|
||||
"2": "AB:dmgBonus+25",
|
||||
"3": "AB:dmgBonus+30",
|
||||
"4": "AB:dmgBonus+35",
|
||||
"5": "AB:dmgBonus+40"
|
||||
},
|
||||
"「渔获」": {
|
||||
"1": "Q:dmgBonus+16;Q:critrate+6",
|
||||
"2": "Q:dmgBonus+20;Q:critrate+7.5",
|
||||
"3": "Q:dmgBonus+24;Q:critrate+9",
|
||||
"4": "Q:dmgBonus+28;Q:critrate+10.5",
|
||||
"5": "Q:dmgBonus+32;Q:critrate+12"
|
||||
},
|
||||
"笛剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"绝弦": {
|
||||
"1": "EQ:dmgBonus+24",
|
||||
"2": "EQ:dmgBonus+30",
|
||||
"3": "EQ:dmgBonus+36",
|
||||
"4": "EQ:dmgBonus+42",
|
||||
"5": "EQ:dmgBonus+48"
|
||||
},
|
||||
"无工之剑": {
|
||||
"1": "shieldBouns+20;attack+20",
|
||||
"2": "shieldBouns+25;attack+25",
|
||||
"3": "shieldBouns+30;attack+30",
|
||||
"4": "shieldBouns+35;attack+35",
|
||||
"5": "shieldBouns+40;attack+40"
|
||||
},
|
||||
"苍翠猎弓": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"流浪乐章": {
|
||||
"1": "dmgBonus+48",
|
||||
"2": "dmgBonus+60",
|
||||
"3": "dmgBonus+72",
|
||||
"4": "dmgBonus+84",
|
||||
"5": "dmgBonus+96"
|
||||
},
|
||||
"讨龙英杰谭": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"飞雷之弦振": {
|
||||
"1": "A:dmgBonus+40",
|
||||
"2": "A:dmgBonus+50",
|
||||
"3": "A:dmgBonus+60",
|
||||
"4": "A:dmgBonus+70",
|
||||
"5": "A:dmgBonus+80"
|
||||
},
|
||||
"旅行剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"甲级宝珏": {
|
||||
"1": "attack+12",
|
||||
"2": "attack+14",
|
||||
"3": "attack+16",
|
||||
"4": "attack+18",
|
||||
"5": "attack+20"
|
||||
},
|
||||
"贯虹之槊": {
|
||||
"1": "shieldBouns+20;attack+20",
|
||||
"2": "shieldBouns+25;attack+25",
|
||||
"3": "shieldBouns+30;attack+30",
|
||||
"4": "shieldBouns+35;attack+35",
|
||||
"5": "shieldBouns+40;attack+40"
|
||||
},
|
||||
"训练大剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"断浪长鳍": {
|
||||
"1": "Q:dmgBonus+40",
|
||||
"2": "Q:dmgBonus+50",
|
||||
"3": "Q:dmgBonus+60",
|
||||
"4": "Q:dmgBonus+70",
|
||||
"5": "Q:dmgBonus+80"
|
||||
},
|
||||
"白影剑": {
|
||||
"1": "attack+24;defense+24",
|
||||
"2": "attack+30;defense+30",
|
||||
"3": "attack+36;defense+36",
|
||||
"4": "attack+42;defense+42",
|
||||
"5": "attack+46;defense+46"
|
||||
},
|
||||
"白铁大剑": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"白缨枪": {
|
||||
"1": "A:dmgBonus+24",
|
||||
"2": "A:dmgBonus+30",
|
||||
"3": "A:dmgBonus+36",
|
||||
"4": "A:dmgBonus+42",
|
||||
"5": "A:dmgBonus+48"
|
||||
},
|
||||
"风花之颂": {
|
||||
"1": "attack+16",
|
||||
"2": "attack+20",
|
||||
"3": "attack+24",
|
||||
"4": "attack+28",
|
||||
"5": "attack+32"
|
||||
},
|
||||
"暗巷的酒与诗": {
|
||||
"1": "attack+20",
|
||||
"2": "attack+25",
|
||||
"3": "attack+30",
|
||||
"4": "attack+35",
|
||||
"5": "attack+40"
|
||||
},
|
||||
"狼的末路": {
|
||||
"1": "",
|
||||
"2": "",
|
||||
"3": "",
|
||||
"4": "",
|
||||
"5": ""
|
||||
},
|
||||
"笼钓瓶一心": {
|
||||
"1": "attack+15",
|
||||
"2": "attack+15",
|
||||
"3": "attack+15",
|
||||
"4": "attack+15",
|
||||
"5": "attack+15"
|
||||
}
|
||||
}
|
762
enkaToData/drawCharCard.py
Normal file
@ -0,0 +1,762 @@
|
||||
import math
|
||||
import json,asyncio
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from typing import List, Optional, Tuple
|
||||
from base64 import b64encode
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont, ImageChops
|
||||
from httpx import get
|
||||
from nonebot import logger
|
||||
|
||||
from .dmgCalc.dmgCalc import *
|
||||
|
||||
R_PATH = Path(__file__).parents[0]
|
||||
TEXT_PATH = R_PATH / 'texture2D'
|
||||
ICON_PATH = R_PATH / 'icon'
|
||||
GACHA_PATH = R_PATH / 'gachaImg'
|
||||
PLAYER_PATH = R_PATH / 'player'
|
||||
RELIC_PATH = R_PATH / 'relicIcon'
|
||||
MAP_PATH = R_PATH / 'map'
|
||||
ETC_PATH = R_PATH / 'etc'
|
||||
|
||||
COLOR_MAP = {'Anemo' : (43, 170, 163), 'Cryo': (97, 168, 202), 'Dendro': (84, 169, 62),
|
||||
'Electro': (150, 62, 169), 'Geo': (169, 143, 62), 'Hydro': (66, 98, 182), 'Pyro': (169, 62, 67)}
|
||||
|
||||
SCORE_MAP = {'暴击率': 2, '暴击伤害': 1, '元素精通': 0.25, '元素充能效率': 0.65, '百分比血量': 0.86,
|
||||
'百分比攻击力': 1, '百分比防御力': 0.7, '血量': 0.014, '攻击力': 0.12, '防御力': 0.18}
|
||||
|
||||
VALUE_MAP = {'攻击力': 4.975, '血量': 4.975, '防御力': 6.2, '元素精通': 19.75,
|
||||
'元素充能效率': 5.5, '暴击率': 3.3, '暴击伤害': 6.6}
|
||||
|
||||
# 引入ValueMap
|
||||
with open(ETC_PATH / 'ValueAttrMap.json', 'r', encoding='UTF-8') as f:
|
||||
ATTR_MAP = json.load(f)
|
||||
|
||||
# 引入dmgMap
|
||||
with open(ETC_PATH / 'dmgMap.json', 'r', encoding='UTF-8') as f:
|
||||
dmgMap = json.load(f)
|
||||
|
||||
# 引入offset
|
||||
with open(ETC_PATH / 'avatarOffsetMap.json', 'r', encoding='UTF-8') as f:
|
||||
avatarOffsetMap = json.load(f)
|
||||
|
||||
# 引入offset2
|
||||
with open(ETC_PATH / 'avatarCardOffsetMap.json', 'r', encoding='UTF-8') as f:
|
||||
avatarCardOffsetMap = json.load(f)
|
||||
|
||||
def genshin_font_origin(size: int) -> ImageFont:
|
||||
return ImageFont.truetype(str(TEXT_PATH / 'yuanshen_origin.ttf'), size=size)
|
||||
|
||||
|
||||
def get_star_png(star: int) -> Image:
|
||||
png = Image.open(TEXT_PATH / 's-{}.png'.format(str(star)))
|
||||
return png
|
||||
|
||||
|
||||
def strLenth(r: str, size: int, limit: int = 540) -> str:
|
||||
result = ''
|
||||
temp = 0
|
||||
for i in r:
|
||||
if temp >= limit:
|
||||
result += '\n' + i
|
||||
temp = 0
|
||||
else:
|
||||
result += i
|
||||
|
||||
if i.isdigit():
|
||||
temp += round(size / 10 * 6)
|
||||
elif i == '/':
|
||||
temp += round(size / 10 * 2.2)
|
||||
elif i == '.':
|
||||
temp += round(size / 10 * 3)
|
||||
elif i == '%':
|
||||
temp += round(size / 10 * 9.4)
|
||||
else:
|
||||
temp += size
|
||||
return result
|
||||
|
||||
|
||||
async def get_artifacts_score(subName: str, subValue: int) -> int:
|
||||
score = subValue * SCORE_MAP[subName]
|
||||
return score
|
||||
|
||||
async def get_artifacts_value(subName: str, subValue: int, baseAtk: int,
|
||||
baseHp: int, baseDef: int, charName: str) -> int:
|
||||
if charName not in ATTR_MAP:
|
||||
ATTR_MAP[charName] = ['攻击力', '暴击率', '暴击伤害']
|
||||
if subName in ATTR_MAP[charName] and subName in ['血量', '防御力', '攻击力']:
|
||||
if subName == '血量':
|
||||
base = (subValue / baseHp) * 100
|
||||
elif subName == '防御力':
|
||||
base = (subValue / baseDef) * 100
|
||||
elif subName == '攻击力':
|
||||
base = (subValue / baseAtk) * 100
|
||||
value = float('{:.2f}'.format(base / VALUE_MAP[subName]))
|
||||
elif subName in ['百分比血量', '百分比防御力', '百分比攻击力']:
|
||||
subName = subName.replace('百分比', '')
|
||||
if subName in ATTR_MAP[charName]:
|
||||
value = float('{:.2f}'.format(subValue / VALUE_MAP[subName]))
|
||||
else:
|
||||
return 0
|
||||
else:
|
||||
if subName in ATTR_MAP[charName]:
|
||||
value = float('{:.2f}'.format(subValue / VALUE_MAP[subName]))
|
||||
else:
|
||||
value = 0
|
||||
|
||||
if charName == '胡桃' and subName == '攻击力':
|
||||
value = value * 0.4
|
||||
return value
|
||||
|
||||
async def get_all_artifacts_value(raw_data: dict, baseHp: int, baseAtk: int, baseDef: int, char_name: str) -> int:
|
||||
artifactsValue = 0
|
||||
for aritifact in raw_data:
|
||||
for i in aritifact['reliquarySubstats']:
|
||||
subName = i['statName']
|
||||
subValue = i['statValue']
|
||||
value_temp = await get_artifacts_value(subName, subValue, baseAtk, baseHp, baseDef, char_name)
|
||||
artifactsValue += value_temp
|
||||
return artifactsValue
|
||||
|
||||
async def get_first_main(mainName: str) -> str:
|
||||
if '伤害加成' in mainName:
|
||||
equipMain = mainName[0]
|
||||
elif '元素' in mainName:
|
||||
equipMain = mainName[2]
|
||||
elif '百分比' in mainName:
|
||||
if '血量' in mainName:
|
||||
equipMain = '生'
|
||||
else:
|
||||
equipMain = mainName[3]
|
||||
else:
|
||||
equipMain = mainName[0]
|
||||
return equipMain
|
||||
|
||||
|
||||
async def get_char_percent(raw_data: dict) -> str:
|
||||
char_name = raw_data['avatarName']
|
||||
weaponName = raw_data['weaponInfo']['weaponName']
|
||||
weaponType = raw_data['weaponInfo']['weaponType']
|
||||
|
||||
fight_prop = raw_data['avatarFightProp']
|
||||
hp = fight_prop['hp']
|
||||
attack = fight_prop['atk']
|
||||
defense = fight_prop['def']
|
||||
em = fight_prop['elementalMastery']
|
||||
critrate = fight_prop['critRate']
|
||||
critdmg = fight_prop['critDmg']
|
||||
ce = fight_prop['energyRecharge']
|
||||
dmgBonus = fight_prop['dmgBonus'] if fight_prop['physicalDmgBonus'] <= fight_prop['dmgBonus'] else fight_prop['physicalDmgBonus']
|
||||
healBouns = fight_prop['healBonus']
|
||||
|
||||
hp_green = fight_prop['addHp']
|
||||
attack_green = fight_prop['addAtk']
|
||||
defense_green = fight_prop['addDef']
|
||||
|
||||
r = 0.9
|
||||
equipMain = ''
|
||||
for aritifact in raw_data['equipList']:
|
||||
mainName = aritifact['reliquaryMainstat']['statName']
|
||||
artifactsPos = aritifact['aritifactPieceName']
|
||||
if artifactsPos == '时之沙':
|
||||
equipMain += await get_first_main(mainName)
|
||||
elif artifactsPos == '空之杯':
|
||||
equipMain += await get_first_main(mainName)
|
||||
elif artifactsPos == '理之冠':
|
||||
equipMain += await get_first_main(mainName)
|
||||
|
||||
if 'equipSets' in raw_data:
|
||||
equipSets = raw_data['equipSets']
|
||||
else:
|
||||
artifact_set_list = []
|
||||
for i in raw_data['equipList']:
|
||||
artifact_set_list.append(i['aritifactSetsName'])
|
||||
equipSetList = set(artifact_set_list)
|
||||
equipSets = {'type':'','set':''}
|
||||
for equip in equipSetList:
|
||||
if artifact_set_list.count(equip) >= 4:
|
||||
equipSets['type'] = '4'
|
||||
equipSets['set'] = equip
|
||||
break
|
||||
elif artifact_set_list.count(equip) == 1:
|
||||
pass
|
||||
elif artifact_set_list.count(equip) >= 2:
|
||||
equipSets['type'] += '2'
|
||||
equipSets['set'] += equip
|
||||
|
||||
if equipSets['type'] in ['2','']:
|
||||
seq = ''
|
||||
else:
|
||||
seq = '{}|{}|{}'.format(weaponName.replace('「','').replace('」',''),equipSets['set'],equipMain)
|
||||
|
||||
if char_name in dmgMap:
|
||||
for action in dmgMap[char_name]:
|
||||
if action['seq'] == seq:
|
||||
cal = action
|
||||
break
|
||||
else:
|
||||
if '钟离' in char_name:
|
||||
cal = dmgMap[char_name][-1]
|
||||
else:
|
||||
cal = dmgMap[char_name][0]
|
||||
|
||||
print(seq)
|
||||
print(cal)
|
||||
if cal['action'] == 'E刹那之花':
|
||||
effect_prop = defense
|
||||
elif cal['key'] == '攻击力':
|
||||
effect_prop = attack
|
||||
elif cal['key'] == '防御力':
|
||||
effect_prop = defense
|
||||
elif cal['key'] == '血量':
|
||||
effect_prop = hp
|
||||
else:
|
||||
effect_prop = attack
|
||||
|
||||
dmgBonus_value_cal = 0
|
||||
dmgBonus_cal = dmgBonus
|
||||
em_cal = em
|
||||
|
||||
if '夜兰' in char_name:
|
||||
effect_prop = hp
|
||||
elif '胡桃' in char_name:
|
||||
effect_prop += 0.4 * hp if 0.4 * hp <= fight_prop['baseAtk'] * 4 else fight_prop['baseAtk'] * 4
|
||||
elif '一斗' in char_name:
|
||||
effect_prop += 0.9792 * defense
|
||||
dmgBonus_value_cal += 0.35 * defense
|
||||
elif '诺艾尔' in char_name:
|
||||
effect_prop = attack
|
||||
effect_prop += 1.3 * defense
|
||||
elif '烟绯' in char_name:
|
||||
dmgBonus_value_cal += 0.6 + 0.2
|
||||
elif '优菈' in char_name:
|
||||
r = 1.065
|
||||
elif '钟离' in char_name:
|
||||
r = 1.05
|
||||
elif '辛焱' in char_name:
|
||||
r = 1.025
|
||||
|
||||
if '踩班' in cal['action']:
|
||||
effect_prop += 1202
|
||||
effect_prop += fight_prop['baseAtk'] * 0.25
|
||||
|
||||
if '雾切' in weaponName:
|
||||
dmgBonus_cal += 0.28
|
||||
elif '弓藏' in weaponName and ('首' in cal['action'] or '击' in cal['action'] or '两段' in cal['action']):
|
||||
dmgBonus_cal += 0.8
|
||||
elif '飞雷' in weaponName and ('首' in cal['action'] or '击' in cal['action'] or '两段' in cal['action']):
|
||||
dmgBonus_cal += 0.4
|
||||
elif '阿莫斯' in weaponName:
|
||||
dmgBonus_cal += 0.52
|
||||
elif '破魔' in weaponName:
|
||||
dmgBonus_cal += 0.18*2
|
||||
elif '赤角石溃杵' in weaponName and ('首' in cal['action'] or '击' in cal['action'] or '两段' in cal['action']):
|
||||
dmgBonus_value_cal += 0.4 * defense
|
||||
elif '螭骨剑' in weaponName:
|
||||
dmgBonus_cal += 0.4
|
||||
elif '松籁响起之时' in weaponName:
|
||||
effect_prop += fight_prop['baseAtk'] * 0.2
|
||||
elif '试作澹月' in weaponName:
|
||||
effect_prop += fight_prop['baseAtk'] * 0.72
|
||||
elif '流浪乐章' in weaponName and '烟绯' in char_name:
|
||||
em_cal += 480
|
||||
elif '冬极' in weaponName:
|
||||
effect_prop += fight_prop['baseAtk'] * 0.48
|
||||
dmgBonus_cal += 0.12
|
||||
|
||||
if '蒸发' in cal['action'] or '融化' in cal['action']:
|
||||
if '蒸发' in cal['action']:
|
||||
if raw_data['avatarElement'] == 'Pyro':
|
||||
k = 1.5
|
||||
else:
|
||||
k = 2
|
||||
elif '融化' in cal['action']:
|
||||
if raw_data['avatarElement'] == 'Pyro':
|
||||
k = 2
|
||||
else:
|
||||
k = 1.5
|
||||
|
||||
if equipSets['type'] in ['2','']:
|
||||
a = 0
|
||||
else:
|
||||
if '魔女' in equipSets['set']:
|
||||
a = 0.15
|
||||
else:
|
||||
a = 0
|
||||
add_dmg = k*(1+(2.78*em_cal)/(em_cal+1400)+a)
|
||||
else:
|
||||
add_dmg = 1
|
||||
|
||||
if equipSets['type'] in ['2','','22']:
|
||||
pass
|
||||
else:
|
||||
if '追忆' in equipSets['set']:
|
||||
dmgBonus_cal += 0.5
|
||||
elif '绝缘' in equipSets['set']:
|
||||
Bouns = ce * 0.25 if ce * 0.25 <= 0.75 else 0.75
|
||||
dmgBonus_cal += Bouns
|
||||
elif '乐团' in equipSets['set']:
|
||||
if weaponType in ['法器', '弓']:
|
||||
dmgBonus_cal += 0.35
|
||||
elif '华馆' in equipSets['set']:
|
||||
if raw_data['avatarElement'] == 'Geo':
|
||||
effect_prop += 0.24 * defense
|
||||
dmgBonus_cal += 0.24
|
||||
|
||||
critdmg_cal = critdmg
|
||||
healBouns_cal = healBouns
|
||||
|
||||
if '魈' in char_name:
|
||||
dmgBonus_cal += 0.906
|
||||
elif '绫华' in char_name:
|
||||
dmgBonus_cal += 0.18
|
||||
elif '宵宫' in char_name:
|
||||
dmgBonus_cal += 0.5
|
||||
elif '九条' in char_name:
|
||||
effect_prop += 0.9129 * fight_prop['baseAtk']
|
||||
critdmg_cal += 0.6
|
||||
|
||||
if '治疗' in cal['action']:
|
||||
if equipSets['type'] in ['2','']:
|
||||
healBouns_cal += 0
|
||||
else:
|
||||
if '少女' in equipSets['set']:
|
||||
healBouns_cal += 0.2
|
||||
|
||||
if cal['action'] == '扩散':
|
||||
dmg = 868 * 1.15 * (1+0.6+(16*em_cal)/(em_cal+2000))
|
||||
elif '霄宫' in char_name:
|
||||
dmg = effect_prop * cal['power'] * (1 + critdmg_cal) * (1 + dmgBonus_cal) * 0.5 * r * add_dmg * 1.5879
|
||||
elif '班尼特' in char_name and 'Q治疗' in cal['action']:
|
||||
power = cal['power'].split('+')
|
||||
dmg = (effect_prop * float(power[0]) / 100 + float(power[1])) * (1 + healBouns_cal)
|
||||
elif '心海' in char_name and cal['action'] == '开Q普攻':
|
||||
dmg = (attack * cal['power'] + hp*(0.0971 + 0.15 * healBouns_cal)) * (1 + dmgBonus_cal) * 0.5 * r * add_dmg
|
||||
elif '心海' in char_name and cal['action'] == '水母回血':
|
||||
dmg = (862 + 0.0748 * hp) * (1 + healBouns_cal)
|
||||
elif char_name in ['芭芭拉', '早柚', '琴', '七七']:
|
||||
power = cal['power'].split('+')
|
||||
dmg = (effect_prop * float(power[0]) / 100 + float(power[1])) * (1 + healBouns_cal)
|
||||
elif '绫人' in char_name:
|
||||
dmg = (effect_prop * cal['power'] + 0.0222 * hp) * (1 + critdmg_cal) * (1 + dmgBonus_cal) * 0.5 * r * add_dmg * 1.5879
|
||||
elif char_name in ['荒泷一斗', '诺艾尔']:
|
||||
dmg = (effect_prop * cal['power'] + dmgBonus_value_cal) * (1 + critdmg_cal) * (1 + dmgBonus_cal) * 0.5 * r
|
||||
elif '迪奥娜' in char_name:
|
||||
dmg = (effect_prop * cal['power'] + 1905) * 1.9
|
||||
elif '钟离' in char_name and 'E实际盾值' in cal['action']:
|
||||
dmg = (2506 + hp * cal['power']) * 1.5 * 1.3
|
||||
elif cal['action'] == 'Q开盾天星':
|
||||
effect_prop = attack
|
||||
dmg = (effect_prop * cal['power'] + 0.33 * hp) * (1 + critdmg_cal) * (1 + dmgBonus_cal) * 0.5 * r * add_dmg
|
||||
elif '凝光' in char_name:
|
||||
dmg = effect_prop * cal['power'] * (1 + critdmg_cal * critrate) * (1 + dmgBonus_cal) * 0.5 * r * add_dmg
|
||||
elif isinstance(cal['power'], str):
|
||||
if cal['power'] == '攻击力':
|
||||
dmg = attack
|
||||
elif cal['power'] == '防御力':
|
||||
dmg = defense
|
||||
else:
|
||||
power = cal['power'].split('+')
|
||||
dmg = effect_prop * float(power[0]) / 100 + float(power[1])
|
||||
elif cal['val'] != 'any':
|
||||
dmg = effect_prop * cal['power'] * (1 + critdmg_cal) * (1 + dmgBonus_cal) * 0.5 * r * add_dmg
|
||||
else:
|
||||
dmg = attack
|
||||
print(dmg)
|
||||
|
||||
if cal['val'] != 'any':
|
||||
percent = '{:.2f}'.format(dmg / cal['val'] * 100)
|
||||
elif cal['power'] == '攻击力':
|
||||
percent = '{:.2f}'.format(dmg / cal['atk'] * 100)
|
||||
elif '云堇' in char_name:
|
||||
percent = '{:.2f}'.format(dmg / cal['other2'] * 100)
|
||||
elif cal['power'] == '防御力':
|
||||
percent = '{:.2f}'.format(dmg / cal['other'] * 100)
|
||||
else:
|
||||
percent = 0.00
|
||||
return percent
|
||||
|
||||
|
||||
async def draw_char_card(raw_data: dict, charUrl: str = None) -> bytes:
|
||||
char_name = raw_data['avatarName']
|
||||
char_level = raw_data['avatarLevel']
|
||||
char_fetter = raw_data['avatarFetter']
|
||||
|
||||
based_w, based_h = 600, 1200
|
||||
if charUrl:
|
||||
offset_x, offset_y = 200, 0
|
||||
char_img = Image.open(BytesIO(get(charUrl).content)).convert('RGBA')
|
||||
else:
|
||||
if char_name in avatarOffsetMap:
|
||||
offset_x, offset_y = avatarOffsetMap[char_name][0], avatarOffsetMap[char_name][1]
|
||||
else:
|
||||
offset_x, offset_y = 200, 0
|
||||
char_img = Image.open(GACHA_PATH / 'UI_Gacha_AvatarImg_{}.png'.format(raw_data['avatarEnName'])) #角色图像
|
||||
|
||||
# 确定图片的长宽
|
||||
w, h = char_img.size
|
||||
if (w, h) != (based_w, based_h):
|
||||
#offset_all = offset_x if offset_x >= offset_y else offset_y
|
||||
based_new_w, based_new_h = based_w + offset_x, based_h + offset_y
|
||||
based_scale = '%.3f' % (based_new_w / based_new_h)
|
||||
scale_f = '%.3f' % (w / h)
|
||||
new_w = math.ceil(based_new_h * float(scale_f))
|
||||
new_h = math.ceil(based_new_w / float(scale_f))
|
||||
if scale_f > based_scale:
|
||||
bg_img2 = char_img.resize((new_w, based_new_h), Image.Resampling.LANCZOS)
|
||||
x1 = new_w/2 - based_new_w /2 + offset_x
|
||||
y1 = 0 + offset_y / 2
|
||||
x2 = new_w/2 + based_new_w /2
|
||||
y2 = based_new_h - offset_y / 2
|
||||
else:
|
||||
bg_img2 = char_img.resize((based_new_w , new_h), Image.Resampling.LANCZOS)
|
||||
x1 = 0 + offset_x
|
||||
y1 = new_h/2 - based_new_h/2 + offset_y / 2
|
||||
x2 = based_new_w
|
||||
y2 = new_h/2 + based_new_h/2 - offset_y / 2
|
||||
char_img = bg_img2.crop((x1, y1, x2, y2))
|
||||
|
||||
dmg_img, dmg_len = await draw_dmgCacl_img(raw_data)
|
||||
img_w, img_h = 950, 1850 + dmg_len * 40
|
||||
overlay = Image.open(TEXT_PATH / 'overlay.png')
|
||||
overlay_w, overlay_h = overlay.size
|
||||
if overlay_h < img_h:
|
||||
new_overlay_h = img_h
|
||||
new_overlay_w = math.ceil(new_overlay_h * overlay_w / overlay_h)
|
||||
overlay = overlay.resize((new_overlay_w, new_overlay_h), Image.Resampling.LANCZOS)
|
||||
overlay = overlay.crop((0, 0, img_w, img_h))
|
||||
color_img = Image.new('RGBA', overlay.size, COLOR_MAP[raw_data['avatarElement']])
|
||||
img = ImageChops.overlay(color_img, overlay)
|
||||
char_info_1 = Image.open(TEXT_PATH / 'char_info_1.png')
|
||||
char_info_mask = Image.open(TEXT_PATH / 'char_info_mask.png')
|
||||
|
||||
img_temp = Image.new('RGBA', (based_w, based_h), (0,0,0,0))
|
||||
img_temp.paste(char_img,(0,0),char_info_mask)
|
||||
img.paste(img_temp, (0, 0), img_temp)
|
||||
img.paste(char_info_1, (0, 0), char_info_1)
|
||||
img.paste(dmg_img,(0,1850),dmg_img)
|
||||
|
||||
lock_img = Image.open(TEXT_PATH / 'icon_lock.png')
|
||||
|
||||
# 命座处理
|
||||
for talent_num in range(0, 6):
|
||||
if talent_num + 1 <= len(raw_data['talentList']):
|
||||
talent = raw_data['talentList'][talent_num]
|
||||
# img.paste(color_holo_img, (13,270 + talent_num * 66), holo_img)
|
||||
talent_img = Image.open(ICON_PATH / '{}.png'.format(talent['talentIcon']))
|
||||
talent_img_new = talent_img.resize((50, 50), Image.Resampling.LANCZOS).convert("RGBA")
|
||||
img.paste(talent_img_new, (850, 375 + talent_num * 81), talent_img_new)
|
||||
else:
|
||||
img.paste(lock_img, (850, 375 + talent_num * 81), lock_img)
|
||||
|
||||
# 天赋处理
|
||||
skillList = raw_data['avatarSkill']
|
||||
a_skill_name = skillList[0]['skillName'].replace('普通攻击·', '')
|
||||
a_skill_level = skillList[0]['skillLevel']
|
||||
e_skill_name = skillList[1]['skillName']
|
||||
e_skill_level = skillList[1]['skillLevel']
|
||||
q_skill_name = skillList[-1]['skillName']
|
||||
q_skill_level = skillList[-1]['skillLevel']
|
||||
|
||||
skill_add = avatarName2SkillAdd[char_name]
|
||||
for skillAdd_index in range(0, 2):
|
||||
if len(raw_data['talentList']) >= 3 + skillAdd_index * 2:
|
||||
if skill_add[skillAdd_index] == 'E':
|
||||
e_skill_level += 3
|
||||
elif skill_add[skillAdd_index] == 'Q':
|
||||
q_skill_level += 3
|
||||
|
||||
for skill_num, skill in enumerate(skillList[0:2] + [skillList[-1]]):
|
||||
skill_img = Image.open(ICON_PATH / '{}.png'.format(skill['skillIcon']))
|
||||
skill_img_new = skill_img.resize((50, 50), Image.Resampling.LANCZOS).convert("RGBA")
|
||||
img.paste(skill_img_new, (78, 756 + 101 * skill_num), skill_img_new)
|
||||
|
||||
# 武器部分
|
||||
weapon_img = Image.open(TEXT_PATH / 'char_info_weapon.png')
|
||||
weapon_star_img = get_star_png(raw_data['weaponInfo']['weaponStar'])
|
||||
weaponName = raw_data['weaponInfo']['weaponName']
|
||||
|
||||
weaponAtk = raw_data['weaponInfo']['weaponStats'][0]['statValue']
|
||||
weaponLevel = raw_data['weaponInfo']['weaponLevel']
|
||||
weaponAffix = raw_data['weaponInfo']['weaponAffix']
|
||||
weaponEffect = raw_data['weaponInfo']['weaponEffect']
|
||||
weapon_type = raw_data['weaponInfo']['weaponType']
|
||||
|
||||
weapon_img.paste(weapon_star_img, (25, 235), weapon_star_img)
|
||||
weapon_text = ImageDraw.Draw(weapon_img)
|
||||
weapon_text.text((35, 80), weaponName, (255, 255, 255), genshin_font_origin(50), anchor='lm')
|
||||
weapon_text.text((35, 120), weapon_type, (255, 255, 255), genshin_font_origin(20), anchor='lm')
|
||||
weapon_text.text((35, 160), '基础攻击力', (255, 255, 255), genshin_font_origin(32), anchor='lm')
|
||||
weapon_text.text((368, 160), str(weaponAtk), (255, 255, 255), genshin_font_origin(32), anchor='rm')
|
||||
if len(raw_data['weaponInfo']['weaponStats']) == 2:
|
||||
weapon_sub_info = raw_data['weaponInfo']['weaponStats'][1]['statName']
|
||||
weapon_sub_value = raw_data['weaponInfo']['weaponStats'][1]['statValue']
|
||||
weapon_text.text((35, 211), weapon_sub_info, (255, 255, 255), genshin_font_origin(32), anchor='lm')
|
||||
weapon_text.text((368, 211), str(weapon_sub_value), (255, 255, 255), genshin_font_origin(32), anchor='rm')
|
||||
else:
|
||||
weapon_text.text((35, 211), '该武器无副词条', (255, 255, 255), genshin_font_origin(32), anchor='lm')
|
||||
weapon_text.text((73, 303), f'Lv.{weaponLevel}', (255, 255, 255), genshin_font_origin(28), anchor='mm')
|
||||
weapon_text.text((130, 305), f'精炼{str(weaponAffix)}阶', (255, 239, 173), genshin_font_origin(28), anchor='lm')
|
||||
|
||||
weaponEffect = strLenth(weaponEffect, 25, 455)
|
||||
weapon_text.text((25, 335), weaponEffect, (255, 255, 255), genshin_font_origin(25))
|
||||
img.paste(weapon_img, (387, 590), weapon_img)
|
||||
|
||||
fight_prop = raw_data['avatarFightProp']
|
||||
hp = fight_prop['hp']
|
||||
baseHp = fight_prop['baseHp']
|
||||
attack = fight_prop['atk']
|
||||
baseAtk = fight_prop['baseAtk']
|
||||
defense = fight_prop['def']
|
||||
baseDef = fight_prop['baseDef']
|
||||
em = fight_prop['elementalMastery']
|
||||
critrate = fight_prop['critRate']
|
||||
critdmg = fight_prop['critDmg']
|
||||
ce = fight_prop['energyRecharge']
|
||||
dmgBonus = fight_prop['dmgBonus'] if fight_prop['physicalDmgBonus'] <= fight_prop['dmgBonus'] else fight_prop['physicalDmgBonus']
|
||||
|
||||
hp_green = fight_prop['addHp']
|
||||
attack_green = fight_prop['addAtk']
|
||||
defense_green = fight_prop['addDef']
|
||||
|
||||
# 圣遗物部分
|
||||
artifactsAllScore = 0
|
||||
for aritifact in raw_data['equipList']:
|
||||
artifacts_img = Image.open(TEXT_PATH / 'char_info_artifacts.png')
|
||||
artifacts_piece_img = Image.open(RELIC_PATH / '{}.png'.format(aritifact['icon']))
|
||||
artifacts_piece_new_img = artifacts_piece_img.resize((75, 75), Image.Resampling.LANCZOS).convert("RGBA")
|
||||
#artifacts_piece_new_img.putalpha(
|
||||
# artifacts_piece_new_img.getchannel('A').point(lambda x: round(x * 0.5) if x > 0 else 0))
|
||||
|
||||
artifacts_img.paste(artifacts_piece_new_img, (195, 35), artifacts_piece_new_img)
|
||||
aritifactStar_img = get_star_png(aritifact['aritifactStar'])
|
||||
artifactsPos = aritifact['aritifactPieceName']
|
||||
|
||||
artifacts_img.paste(aritifactStar_img, (20, 165), aritifactStar_img)
|
||||
artifacts_text = ImageDraw.Draw(artifacts_img)
|
||||
artifacts_text.text((30, 66), aritifact['aritifactName'][:4], (255, 255, 255), genshin_font_origin(34), anchor='lm')
|
||||
artifacts_text.text((30, 102), artifactsPos, (255, 255, 255), genshin_font_origin(20), anchor='lm')
|
||||
|
||||
mainValue = aritifact['reliquaryMainstat']['statValue']
|
||||
mainName = aritifact['reliquaryMainstat']['statName']
|
||||
mainLevel = aritifact['aritifactLevel']
|
||||
|
||||
if mainName in ['攻击力', '血量', '防御力', '元素精通']:
|
||||
mainValueStr = str(mainValue)
|
||||
else:
|
||||
mainValueStr = str(mainValue) + '%'
|
||||
|
||||
mainNameNew = mainName.replace('百分比', '').replace('伤害加成', '伤加成').replace('元素', '').replace('理', '')
|
||||
|
||||
artifacts_text.text((30, 141), mainNameNew, (255, 255, 255), genshin_font_origin(28), anchor='lm')
|
||||
artifacts_text.text((263, 141), mainValueStr, (255, 255, 255), genshin_font_origin(28), anchor='rm')
|
||||
artifacts_text.text((55, 219), '+{}'.format(str(mainLevel)), (255, 255, 255), genshin_font_origin(24),
|
||||
anchor='mm')
|
||||
|
||||
artifactsScore = 0
|
||||
for index, i in enumerate(aritifact['reliquarySubstats']):
|
||||
subName = i['statName']
|
||||
subValue = i['statValue']
|
||||
if subName in ['攻击力', '血量', '防御力', '元素精通']:
|
||||
subValueStr = str(subValue)
|
||||
else:
|
||||
subValueStr = str(subValue) + '%'
|
||||
#artifactsScore += await get_artifacts_score(subName, subValue)
|
||||
value_temp = await get_artifacts_value(subName, subValue, baseAtk, baseHp, baseDef, char_name)
|
||||
artifactsScore += value_temp
|
||||
subNameStr = subName.replace('百分比', '').replace('元素', '')
|
||||
if value_temp == 0:
|
||||
artifacts_color = (160, 160, 160)
|
||||
elif value_temp >= 4.5:
|
||||
artifacts_color = (247, 50, 50)
|
||||
else:
|
||||
artifacts_color = (255, 255, 100)
|
||||
artifacts_text.text((20, 256 + index * 33), '·{}'.format(subNameStr), artifacts_color,
|
||||
genshin_font_origin(25), anchor='lm')
|
||||
artifacts_text.text((268, 256 + index * 33), '{}'.format(subValueStr), artifacts_color,
|
||||
genshin_font_origin(25), anchor='rm')
|
||||
if artifactsScore >= 6:
|
||||
artifactsScore_color = (247, 26, 26)
|
||||
else:
|
||||
artifactsScore_color = (255, 255, 255)
|
||||
artifactsAllScore += artifactsScore
|
||||
artifacts_text.text((268, 190), '{:.2f}'.format(artifactsScore) + '条', artifactsScore_color, genshin_font_origin(23),
|
||||
anchor='rm')
|
||||
|
||||
if artifactsPos == '生之花':
|
||||
img.paste(artifacts_img, (18, 1075), artifacts_img)
|
||||
elif artifactsPos == '死之羽':
|
||||
img.paste(artifacts_img, (318, 1075), artifacts_img)
|
||||
elif artifactsPos == '时之沙':
|
||||
img.paste(artifacts_img, (618, 1075), artifacts_img)
|
||||
elif artifactsPos == '空之杯':
|
||||
img.paste(artifacts_img, (18, 1447), artifacts_img)
|
||||
elif artifactsPos == '理之冠':
|
||||
img.paste(artifacts_img, (318, 1447), artifacts_img)
|
||||
|
||||
# 角色基本信息
|
||||
img_text = ImageDraw.Draw(img)
|
||||
img_text.text((411, 72), char_name, (255, 255, 255), genshin_font_origin(55), anchor='lm')
|
||||
img_text.text((411, 122), '等级{}'.format(char_level), (255, 255, 255), genshin_font_origin(40), anchor='lm')
|
||||
img_text.text((747, 126), str(char_fetter), (255, 255, 255), genshin_font_origin(28), anchor='lm')
|
||||
|
||||
# aeq
|
||||
# img_text.text((110, 771), a_skill_name, (255, 255, 255), genshin_font_origin(26), anchor='lm')
|
||||
img_text.text((103, 812), f'{str(a_skill_level)}', (255, 255, 255), genshin_font_origin(30), anchor='mm')
|
||||
|
||||
# img_text.text((110, 872), e_skill_name, (255, 255, 255), genshin_font_origin(26), anchor='lm')
|
||||
img_text.text((103, 915), f'{str(e_skill_level)}', (255, 255, 255), genshin_font_origin(30), anchor='mm')
|
||||
|
||||
# img_text.text((110, 973), q_skill_name, (255, 255, 255), genshin_font_origin(26), anchor='lm')
|
||||
img_text.text((103, 1016), f'{str(q_skill_level)}', (255, 255, 255), genshin_font_origin(30), anchor='mm')
|
||||
|
||||
# 属性
|
||||
img_text.text((785, 174), str(round(hp)), (255, 255, 255), genshin_font_origin(28), anchor='rm')
|
||||
img_text.text((785, 227), str(round(attack)), (255, 255, 255), genshin_font_origin(28), anchor='rm')
|
||||
img_text.text((785, 280), str(round(defense)), (255, 255, 255), genshin_font_origin(28), anchor='rm')
|
||||
img_text.text((785, 333), str(round(em)), (255, 255, 255), genshin_font_origin(28), anchor='rm')
|
||||
img_text.text((785, 386), f'{str(round(critrate * 100, 2))}%', (255, 255, 255), genshin_font_origin(28),
|
||||
anchor='rm')
|
||||
img_text.text((785, 439), f'{str(round(critdmg * 100, 2))}%', (255, 255, 255), genshin_font_origin(28), anchor='rm')
|
||||
img_text.text((785, 492), f'{str(round(ce * 100, 1))}%', (255, 255, 255), genshin_font_origin(28), anchor='rm')
|
||||
img_text.text((785, 545), f'{str(round(dmgBonus * 100, 1))}%', (255, 255, 255), genshin_font_origin(28),
|
||||
anchor='rm')
|
||||
|
||||
img_text.text((805, 174), f'(+{str(round(hp_green))})', (95, 251, 80), genshin_font_origin(28), anchor='lm')
|
||||
img_text.text((805, 227), f'(+{str(round(attack_green))})', (95, 251, 80), genshin_font_origin(28), anchor='lm')
|
||||
img_text.text((805, 280), f'(+{str(round(defense_green))})', (95, 251, 80), genshin_font_origin(28), anchor='lm')
|
||||
|
||||
uid = raw_data['playerUid']
|
||||
data_time = raw_data['dataTime']
|
||||
# uid
|
||||
img_text.text((350, 1035), f'UID{uid}', (255, 255, 255), genshin_font_origin(24), anchor='rm')
|
||||
|
||||
# 数据最后更新时间
|
||||
img_text.text((780, 600), f'数据最后更新于{data_time}', (255, 255, 255), genshin_font_origin(22), anchor='rm')
|
||||
|
||||
# 角色评分
|
||||
img_text.text((768, 1557), f'{round(artifactsAllScore, 1)}', (255, 255, 255), genshin_font_origin(50), anchor='mm')
|
||||
percent = await get_char_percent(raw_data)
|
||||
img_text.text((768, 1690), f'{str(percent)+"%"}', (255, 255, 255), genshin_font_origin(50), anchor='mm')
|
||||
|
||||
img = img.convert('RGB')
|
||||
result_buffer = BytesIO()
|
||||
img.save(result_buffer, format='JPEG', subsampling=0, quality=90)
|
||||
imgmes = 'base64://' + b64encode(result_buffer.getvalue()).decode()
|
||||
res = imgmes
|
||||
return res
|
||||
|
||||
async def draw_single_card(img: Image, char: dict, index: int, color: Tuple[int, int, int],
|
||||
x_limit: int, char_card_mask: Image, char_card_1: Image, img_card: Image):
|
||||
|
||||
size_36 = genshin_font_origin(36)
|
||||
size_46 = genshin_font_origin(46)
|
||||
|
||||
overlay = Image.open(TEXT_PATH / 'overlay.png')
|
||||
color_img = Image.new('RGBA', overlay.size, COLOR_MAP[char['avatarElement']])
|
||||
img_base = ImageChops.overlay(color_img, overlay)
|
||||
if char['char_name'] in avatarCardOffsetMap:
|
||||
offset_x, offset_y = avatarCardOffsetMap[char['char_name']][0], avatarCardOffsetMap[char['char_name']][1]
|
||||
else:
|
||||
offset_x, offset_y = 200, 0
|
||||
char_img = Image.open(GACHA_PATH / 'UI_Gacha_AvatarImg_{}.png'.format(char['avatarEnName']))
|
||||
|
||||
img_base.paste(char_img, (-439 + offset_x, 130 + offset_y), char_img)
|
||||
img_card.paste(img_base, (-25, -260), char_card_mask)
|
||||
img_card = Image.alpha_composite(img_card, char_card_1)
|
||||
#img_card.paste(img_card, (0, 0), img_card)
|
||||
|
||||
char_card_text = ImageDraw.Draw(img_card)
|
||||
|
||||
char_card_text.text((448, 59.2), f'{str(round(char["critrate"] * 100, 2))}%', color, size_36, anchor='lm')
|
||||
char_card_text.text((448, 122.2), f'{str(round(char["critdmg"] * 100, 2))}%', color, size_36, anchor='lm')
|
||||
|
||||
char_card_text.text((410.9, 252.6), str(char['a_skill_level']), color, size_36, anchor='mm')
|
||||
char_card_text.text((485, 252.6), str(char['e_skill_level']), color, size_36, anchor='mm')
|
||||
char_card_text.text((558, 252.6), str(char['q_skill_level']), color, size_36, anchor='mm')
|
||||
|
||||
if float(char['percent']) >= 100:
|
||||
percent_color = (204, 57, 78)
|
||||
else:
|
||||
percent_color = color
|
||||
|
||||
if char['value'] >= 28.5:
|
||||
value_color = (204, 57, 78)
|
||||
else:
|
||||
value_color = color
|
||||
|
||||
char_card_text.text((742, 253.1), str(char['percent']) + '%', percent_color, size_46, anchor='mm')
|
||||
char_card_text.text((742, 113.1), str(char['value']) + '条', value_color, size_46, anchor='mm')
|
||||
|
||||
char_card_text.text((21.2, 70.5), f'{str(char["talent_num"])}命', color, size_36, anchor='lm')
|
||||
char_card_text.text((21.2, 129.8), f'{str(char["weapon_affix"])}精', color, size_36, anchor='lm')
|
||||
|
||||
img.paste(img_card, ((index % x_limit) * 900, (index // x_limit) * 300), img_card)
|
||||
|
||||
async def draw_cahrcard_list(uid: str,limit :int = 24) -> str:
|
||||
uid_fold = PLAYER_PATH / str(uid)
|
||||
char_file_list = uid_fold.glob('*')
|
||||
char_list = []
|
||||
for i in char_file_list:
|
||||
file_name = i.name
|
||||
if '\u4e00' <= file_name[0] <= '\u9fff':
|
||||
char_list.append(file_name.split('.')[0])
|
||||
if not char_list:
|
||||
return '你还没有已缓存的角色!\n请先使用【强制刷新】进行刷新!'
|
||||
|
||||
char_done_list = []
|
||||
for char_name in char_list:
|
||||
temp = {}
|
||||
with open(uid_fold / f'{char_name}.json', 'r', encoding='UTF-8') as f:
|
||||
raw_data = json.load(f)
|
||||
|
||||
fight_prop = raw_data['avatarFightProp']
|
||||
skillList = raw_data['avatarSkill']
|
||||
|
||||
temp['char_name'] = char_name
|
||||
temp['avatarEnName'] = raw_data['avatarEnName']
|
||||
temp['avatarElement'] = raw_data['avatarElement']
|
||||
temp['percent'] = await get_char_percent(raw_data)
|
||||
temp['critrate'] = fight_prop['critRate']
|
||||
temp['critdmg'] = fight_prop['critDmg']
|
||||
baseHp = fight_prop['baseHp']
|
||||
baseAtk = fight_prop['baseAtk']
|
||||
baseDef = fight_prop['baseDef']
|
||||
temp['value'] = await get_all_artifacts_value(raw_data['equipList'], baseHp, baseAtk, baseDef, char_name)
|
||||
temp['value'] = float('{:.2f}'.format(temp['value']))
|
||||
temp['avatarElement'] = raw_data['avatarElement']
|
||||
temp['a_skill_level'] = skillList[0]['skillLevel']
|
||||
temp['e_skill_level'] = skillList[1]['skillLevel']
|
||||
temp['q_skill_level'] = skillList[-1]['skillLevel']
|
||||
temp['talent_num'] = len(raw_data['talentList'])
|
||||
temp['weapon_affix'] = raw_data['weaponInfo']['weaponAffix']
|
||||
char_done_list.append(temp)
|
||||
|
||||
# 排序
|
||||
char_done_list.sort(key=lambda x: (-float(x['percent'])))
|
||||
char_done_list = char_done_list[:limit]
|
||||
|
||||
char_card_1 = Image.open(TEXT_PATH / 'charcard_1.png')
|
||||
char_card_mask = Image.open(TEXT_PATH / 'charcard_mask.png')
|
||||
|
||||
x_limit = 2
|
||||
color = (255, 255, 255)
|
||||
x_tile = (len(char_done_list) + x_limit - 1) // x_limit
|
||||
y_tile = math.ceil(len(char_done_list) / x_tile)
|
||||
x_tile, y_tile = x_tile if x_tile <= y_tile else y_tile, y_tile if y_tile >= x_tile else x_tile
|
||||
|
||||
img = Image.new('RGBA', (900 * x_tile, 300 * y_tile), (0, 0, 0))
|
||||
img_card = Image.new('RGBA', (900, 300))
|
||||
|
||||
tasks = []
|
||||
for index, char in enumerate(char_done_list):
|
||||
tasks.append(draw_single_card(img, char, index, color, x_limit, char_card_mask, char_card_1, img_card))
|
||||
await asyncio.wait(tasks)
|
||||
|
||||
img = img.convert('RGB')
|
||||
result_buffer = BytesIO()
|
||||
img.save(result_buffer, format='JPEG', subsampling=0, quality=90)
|
||||
imgmes = 'base64://' + b64encode(result_buffer.getvalue()).decode()
|
||||
res = imgmes
|
||||
return res
|
261
enkaToData/enkaToData.py
Normal file
@ -0,0 +1,261 @@
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
import httpx
|
||||
import json
|
||||
import time
|
||||
|
||||
R_PATH = Path(__file__).parents[0]
|
||||
MAP_PATH = R_PATH / 'map'
|
||||
ICON_PATH = R_PATH / 'icon'
|
||||
DATA_PATH = R_PATH / 'data'
|
||||
PLAYER_PATH = R_PATH / 'player'
|
||||
|
||||
version = '2.8.0'
|
||||
|
||||
avatarName2Element_fileName = f'avatarName2Element_mapping_{version}.json'
|
||||
weaponHash2Name_fileName = f'weaponHash2Name_mapping_{version}.json'
|
||||
weaponHash2Type_fileName = f'weaponHash2Type_mapping_{version}.json'
|
||||
skillId2Name_fileName = f'skillId2Name_mapping_{version}.json'
|
||||
talentId2Name_fileName = f'talentId2Name_mapping_{version}.json'
|
||||
avatarId2Name_fileName = f'avatarId2Name_mapping_{version}.json'
|
||||
|
||||
artifact2attr_fileName = f'artifact2attr_mapping_{version}.json'
|
||||
icon2Name_fileName = f'icon2Name_mapping_{version}.json'
|
||||
|
||||
with open(MAP_PATH / avatarId2Name_fileName, "r", encoding='UTF-8') as f:
|
||||
avatarId2Name = json.load(f)
|
||||
|
||||
with open(MAP_PATH / icon2Name_fileName, "r", encoding='UTF-8') as f:
|
||||
icon2Name = json.load(f)
|
||||
|
||||
with open(MAP_PATH / artifact2attr_fileName, "r", encoding='UTF-8') as f:
|
||||
artifact2attr = json.load(f)
|
||||
|
||||
with open(MAP_PATH / 'propId2Name_mapping.json', "r", encoding='UTF-8') as f:
|
||||
propId2Name = json.load(f)
|
||||
|
||||
with open(MAP_PATH / weaponHash2Name_fileName, "r", encoding='UTF-8') as f:
|
||||
weaponHash2Name = json.load(f)
|
||||
|
||||
with open(MAP_PATH / weaponHash2Type_fileName, "r", encoding='UTF-8') as f:
|
||||
weaponHash2Type = json.load(f)
|
||||
|
||||
with open(MAP_PATH / 'artifactId2Piece_mapping.json', "r", encoding='UTF-8') as f:
|
||||
artifactId2Piece = json.load(f)
|
||||
|
||||
with open(MAP_PATH / skillId2Name_fileName, "r", encoding='UTF-8') as f:
|
||||
skillId2Name = json.load(f)
|
||||
|
||||
with open(MAP_PATH / talentId2Name_fileName, "r", encoding='UTF-8') as f:
|
||||
talentId2Name = json.load(f)
|
||||
|
||||
with open(MAP_PATH / avatarName2Element_fileName, 'r', encoding='UTF-8') as f:
|
||||
avatarName2Element = json.load(f)
|
||||
|
||||
async def enkaToData(uid: str, enka_data: Optional[dict] = None) -> dict:
|
||||
if enka_data:
|
||||
pass
|
||||
else:
|
||||
enka_data = json.loads(httpx.get(url=f'https://enka.network/u/{str(uid)}/__data.json', headers={'User-Agent': 'GenshinUID/2.0'}).text)
|
||||
if enka_data == {}:
|
||||
return enka_data
|
||||
now = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
|
||||
playerInfo = enka_data['playerInfo']
|
||||
path = PLAYER_PATH / str(uid)
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
with open(path / '{}.json'.format(str(uid)),'w', encoding='UTF-8') as file:
|
||||
json.dump(playerInfo, file, ensure_ascii=False)
|
||||
with open(path / 'rawData.json','w', encoding='UTF-8') as file:
|
||||
json.dump(enka_data, file, ensure_ascii=False)
|
||||
|
||||
if 'avatarInfoList' not in enka_data:
|
||||
return f'UID{uid}刷新失败!未打开角色展柜!'
|
||||
|
||||
char_name_list = []
|
||||
for char in enka_data['avatarInfoList']:
|
||||
# 处理基本信息
|
||||
char_data = {}
|
||||
avatarId = char['avatarId']
|
||||
char_data['playerUid'] = str(uid)
|
||||
char_data['playerName'] = enka_data['playerInfo']['nickname']
|
||||
char_data['avatarId'] = avatarId
|
||||
avatarName = avatarId2Name[str(char['avatarId'])]
|
||||
char_data['avatarName'] = avatarId2Name[str(char['avatarId'])]
|
||||
char_name_list.append(char_data['avatarName'])
|
||||
char_data['avatarFetter'] = char['fetterInfo']['expLevel']
|
||||
char_data['avatarLevel'] = char['propMap']['4001']['val']
|
||||
|
||||
try:
|
||||
char_data['avatarElement'] = avatarName2Element[char_data['avatarName']]
|
||||
except KeyError:
|
||||
check = skillId2Name['Name'][str(list(char['skillLevelMap'].keys())[2])]
|
||||
if '风' in check:
|
||||
char_data['avatarElement'] = 'Anemo'
|
||||
elif '雷' in check:
|
||||
char_data['avatarElement'] = 'Electro'
|
||||
elif '岩' in check:
|
||||
char_data['avatarElement'] = 'Geo'
|
||||
elif '草' in check:
|
||||
char_data['avatarElement'] = 'Dendro'
|
||||
elif '冰' in check:
|
||||
char_data['avatarElement'] = 'Cryo'
|
||||
elif '水' in check:
|
||||
char_data['avatarElement'] = 'Hydro'
|
||||
else:
|
||||
char_data['avatarElement'] = 'Pyro'
|
||||
|
||||
char_data['dataTime'] = now
|
||||
|
||||
char_data['avatarSkill'] = []
|
||||
# 处理天赋
|
||||
for skill in char['skillLevelMap']:
|
||||
skill_temp = {}
|
||||
skill_temp['skillId'] = skill
|
||||
skill_temp['skillName'] = skillId2Name['Name'][skill_temp['skillId']]
|
||||
skill_temp['skillLevel'] = char['skillLevelMap'][skill]
|
||||
skill_temp['skillIcon'] = skillId2Name['Icon'][skill_temp['skillId']]
|
||||
char_data['avatarSkill'].append(skill_temp)
|
||||
|
||||
if char_data['avatarName'] in ['神里绫华', '安柏']:
|
||||
char_data['avatarSkill'][0], char_data['avatarSkill'][-1] = char_data['avatarSkill'][-1], \
|
||||
char_data['avatarSkill'][0]
|
||||
char_data['avatarSkill'][2], char_data['avatarSkill'][-1] = char_data['avatarSkill'][-1], \
|
||||
char_data['avatarSkill'][2]
|
||||
char_data['avatarEnName'] = char_data['avatarSkill'][1]['skillIcon'].split('_')[-2]
|
||||
elif char_data['avatarName'] in ['旅行者']:
|
||||
char_data['avatarSkill'][0], char_data['avatarSkill'][-1] = char_data['avatarSkill'][-1], \
|
||||
char_data['avatarSkill'][0]
|
||||
char_data['avatarSkill'][1], char_data['avatarSkill'][-1] = char_data['avatarSkill'][-1], \
|
||||
char_data['avatarSkill'][1]
|
||||
char_data['avatarEnName'] = str(avatarId)
|
||||
else:
|
||||
char_data['avatarEnName'] = char_data['avatarSkill'][-1]['skillIcon'].split('_')[-2]
|
||||
|
||||
# 处理命座
|
||||
talent_temp = []
|
||||
if 'talentIdList' in char:
|
||||
for index,talent in enumerate(char['talentIdList']):
|
||||
talentTemp = {}
|
||||
talentTemp['talentId'] = char['talentIdList'][index]
|
||||
talentTemp['talentName'] = talentId2Name['Name'][str(talent)]
|
||||
talentTemp['talentIcon'] = talentId2Name['Icon'][str(talent)]
|
||||
talent_temp.append(talentTemp)
|
||||
char_data['talentList'] = talent_temp
|
||||
|
||||
# 处理属性
|
||||
fight_prop = {}
|
||||
# 血量
|
||||
fight_prop['hp'] = char["fightPropMap"]["2000"]
|
||||
fight_prop['baseHp'] = char["fightPropMap"]["1"]
|
||||
fight_prop['addHp'] = char["fightPropMap"]["2000"] - char["fightPropMap"]["1"]
|
||||
# 攻击力
|
||||
fight_prop['atk'] = char["fightPropMap"]["2001"]
|
||||
fight_prop['baseAtk'] = char["fightPropMap"]["4"]
|
||||
fight_prop['addAtk'] = char["fightPropMap"]["2001"] - char["fightPropMap"]["4"]
|
||||
# 防御力
|
||||
fight_prop['def'] = char["fightPropMap"]["2002"]
|
||||
fight_prop['baseDef'] = char["fightPropMap"]["7"]
|
||||
fight_prop['addDef'] = char["fightPropMap"]["2002"] - char["fightPropMap"]["7"]
|
||||
# 元素精通
|
||||
fight_prop['elementalMastery'] = char["fightPropMap"]["28"]
|
||||
# 暴击率
|
||||
fight_prop['critRate'] = char["fightPropMap"]["20"]
|
||||
# 暴击伤害
|
||||
fight_prop['critDmg'] = char["fightPropMap"]["22"]
|
||||
# 充能效率
|
||||
fight_prop['energyRecharge'] = char["fightPropMap"]["23"]
|
||||
# 治疗&受治疗
|
||||
fight_prop['healBonus'] = char["fightPropMap"]["26"]
|
||||
fight_prop['healedBonus'] = char["fightPropMap"]["27"]
|
||||
# 物理伤害加成 & 抗性
|
||||
fight_prop['physicalDmgSub'] = char["fightPropMap"]["29"]
|
||||
fight_prop['physicalDmgBonus'] = char["fightPropMap"]["30"]
|
||||
# 伤害加成
|
||||
for i in range(40,47):
|
||||
if char["fightPropMap"][str(i)] > 0:
|
||||
fight_prop['dmgBonus'] = char["fightPropMap"][str(i)]
|
||||
break
|
||||
else:
|
||||
fight_prop['dmgBonus'] = 0
|
||||
|
||||
char_data['avatarFightProp'] = fight_prop
|
||||
|
||||
# 处理武器
|
||||
weapon_info = {}
|
||||
weapon_data = char['equipList'][-1]
|
||||
weapon_info['itemId'] = weapon_data['itemId']
|
||||
weapon_info['nameTextMapHash'] = weapon_data['flat']['nameTextMapHash']
|
||||
weapon_info['weaponIcon'] = weapon_data['flat']['icon']
|
||||
weapon_info['weaponType'] = weaponHash2Type[weapon_info['nameTextMapHash']]
|
||||
weapon_info['weaponName'] = weaponHash2Name[weapon_info['nameTextMapHash']]
|
||||
weapon_info['weaponStar'] = weapon_data['flat']['rankLevel']
|
||||
# 防止未精炼
|
||||
if 'promoteLevel' in weapon_data['weapon']:
|
||||
weapon_info['promoteLevel'] = weapon_data['weapon']['promoteLevel']
|
||||
else:
|
||||
weapon_info['promoteLevel'] = 0
|
||||
weapon_info['weaponLevel'] = weapon_data['weapon']['level']
|
||||
if 'affixMap' in weapon_data['weapon']:
|
||||
weapon_info['weaponAffix'] = list(weapon_data['weapon']['affixMap'].values())[0] + 1
|
||||
else:
|
||||
weapon_info['weaponAffix'] = 1
|
||||
weapon_info['weaponStats'] = []
|
||||
for k in weapon_data['flat']['weaponStats']:
|
||||
weapon_prop_temp = {}
|
||||
weapon_prop_temp['appendPropId'] = k['appendPropId']
|
||||
weapon_prop_temp['statName'] = propId2Name[k['appendPropId']]
|
||||
weapon_prop_temp['statValue'] = k['statValue']
|
||||
weapon_info['weaponStats'].append(weapon_prop_temp)
|
||||
# 武器特效,须请求API
|
||||
effect_raw = json.loads(httpx.get('https://info.minigg.cn/weapons?query={}'.format(weapon_info['weaponName'])).text)
|
||||
if 'effect' in effect_raw:
|
||||
effect = effect_raw['effect'].format(*effect_raw['r{}'.format(str(weapon_info['weaponAffix']))])
|
||||
else:
|
||||
effect = '无特效。'
|
||||
weapon_info['weaponEffect'] = effect
|
||||
char_data['weaponInfo'] = weapon_info
|
||||
|
||||
# 处理圣遗物
|
||||
artifacts_info = []
|
||||
artifacts_data = char['equipList'][:-1]
|
||||
artifact_set_list = []
|
||||
for artifact in artifacts_data:
|
||||
artifact_temp = {}
|
||||
artifact_temp['itemId'] = artifact['itemId']
|
||||
artifact_temp['nameTextMapHash'] = artifact['flat']['nameTextMapHash']
|
||||
artifact_temp['icon'] = artifact['flat']['icon']
|
||||
artifact_temp['aritifactName'] = icon2Name[artifact['flat']['icon']]
|
||||
artifact_temp['aritifactSetsName'] = artifact2attr[artifact_temp['aritifactName']]
|
||||
artifact_set_list.append(artifact_temp['aritifactSetsName'])
|
||||
artifact_temp['aritifactSetPiece'] = artifactId2Piece[artifact_temp['icon'].split('_')[-1]][0]
|
||||
artifact_temp['aritifactPieceName'] = artifactId2Piece[artifact_temp['icon'].split('_')[-1]][1]
|
||||
|
||||
artifact_temp['aritifactStar'] = artifact['flat']['rankLevel']
|
||||
artifact_temp['aritifactLevel'] = artifact['reliquary']['level'] - 1
|
||||
|
||||
artifact_temp['reliquaryMainstat'] = artifact['flat']['reliquaryMainstat']
|
||||
artifact_temp['reliquaryMainstat']['statName'] = propId2Name[artifact_temp['reliquaryMainstat']['mainPropId']]
|
||||
|
||||
artifact_temp['reliquarySubstats'] = artifact['flat']['reliquarySubstats']
|
||||
for sub in artifact_temp['reliquarySubstats']:
|
||||
sub['statName'] = propId2Name[sub['appendPropId']]
|
||||
artifacts_info.append(artifact_temp)
|
||||
|
||||
equipSetList = set(artifact_set_list)
|
||||
char_data['equipSets'] = {'type':'','set':''}
|
||||
char_data['equipList'] = artifacts_info
|
||||
for equip in equipSetList:
|
||||
if artifact_set_list.count(equip) >= 4:
|
||||
char_data['equipSets']['type'] = '4'
|
||||
char_data['equipSets']['set'] = equip
|
||||
break
|
||||
elif artifact_set_list.count(equip) == 1:
|
||||
pass
|
||||
elif artifact_set_list.count(equip) >= 2:
|
||||
char_data['equipSets']['type'] += '2'
|
||||
char_data['equipSets']['set'] += equip
|
||||
|
||||
with open(path / '{}.json'.format(avatarName),'w', encoding='UTF-8') as file:
|
||||
json.dump(char_data, file, ensure_ascii=False)
|
||||
char_name_list_str = ','.join(char_name_list)
|
||||
return f'UID{uid}刷新完成!\n本次缓存:{char_name_list_str}'
|
269
enkaToData/etc/ValueAttrMap.json
Normal file
@ -0,0 +1,269 @@
|
||||
{
|
||||
"神里绫人": [
|
||||
"血量",
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素精通"
|
||||
],
|
||||
"八重神子": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素精通",
|
||||
""
|
||||
],
|
||||
"申鹤": [
|
||||
"攻击力",
|
||||
"元素充能效率"
|
||||
],
|
||||
"云堇": [
|
||||
"防御力",
|
||||
"元素充能效率"
|
||||
],
|
||||
"荒泷一斗": [
|
||||
"防御力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"五郎": [
|
||||
"防御力",
|
||||
"元素充能效率"
|
||||
],
|
||||
"班尼特": [
|
||||
"血量",
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率"
|
||||
],
|
||||
"枫原万叶": [
|
||||
"元素精通",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率"
|
||||
],
|
||||
"雷电将军": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率"
|
||||
],
|
||||
"行秋": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率"
|
||||
],
|
||||
"钟离": [
|
||||
"血量",
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率"
|
||||
],
|
||||
"神里绫华": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"香菱": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率",
|
||||
"元素精通"
|
||||
],
|
||||
"胡桃": [
|
||||
"血量",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素精通"
|
||||
],
|
||||
"甘雨": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素精通"
|
||||
],
|
||||
"温迪": [
|
||||
"元素精通",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率"
|
||||
],
|
||||
"珊瑚宫心海": [
|
||||
"血量",
|
||||
"元素充能效率"
|
||||
],
|
||||
"莫娜": [
|
||||
"元素精通",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率"
|
||||
],
|
||||
"阿贝多": [
|
||||
"防御力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"迪奥娜": [
|
||||
"血量",
|
||||
"元素充能效率"
|
||||
],
|
||||
"优菈": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"达达利亚": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素精通"
|
||||
],
|
||||
"魈": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"宵宫": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素精通"
|
||||
],
|
||||
"九条裟罗": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率"
|
||||
],
|
||||
"琴": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率"
|
||||
],
|
||||
"菲谢尔": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"罗莎莉亚": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"可莉": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"凝光": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"北斗": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"刻晴": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"托马": [
|
||||
"血量",
|
||||
"元素充能效率"
|
||||
],
|
||||
"迪卢克": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素精通"
|
||||
],
|
||||
"芭芭拉": [
|
||||
"血量",
|
||||
"元素充能效率"
|
||||
],
|
||||
"诺艾尔": [
|
||||
"防御力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"旅行者": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"重云": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"七七": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率"
|
||||
],
|
||||
"凯亚": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"烟绯": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素精通"
|
||||
],
|
||||
"早柚": [
|
||||
"元素精通",
|
||||
"元素充能效率"
|
||||
],
|
||||
"安柏": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素精通"
|
||||
],
|
||||
"丽莎": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"埃洛伊": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"辛焱": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"砂糖": [
|
||||
"元素精通",
|
||||
"元素充能效率"
|
||||
],
|
||||
"雷泽": [
|
||||
"攻击力",
|
||||
"暴击率",
|
||||
"暴击伤害"
|
||||
],
|
||||
"夜兰": [
|
||||
"血量",
|
||||
"暴击率",
|
||||
"暴击伤害",
|
||||
"元素充能效率"
|
||||
],
|
||||
"久岐忍": [
|
||||
"血量",
|
||||
"元素充能效率",
|
||||
"元素精通"
|
||||
]
|
||||
}
|
1
enkaToData/etc/avatarCardOffsetMap.json
Normal file
@ -0,0 +1 @@
|
||||
{"凯特": [200, 0], "神里绫华": [-110, 10], "琴": [100, 30], "旅行者": [200, 0], "丽莎": [260, 110], "芭芭拉": [200, 70], "凯亚": [100, 130], "迪卢克": [-350, 0], "雷泽": [60, -40], "安柏": [220, -100], "温迪": [100, 0], "香菱": [150, 170], "北斗": [0, 0], "行秋": [250, 100], "魈": [40, -135], "凝光": [-100, 20], "可莉": [0, 0], "钟离": [200, 0], "菲谢尔": [150, 0], "班尼特": [30, -70], "达达利亚": [0, -40], "诺艾尔": [150, 110], "七七": [120, -100], "重云": [120, -10], "甘雨": [100, 70], "阿贝多": [-50, -15], "迪奥娜": [350, 50], "莫娜": [50, 0], "刻晴": [20, -15], "砂糖": [130, 30], "辛焱": [-40, -40], "罗莎莉亚": [160, 30], "胡桃": [-245, -25], "枫原万叶": [45, 160], "烟绯": [345, 130], "宵宫": [70, 0], "托马": [160, 20], "优菈": [110, 30], "雷电将军": [150, 0], "早柚": [-50, 0], "珊瑚宫心海": [100, 30], "五郎": [260, 0], "九条裟罗": [180, 110], "荒泷一斗": [100, 0], "八重神子": [80, 30], "夜兰": [140, 10], "埃洛伊": [280, 0], "申鹤": [-10, 30], "云堇": [350, 100], "久岐忍": [200, 0], "神里绫人": [150, 100], "队伍测试4号": [200, 0], "场景测试": [200, 0], "裸模1号": [200, 0], "裸男": [200, 0], "联机测试": [200, 0], "成男体型测试": [200, 0], "成女体型测试": [200, 0], "少女体型测试": [200, 0], "阿葵丽雅": [200, 0], "瑶瑶": [200, 0], "少女体型测试-二号机": [200, 0], "白盒少女": [200, 0], "大剑少女": [200, 0], "后武器测试A": [200, 0], "后武器测试B": [200, 0], "后武器测试C": [200, 0], "后武器测试D": [200, 0], "长枪成女": [200, 0], "单手剑成女测试": [200, 0], "Rx白盒": [200, 0], "少男体型测试": [200, 0], "女主新普攻": [200, 0], "男主新普攻": [200, 0], "重云(测试)": [200, 0], "测试角色": [200, 0], "七七(测试)": [200, 0], "迪奥娜(测试)": [200, 0]}
|
1
enkaToData/etc/avatarOffsetMap.json
Normal file
@ -0,0 +1 @@
|
||||
{"凯特": [200, 0], "神里绫华": [0, 0], "琴": [100, 0], "旅行者": [0, -160], "丽莎": [200, -100], "芭芭拉": [200, 0], "凯亚": [150, -150], "迪卢克": [300, 0], "雷泽": [400, 0], "安柏": [0, 200], "温迪": [100, 0], "香菱": [-100, -250], "北斗": [200, 0], "行秋": [250, -100], "魈": [200, 200], "凝光": [500, 0], "可莉": [0, 0], "钟离": [100, 0], "菲谢尔": [300, 0], "班尼特": [150, 150], "达达利亚": [0, 0], "诺艾尔": [300, -80], "七七": [200, 100], "重云": [200, 0], "甘雨": [100, 0], "阿贝多": [200, 0], "迪奥娜": [-300, 0], "莫娜": [200, 0], "刻晴": [400, 250], "砂糖": [50, 0], "辛焱": [250, 0], "罗莎莉亚": [200, 0], "胡桃": [560, 0], "枫原万叶": [150, -200], "烟绯": [-400, 0], "宵宫": [250, 0], "托马": [200, 0], "优菈": [-200, 0], "雷电将军": [100, 0], "早柚": [500, 0], "珊瑚宫心海": [200, 0], "五郎": [60, 0], "九条裟罗": [100, 0], "荒泷一斗": [100, 0], "八重神子": [300, 0], "夜兰": [80, 0], "埃洛伊": [60, 0], "申鹤": [360, 0], "云堇": [100, 0], "久岐忍": [200, 0], "神里绫人": [50, 0], "队伍测试4号": [200, 0], "场景测试": [200, 0], "裸模1号": [200, 0], "裸男": [200, 0], "联机测试": [200, 0], "成男体型测试": [200, 0], "成女体型测试": [200, 0], "少女体型测试": [200, 0], "阿葵丽雅": [200, 0], "瑶瑶": [200, 0], "少女体型测试-二号机": [200, 0], "白盒少女": [200, 0], "大剑少女": [200, 0], "后武器测试A": [200, 0], "后武器测试B": [200, 0], "后武器测试C": [200, 0], "后武器测试D": [200, 0], "长枪成女": [200, 0], "单手剑成女测试": [200, 0], "Rx白盒": [200, 0], "少男体型测试": [200, 0], "女主新普攻": [200, 0], "男主新普攻": [200, 0], "重云(测试)": [200, 0], "测试角色": [200, 0], "七七(测试)": [200, 0], "迪奥娜(测试)": [200, 0]}
|
1
enkaToData/etc/dmgMap.json
Normal file
1
enkaToData/etc/propMap.json
Normal file
@ -0,0 +1 @@
|
||||
{"1": "FIGHT_PROP_BASE_HP", "2": "FIGHT_PROP_HP", "3": "FIGHT_PROP_HP_PERCENT", "4": "FIGHT_PROP_BASE_ATTACK", "5": "FIGHT_PROP_ATTACK", "6": "FIGHT_PROP_ATTACK_PERCENT", "7": "FIGHT_PROP_BASE_DEFENSE", "8": "FIGHT_PROP_DEFENSE", "9": "FIGHT_PROP_DEFENSE_PERCENT", "10": "FIGHT_PROP_BASE_SPEED", "11": "FIGHT_PROP_SPEED_PERCENT", "12": "FIGHT_PROP_HP_MP_PERCENT", "13": "FIGHT_PROP_ATTACK_MP_PERCENT", "20": "FIGHT_PROP_CRITICAL", "21": "FIGHT_PROP_ANTI_CRITICAL", "22": "FIGHT_PROP_CRITICAL_HURT", "23": "FIGHT_PROP_CHARGE_EFFICIENCY", "24": "FIGHT_PROP_ADD_HURT", "25": "FIGHT_PROP_SUB_HURT", "26": "FIGHT_PROP_HEAL_ADD", "27": "FIGHT_PROP_HEALED_ADD", "28": "FIGHT_PROP_ELEMENT_MASTERY", "29": "FIGHT_PROP_PHYSICAL_SUB_HURT", "30": "FIGHT_PROP_PHYSICAL_ADD_HURT", "31": "FIGHT_PROP_DEFENCE_IGNORE_RATIO", "32": "FIGHT_PROP_DEFENCE_IGNORE_DELTA", "40": "FIGHT_PROP_FIRE_ADD_HURT", "41": "FIGHT_PROP_ELEC_ADD_HURT", "42": "FIGHT_PROP_WATER_ADD_HURT", "43": "FIGHT_PROP_GRASS_ADD_HURT", "44": "FIGHT_PROP_WIND_ADD_HURT", "45": "FIGHT_PROP_ROCK_ADD_HURT", "46": "FIGHT_PROP_ICE_ADD_HURT", "47": "FIGHT_PROP_HIT_HEAD_ADD_HURT", "50": "FIGHT_PROP_FIRE_SUB_HURT", "51": "FIGHT_PROP_ELEC_SUB_HURT", "52": "FIGHT_PROP_WATER_SUB_HURT", "53": "FIGHT_PROP_GRASS_SUB_HURT", "54": "FIGHT_PROP_WIND_SUB_HURT", "55": "FIGHT_PROP_ROCK_SUB_HURT", "56": "FIGHT_PROP_ICE_SUB_HURT", "60": "FIGHT_PROP_EFFECT_HIT", "61": "FIGHT_PROP_EFFECT_RESIST", "62": "FIGHT_PROP_FREEZE_RESIST", "63": "FIGHT_PROP_TORPOR_RESIST", "64": "FIGHT_PROP_DIZZY_RESIST", "65": "FIGHT_PROP_FREEZE_SHORTEN", "66": "FIGHT_PROP_TORPOR_SHORTEN", "67": "FIGHT_PROP_DIZZY_SHORTEN", "70": "FIGHT_PROP_MAX_FIRE_ENERGY", "71": "FIGHT_PROP_MAX_ELEC_ENERGY", "72": "FIGHT_PROP_MAX_WATER_ENERGY", "73": "FIGHT_PROP_MAX_GRASS_ENERGY", "74": "FIGHT_PROP_MAX_WIND_ENERGY", "75": "FIGHT_PROP_MAX_ICE_ENERGY", "76": "FIGHT_PROP_MAX_ROCK_ENERGY", "80": "FIGHT_PROP_SKILL_CD_MINUS_RATIO", "81": "FIGHT_PROP_SHIELD_COST_MINUS_RATIO", "1000": "FIGHT_PROP_CUR_FIRE_ENERGY", "1001": "FIGHT_PROP_CUR_ELEC_ENERGY", "1002": "FIGHT_PROP_CUR_WATER_ENERGY", "1003": "FIGHT_PROP_CUR_GRASS_ENERGY", "1004": "FIGHT_PROP_CUR_WIND_ENERGY", "1005": "FIGHT_PROP_CUR_ICE_ENERGY", "1006": "FIGHT_PROP_CUR_ROCK_ENERGY", "1010": "FIGHT_PROP_CUR_HP", "2000": "FIGHT_PROP_MAX_HP", "2001": "FIGHT_PROP_CUR_ATTACK", "2002": "FIGHT_PROP_CUR_DEFENSE", "2003": "FIGHT_PROP_CUR_SPEED", "3000": "FIGHT_PROP_NONEXTRA_ATTACK", "3001": "FIGHT_PROP_NONEXTRA_DEFENSE", "3002": "FIGHT_PROP_NONEXTRA_CRITICAL", "3003": "FIGHT_PROP_NONEXTRA_ANTI_CRITICAL", "3004": "FIGHT_PROP_NONEXTRA_CRITICAL_HURT", "3005": "FIGHT_PROP_NONEXTRA_CHARGE_EFFICIENCY", "3006": "FIGHT_PROP_NONEXTRA_ELEMENT_MASTERY", "3007": "FIGHT_PROP_NONEXTRA_PHYSICAL_SUB_HURT", "3008": "FIGHT_PROP_NONEXTRA_FIRE_ADD_HURT", "3009": "FIGHT_PROP_NONEXTRA_ELEC_ADD_HURT", "3010": "FIGHT_PROP_NONEXTRA_WATER_ADD_HURT", "3011": "FIGHT_PROP_NONEXTRA_GRASS_ADD_HURT", "3012": "FIGHT_PROP_NONEXTRA_WIND_ADD_HURT", "3013": "FIGHT_PROP_NONEXTRA_ROCK_ADD_HURT", "3014": "FIGHT_PROP_NONEXTRA_ICE_ADD_HURT", "3015": "FIGHT_PROP_NONEXTRA_FIRE_SUB_HURT", "3016": "FIGHT_PROP_NONEXTRA_ELEC_SUB_HURT", "3017": "FIGHT_PROP_NONEXTRA_WATER_SUB_HURT", "3018": "FIGHT_PROP_NONEXTRA_GRASS_SUB_HURT", "3019": "FIGHT_PROP_NONEXTRA_WIND_SUB_HURT", "3020": "FIGHT_PROP_NONEXTRA_ROCK_SUB_HURT", "3021": "FIGHT_PROP_NONEXTRA_ICE_SUB_HURT", "3022": "FIGHT_PROP_NONEXTRA_SKILL_CD_MINUS_RATIO", "3023": "FIGHT_PROP_NONEXTRA_SHIELD_COST_MINUS_RATIO", "3024": "FIGHT_PROP_NONEXTRA_PHYSICAL_ADD_HURT"}
|
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_10000005.png
Normal file
After Width: | Height: | Size: 800 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_10000007.png
Normal file
After Width: | Height: | Size: 722 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Albedo.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Aloy.png
Normal file
After Width: | Height: | Size: 772 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Ambor.png
Normal file
After Width: | Height: | Size: 595 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Ambor_TT.png
Normal file
After Width: | Height: | Size: 609 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Ayaka.png
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Ayato.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Barbara.png
Normal file
After Width: | Height: | Size: 635 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Beidou.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Bennett.png
Normal file
After Width: | Height: | Size: 892 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Chongyun.png
Normal file
After Width: | Height: | Size: 935 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Diluc.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Diona.png
Normal file
After Width: | Height: | Size: 440 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Eula.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Feiyan.png
Normal file
After Width: | Height: | Size: 858 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Fischl.png
Normal file
After Width: | Height: | Size: 694 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Ganyu.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Gorou.png
Normal file
After Width: | Height: | Size: 642 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Heizo.png
Normal file
After Width: | Height: | Size: 237 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Hutao.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Itto.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Kaeya.png
Normal file
After Width: | Height: | Size: 590 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Kazuha.png
Normal file
After Width: | Height: | Size: 759 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Keqing.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Klee.png
Normal file
After Width: | Height: | Size: 486 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Kokomi.png
Normal file
After Width: | Height: | Size: 964 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Lisa.png
Normal file
After Width: | Height: | Size: 495 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Mona.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Mona_TT.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Ningguang.png
Normal file
After Width: | Height: | Size: 902 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Noel.png
Normal file
After Width: | Height: | Size: 636 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Qin.png
Normal file
After Width: | Height: | Size: 974 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Qin_TT.png
Normal file
After Width: | Height: | Size: 979 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Qiqi.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Razor.png
Normal file
After Width: | Height: | Size: 949 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Rosaria #2526820.png
Normal file
After Width: | Height: | Size: 749 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Rosaria.png
Normal file
After Width: | Height: | Size: 795 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Rosaria_TT.png
Normal file
After Width: | Height: | Size: 807 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Sara.png
Normal file
After Width: | Height: | Size: 574 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Sayu.png
Normal file
After Width: | Height: | Size: 613 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Shenhe.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Shinobu.png
Normal file
After Width: | Height: | Size: 462 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Shougun.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Sucrose.png
Normal file
After Width: | Height: | Size: 693 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Tartaglia.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Tohma.png
Normal file
After Width: | Height: | Size: 792 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Venti.png
Normal file
After Width: | Height: | Size: 996 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Xiangling.png
Normal file
After Width: | Height: | Size: 579 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Xiao.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Xingqiu.png
Normal file
After Width: | Height: | Size: 542 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Xinyan.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Yae.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Yelan.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Yoimiya.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Yunjin.png
Normal file
After Width: | Height: | Size: 474 KiB |
BIN
enkaToData/gachaImg/UI_Gacha_AvatarImg_Zhongli.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
enkaToData/icon/Skill_A_01.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
enkaToData/icon/Skill_A_02.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
enkaToData/icon/Skill_A_03.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
enkaToData/icon/Skill_A_04.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
enkaToData/icon/Skill_A_CC_Electric.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
enkaToData/icon/Skill_A_CC_Rock.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
enkaToData/icon/Skill_A_Catalyst_MD.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
enkaToData/icon/Skill_A_Dvalin_AirGun.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
enkaToData/icon/Skill_A_Thunderbolt.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
enkaToData/icon/Skill_B_Barbara_01.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
enkaToData/icon/Skill_C_ChargeNormal.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
enkaToData/icon/Skill_C_ElectricTransfer.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
enkaToData/icon/Skill_C_FireCracker.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
enkaToData/icon/Skill_C_Stamine_1.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
enkaToData/icon/Skill_C_Stamine_2.png
Normal file
After Width: | Height: | Size: 1.6 KiB |