feat: 评分

This commit is contained in:
bietiaop 2024-07-28 23:43:25 +08:00
parent 1441b8efcc
commit 394bea4c87
9 changed files with 1024 additions and 334 deletions

106
lib/score.js Normal file
View file

@ -0,0 +1,106 @@
import { getMapData } from '../utils/file.js';
const scoreData = getMapData('EquipScore');
const baseValueData = getMapData('EquipBaseValue');
/**
* 是否有分数数据
* @param {string} charID 角色id
* @returns {boolean}
*/
export const hasScoreData = charID => {
return (
scoreData.hasOwnProperty(charID) &&
Object.keys(scoreData[charID]).length > 0
);
};
/**
* 获取装备属性基准分数
* @param {string} charID 角色id
* @param {string} propertyID 属性id
* @returns {number}
*/
export const getEquipPropertyBaseScore = (charID, propertyID) => {
const score = scoreData[charID][propertyID] || 0;
return score;
};
/**
* 获取装备属性分数
* @param {string} charID 角色id
* @param {string} propertyID 属性id
* @param {string} value 属性值
* @returns {number}
*/
export const getEquipPropertyScore = (charID, propertyID, value) => {
if (value.includes('%')) {
value = value.replace('%', '');
}
value = Number(value);
const baseScore = getEquipPropertyBaseScore(charID, propertyID);
let finalScore = baseScore * value;
switch (propertyID) {
// 小生命
case '11103':
finalScore = value * 0.043 * baseScore * 1;
break;
// 大生命
case '11102':
finalScore = value * 1.6 * baseScore * 100;
break;
// 小攻击
case '12103':
finalScore = value * 0.25 * baseScore * 1;
break;
// 大攻击
case '12102':
finalScore = value * 1.6 * baseScore * 100;
break;
// 小防御
case '13103':
finalScore = value * 0.32 * baseScore * 1;
break;
// 大防御
case '13102':
finalScore = value * 1 * baseScore * 100;
break;
// 暴击
case '20103':
finalScore = value * 2 * baseScore * 100;
break;
// 暴击伤害
case '21103':
finalScore = value * 1 * baseScore * 100;
break;
// 穿透值
case '23203':
finalScore = value * 0.53 * baseScore * 1;
break;
// 异常精通
case '31403':
finalScore = value * 0.5 * baseScore * 100;
break;
default:
break;
}
return finalScore;
};
/**
* 获取词条强化次数
* @param {string} propertyID 属性id
* @param {string} value 属性值
* @returns {number}
*/
export const getEquipPropertyEnhanceCount = (propertyID, value) => {
if (value.includes('%')) {
value = value.replace('%', '');
}
value = Number(value);
const baseValue = baseValueData[propertyID] || 0;
if (baseValue === 0) {
return 0;
}
return value / baseValue - 1;
};

View file

@ -6,7 +6,9 @@ import { Property } from './property.js';
import { Skill } from './skill.js';
import { relice_ability } from './damage/relice.js';
import { weapon_ability } from './damage/weapon.js';
import { avatar_ability } from './damage/avatar.js';
import { avatar_ability, has_calculation } from './damage/avatar.js';
import { hasScoreData } from '../lib/score.js';
import _ from 'lodash';
import fs from 'fs';
import path from 'path';
@ -253,6 +255,9 @@ export class ZZZAvatarInfo {
this.element_str = element.IDToElement(element_type);
/** @type {boolean} */
this.isNew = isNew;
for (const equip of this.equip) {
equip.get_score(this.id);
}
}
getProperty(name) {
@ -364,6 +369,9 @@ export class ZZZAvatarInfo {
* value: {name: string, value: number}[]
* }[]} */
get damages() {
if (!has_calculation(this.id)) {
return [];
}
/** 处理基础数据 */
let base_detail = this.damage_basic_properties.base_detail;
let bonus_detail = this.damage_basic_properties.bonus_detail;
@ -392,6 +400,44 @@ export class ZZZAvatarInfo {
return damagelist;
}
/** @type {number|boolean} */
get equip_score() {
if (hasScoreData(this.id)) {
let score = 0;
for (const equip of this.equip) {
score += equip.score;
}
return score;
}
return false;
}
/** @type {'C'|'B'|'A'|'S'|'SS'|'SSS'|'ACE'|false} */
get equip_comment() {
if (this.equip_score <= 130) {
return 'C';
}
if (this.equip_score <= 150) {
return 'B';
}
if (this.equip_score <= 170) {
return 'A';
}
if (this.equip_score <= 190) {
return 'S';
}
if (this.equip_score <= 210) {
return 'SS';
}
if (this.equip_score <= 240) {
return 'SSS';
}
if (this.equip_score > 240) {
return 'ACE';
}
return false;
}
async get_basic_assets() {
const result = await getSquareAvatar(this.id);
/** @type {string} */

View file

@ -14,341 +14,346 @@ const skilldict = getMapData('SkillData');
* }[]} 伤害列表
*/
export const avatar_ability = (data, base_detail, bonus_detail) => {
const damagelist = [];
switch (data.id) {
case 1191:{
/** 处理命座加成 */
if (data.rank >= 1) {
const CriticalChanceBase = _.get(bonus_detail, 'CriticalChanceBase', 0);
bonus_detail['CriticalChanceBase'] = CriticalChanceBase + 0.12;
}
if (data.rank >= 2) {
const ES_CriticalDamageBase = _.get(
bonus_detail,
'ES_CriticalDamageBase',
0
);
bonus_detail['ES_CriticalDamageBase'] = ES_CriticalDamageBase + 0.6;
const EH_CriticalDamageBase = _.get(
bonus_detail,
'EH_CriticalDamageBase',
0
);
bonus_detail['EH_CriticalDamageBase'] = EH_CriticalDamageBase + 0.6;
}
if (data.rank >= 6) {
const PenRatio = _.get(bonus_detail, 'PenRatioBase', 0);
bonus_detail['PenRatioBase'] = PenRatio + 0.2;
const damagelist = [];
switch (data.id) {
case 1191: {
/** 处理命座加成 */
if (data.rank >= 1) {
const CriticalChanceBase = _.get(bonus_detail, 'CriticalChanceBase', 0);
bonus_detail['CriticalChanceBase'] = CriticalChanceBase + 0.12;
}
if (data.rank >= 2) {
const ES_CriticalDamageBase = _.get(
bonus_detail,
'ES_CriticalDamageBase',
0
);
bonus_detail['ES_CriticalDamageBase'] = ES_CriticalDamageBase + 0.6;
const EH_CriticalDamageBase = _.get(
bonus_detail,
'EH_CriticalDamageBase',
0
);
bonus_detail['EH_CriticalDamageBase'] = EH_CriticalDamageBase + 0.6;
}
if (data.rank >= 6) {
const PenRatio = _.get(bonus_detail, 'PenRatioBase', 0);
bonus_detail['PenRatioBase'] = PenRatio + 0.2;
const C_DmgAdd = _.get(bonus_detail, 'C_DmgAdd', 0);
bonus_detail['C_DmgAdd'] = C_DmgAdd + 2.5;
}
const C_DmgAdd = _.get(bonus_detail, 'C_DmgAdd', 0);
bonus_detail['C_DmgAdd'] = C_DmgAdd + 2.5;
}
/** 处理天赋加成 */
/** 获取天赋等级与加成倍率 */
const CDB = getskilllevelnum(data.id, data.skills, 'T', 'T');
const C_CriticalDamageBase = _.get(
bonus_detail,
'C_CriticalDamageBase',
0
);
bonus_detail['C_CriticalDamageBase'] = C_CriticalDamageBase + CDB;
const A_CriticalDamageBase = _.get(
bonus_detail,
'A_CriticalDamageBase',
0
);
bonus_detail['A_CriticalDamageBase'] = A_CriticalDamageBase + CDB;
/** 处理天赋加成 */
/** 获取天赋等级与加成倍率 */
const CDB = getskilllevelnum(data.id, data.skills, 'T', 'T');
const C_CriticalDamageBase = _.get(
bonus_detail,
'C_CriticalDamageBase',
0
);
bonus_detail['C_CriticalDamageBase'] = C_CriticalDamageBase + CDB;
const A_CriticalDamageBase = _.get(
bonus_detail,
'A_CriticalDamageBase',
0
);
bonus_detail['A_CriticalDamageBase'] = A_CriticalDamageBase + CDB;
const IceDmgAdd = _.get(bonus_detail, 'Ice_DmgAdd', 0);
bonus_detail['Ice_DmgAdd'] = IceDmgAdd + 0.3;
const IceDmgAdd = _.get(bonus_detail, 'Ice_DmgAdd', 0);
bonus_detail['Ice_DmgAdd'] = IceDmgAdd + 0.3;
/** 计算伤害 */
/** 计算普攻伤害 */
const skill_multiplier1 = getskilllevelnum(
data.id,
data.skills,
'A',
'A'
);
const damagelist1 = calculate_damage(
base_detail,
bonus_detail,
'A',
'A',
'Ice',
skill_multiplier1,
data.level
);
const damage1 = {
title: '普通攻击:急冻修剪法',
value: damagelist1,
};
damagelist.push(damage1);
/** 计算伤害 */
/** 计算普攻伤害 */
const skill_multiplier1 = getskilllevelnum(
data.id,
data.skills,
'A',
'A'
);
const damagelist1 = calculate_damage(
base_detail,
bonus_detail,
'A',
'A',
'Ice',
skill_multiplier1,
data.level
);
const damage1 = {
title: '普通攻击:急冻修剪法',
value: damagelist1,
};
damagelist.push(damage1);
/** 计算冲刺伤害 */
const skill_multiplier2 = getskilllevelnum(
data.id,
data.skills,
'C',
'C'
);
const damagelist2 = calculate_damage(
base_detail,
bonus_detail,
'C',
'C',
'Ice',
skill_multiplier2,
data.level
);
const damage2 = {
title: '冲刺攻击:冰渊潜袭',
value: damagelist2,
};
damagelist.push(damage2);
/** 计算冲刺伤害 */
const skill_multiplier2 = getskilllevelnum(
data.id,
data.skills,
'C',
'C'
);
const damagelist2 = calculate_damage(
base_detail,
bonus_detail,
'C',
'C',
'Ice',
skill_multiplier2,
data.level
);
const damage2 = {
title: '冲刺攻击:冰渊潜袭',
value: damagelist2,
};
damagelist.push(damage2);
/** 计算特殊技伤害 */
const skill_multiplier3 = getskilllevelnum(
data.id,
data.skills,
'E',
'EH'
);
const damagelist3 = calculate_damage(
base_detail,
bonus_detail,
'EUP',
'EH',
'Ice',
skill_multiplier3,
data.level
);
const damage3 = {
title: '强化特殊技:横扫',
value: damagelist3,
};
damagelist.push(damage3);
/** 计算特殊技伤害 */
const skill_multiplier3 = getskilllevelnum(
data.id,
data.skills,
'E',
'EH'
);
const damagelist3 = calculate_damage(
base_detail,
bonus_detail,
'EUP',
'EH',
'Ice',
skill_multiplier3,
data.level
);
const damage3 = {
title: '强化特殊技:横扫',
value: damagelist3,
};
damagelist.push(damage3);
const skill_multiplier4 = getskilllevelnum(
data.id,
data.skills,
'E',
'ES'
);
const damagelist4 = calculate_damage(
base_detail,
bonus_detail,
'EUP',
'ES',
'Ice',
skill_multiplier4,
data.level
);
const damage4 = {
title: '强化特殊技:鲨卷风',
value: damagelist4,
};
damagelist.push(damage4);
const skill_multiplier4 = getskilllevelnum(
data.id,
data.skills,
'E',
'ES'
);
const damagelist4 = calculate_damage(
base_detail,
bonus_detail,
'EUP',
'ES',
'Ice',
skill_multiplier4,
data.level
);
const damage4 = {
title: '强化特殊技:鲨卷风',
value: damagelist4,
};
damagelist.push(damage4);
/** 计算连携技伤害 */
const skill_multiplier5 = getskilllevelnum(
data.id,
data.skills,
'R',
'RL'
);
const damagelist5 = calculate_damage(
base_detail,
bonus_detail,
'RL',
'RL',
'Ice',
skill_multiplier5,
data.level
);
const damage5 = {
title: '连携技:雪崩',
value: damagelist5,
};
damagelist.push(damage5);
/** 计算连携技伤害 */
const skill_multiplier5 = getskilllevelnum(
data.id,
data.skills,
'R',
'RL'
);
const damagelist5 = calculate_damage(
base_detail,
bonus_detail,
'RL',
'RL',
'Ice',
skill_multiplier5,
data.level
);
const damage5 = {
title: '连携技:雪崩',
value: damagelist5,
};
damagelist.push(damage5);
/** 计算终结技伤害 */
const skill_multiplier6 = getskilllevelnum(
data.id,
data.skills,
'R',
'R'
);
const damagelist6 = calculate_damage(
base_detail,
bonus_detail,
'R',
'R',
'Ice',
skill_multiplier6,
data.level
);
const damage6 = {
title: '终结技:永冬狂宴',
value: damagelist6,
};
damagelist.push(damage6);
logger.debug('伤害', damagelist);
break;
}
case 1241:{
/** 处理命座加成 */
if (data.rank >= 2) {
let A_DmgAdd = _.get(bonus_detail, 'A_DmgAdd', 0);
bonus_detail['A_DmgAdd'] = A_DmgAdd + 0.5;
let C_DmgAdd = _.get(bonus_detail, 'C_DmgAdd', 0);
bonus_detail['C_DmgAdd'] = C_DmgAdd + 0.5;
}
if (data.rank >= 4) {
let Ether_ResistancePenetration = _.get(bonus_detail, 'Ether_ResistancePenetration', 0);
bonus_detail['Ether_ResistancePenetration'] = Ether_ResistancePenetration + 0.25;
}
/** 处理天赋加成 */
/** 获取天赋等级与加成倍率 */
const DMG_ADD = getskilllevelnum(data.id, data.skills, 'T', 'T');
let A_DmgAdd = _.get(bonus_detail, 'A_DmgAdd', 0);
bonus_detail['A_DmgAdd'] = A_DmgAdd + DMG_ADD;
let C_DmgAdd = _.get(bonus_detail, 'C_DmgAdd', 0);
bonus_detail['C_DmgAdd'] = C_DmgAdd + DMG_ADD;
let CriticalChanceBase = _.get(bonus_detail, 'CriticalChanceBase', 0);
bonus_detail['CriticalChanceBase'] = CriticalChanceBase + 0.3;
/** 计算伤害 */
/** 计算普攻伤害 */
const skill_multiplier1 = getskilllevelnum(
data.id,
data.skills,
'A',
'A'
);
const damagelist1 = calculate_damage(
base_detail,
bonus_detail,
'A',
'A',
'Ether',
skill_multiplier1,
data.level
);
const damage1 = {
title: '普通攻击:请勿抵抗',
value: damagelist1,
};
damagelist.push(damage1);
/** 计算冲刺伤害 */
const skill_multiplier2 = getskilllevelnum(
data.id,
data.skills,
'C',
'C'
);
const damagelist2 = calculate_damage(
base_detail,
bonus_detail,
'C',
'C',
'Ether',
skill_multiplier2,
data.level
);
const damage2 = {
title: '冲刺攻击:火力压制',
value: damagelist2,
};
damagelist.push(damage2);
/** 计算强化特殊技伤害 */
const skill_multiplier3 = getskilllevelnum(
data.id,
data.skills,
'E',
'EUP'
);
let damagelist3 = calculate_damage(
base_detail,
bonus_detail,
'EUP',
'EUP',
'Ether',
skill_multiplier3,
data.level
);
if (data.rank >= 6) {
let damagelist_add = calculate_damage(
base_detail,
bonus_detail,
'EUP',
'EUP',
'Ether',
2.2,
data.level
);
damagelist3['cd'] = damagelist3['cd'] + damagelist_add['cd'] * 4
damagelist3['qw'] = damagelist3['qw'] + damagelist_add['qw'] * 4
}
const damage3 = {
title: '强化特殊技:全弹连射',
value: damagelist3,
};
damagelist.push(damage3);
/** 计算连携技伤害 */
const skill_multiplier4 = getskilllevelnum(
data.id,
data.skills,
'R',
'RL'
);
const damagelist4 = calculate_damage(
base_detail,
bonus_detail,
'RL',
'RL',
'Ether',
skill_multiplier4,
data.level
);
const damage4 = {
title: '连携技:歼灭模式',
value: damagelist4,
};
damagelist.push(damage4);
/** 计算终结技伤害 */
const skill_multiplier5 = getskilllevelnum(
data.id,
data.skills,
'R',
'R'
);
const damagelist5 = calculate_damage(
base_detail,
bonus_detail,
'R',
'R',
'Ether',
skill_multiplier5,
data.level
);
const damage5 = {
title: '终结技歼灭模式MAX',
value: damagelist5,
};
damagelist.push(damage5);
break;
}
}
return damagelist;
/** 计算终结技伤害 */
const skill_multiplier6 = getskilllevelnum(
data.id,
data.skills,
'R',
'R'
);
const damagelist6 = calculate_damage(
base_detail,
bonus_detail,
'R',
'R',
'Ice',
skill_multiplier6,
data.level
);
const damage6 = {
title: '终结技:永冬狂宴',
value: damagelist6,
};
damagelist.push(damage6);
logger.debug('伤害', damagelist);
break;
}
case 1241: {
/** 处理命座加成 */
if (data.rank >= 2) {
let A_DmgAdd = _.get(bonus_detail, 'A_DmgAdd', 0);
bonus_detail['A_DmgAdd'] = A_DmgAdd + 0.5;
let C_DmgAdd = _.get(bonus_detail, 'C_DmgAdd', 0);
bonus_detail['C_DmgAdd'] = C_DmgAdd + 0.5;
}
if (data.rank >= 4) {
let Ether_ResistancePenetration = _.get(
bonus_detail,
'Ether_ResistancePenetration',
0
);
bonus_detail['Ether_ResistancePenetration'] =
Ether_ResistancePenetration + 0.25;
}
/** 处理天赋加成 */
/** 获取天赋等级与加成倍率 */
const DMG_ADD = getskilllevelnum(data.id, data.skills, 'T', 'T');
let A_DmgAdd = _.get(bonus_detail, 'A_DmgAdd', 0);
bonus_detail['A_DmgAdd'] = A_DmgAdd + DMG_ADD;
let C_DmgAdd = _.get(bonus_detail, 'C_DmgAdd', 0);
bonus_detail['C_DmgAdd'] = C_DmgAdd + DMG_ADD;
let CriticalChanceBase = _.get(bonus_detail, 'CriticalChanceBase', 0);
bonus_detail['CriticalChanceBase'] = CriticalChanceBase + 0.3;
/** 计算伤害 */
/** 计算普攻伤害 */
const skill_multiplier1 = getskilllevelnum(
data.id,
data.skills,
'A',
'A'
);
const damagelist1 = calculate_damage(
base_detail,
bonus_detail,
'A',
'A',
'Ether',
skill_multiplier1,
data.level
);
const damage1 = {
title: '普通攻击:请勿抵抗',
value: damagelist1,
};
damagelist.push(damage1);
/** 计算冲刺伤害 */
const skill_multiplier2 = getskilllevelnum(
data.id,
data.skills,
'C',
'C'
);
const damagelist2 = calculate_damage(
base_detail,
bonus_detail,
'C',
'C',
'Ether',
skill_multiplier2,
data.level
);
const damage2 = {
title: '冲刺攻击:火力压制',
value: damagelist2,
};
damagelist.push(damage2);
/** 计算强化特殊技伤害 */
const skill_multiplier3 = getskilllevelnum(
data.id,
data.skills,
'E',
'EUP'
);
let damagelist3 = calculate_damage(
base_detail,
bonus_detail,
'EUP',
'EUP',
'Ether',
skill_multiplier3,
data.level
);
if (data.rank >= 6) {
let damagelist_add = calculate_damage(
base_detail,
bonus_detail,
'EUP',
'EUP',
'Ether',
2.2,
data.level
);
damagelist3['cd'] = damagelist3['cd'] + damagelist_add['cd'] * 4;
damagelist3['qw'] = damagelist3['qw'] + damagelist_add['qw'] * 4;
}
const damage3 = {
title: '强化特殊技:全弹连射',
value: damagelist3,
};
damagelist.push(damage3);
/** 计算连携技伤害 */
const skill_multiplier4 = getskilllevelnum(
data.id,
data.skills,
'R',
'RL'
);
const damagelist4 = calculate_damage(
base_detail,
bonus_detail,
'RL',
'RL',
'Ether',
skill_multiplier4,
data.level
);
const damage4 = {
title: '连携技:歼灭模式',
value: damagelist4,
};
damagelist.push(damage4);
/** 计算终结技伤害 */
const skill_multiplier5 = getskilllevelnum(
data.id,
data.skills,
'R',
'R'
);
const damagelist5 = calculate_damage(
base_detail,
bonus_detail,
'R',
'R',
'Ether',
skill_multiplier5,
data.level
);
const damage5 = {
title: '终结技歼灭模式MAX',
value: damagelist5,
};
damagelist.push(damage5);
break;
}
}
return damagelist;
};
export const getskilllevelnum = (avatarId, skills, skilltype, skillname) => {
@ -365,3 +370,7 @@ export const getskilllevelnum = (avatarId, skills, skilltype, skillname) => {
) - 1;
return skilldict[avatarId][skillname][skilllevel];
};
export const has_calculation = avatarId => {
return Object.keys(skilldict).includes(avatarId.toString());
};

View file

@ -1,5 +1,10 @@
import { property } from '../lib/convert.js';
import { getSuitImage, getWeaponImage } from '../lib/download.js';
import {
getEquipPropertyBaseScore,
getEquipPropertyEnhanceCount,
getEquipPropertyScore,
} from '../lib/score.js';
/**
* @class
@ -30,6 +35,24 @@ export class EquipProperty {
this.classname = property.idToClassName(property_id);
}
/**
* 获取属性分数
* @param {string} charID
* @returns {number}
*/
get_score(charID) {
/** @type {number} */
this.score = getEquipPropertyScore(charID, this.property_id, this.base);
/** @type {number} */
this.base_score = getEquipPropertyBaseScore(charID, this.property_id);
return this.score;
}
/** @type {number} */
get count() {
return getEquipPropertyEnhanceCount(this.property_id, this.base);
}
}
/**
@ -60,6 +83,25 @@ export class EquipMainProperty {
this.base = base;
this.classname = property.idToClassName(property_id);
this.score = 0;
}
/**
* 获取属性分数
* @param {string} charID
* @returns {number}
*/
get_score(charID) {
/** @type {number} */
const _score = getEquipPropertyBaseScore(
charID,
this.property_id,
this.base
);
if (_score > 0) {
this.score = 1;
}
return this.score;
}
}
@ -120,6 +162,8 @@ export class Equip {
this.equip_suit;
/** @type {number} */
this.equipment_type;
/** @type {boolean|number} */
this.score = false;
const {
id,
@ -159,6 +203,56 @@ export class Equip {
const result = await getSuitImage(this.id);
this.suit_icon = result;
}
/**
* 获取装备属性分数
* @param {string} charID
* @returns {number}
*/
get_score(charID) {
this.score = this.properties.reduce(
(acc, item) => acc + item.get_score(charID),
0
);
const additional = this.main_properties.reduce(
(acc, item) => acc + item.get_score(charID),
0
);
if (this.equipment_type === 4) {
this.score += 4.8 * additional;
} else if (this.equipment_type === 5) {
this.score += 9.6 * additional;
} else if (this.equipment_type === 6) {
this.score += 4.8 * additional;
}
return this.score;
}
/** @type {'C'|'B'|'A'|'S'|'SS'|'SSS'|'ACE'|false} */
get comment() {
if (this.score <= 8) {
return 'C';
}
if (this.score <= 13) {
return 'B';
}
if (this.score <= 18) {
return 'A';
}
if (this.score <= 23) {
return 'S';
}
if (this.score <= 28) {
return 'SS';
}
if (this.score <= 33) {
return 'SSS';
}
if (this.score > 33) {
return 'ACE';
}
return false;
}
}
/**

View file

@ -0,0 +1,12 @@
{
"11103": 112,
"11102": 3,
"12103": 19,
"12102": 3,
"13103": 15,
"13102": 4.8,
"20103": 2.4,
"21103": 4.8,
"23203": 9,
"31403": 9
}

View file

@ -0,0 +1,82 @@
{
"1011": {},
"1021": {},
"1031": {},
"1041": {},
"1061": {},
"1081": {},
"1091": {},
"1101": {},
"1111": {},
"1121": {},
"1131": {},
"1141": {
"11103": 0,
"11102": 0,
"12103": 1,
"12102": 1,
"13103": 0,
"13102": 0,
"20103": 0.75,
"21103": 0.75,
"23203": 0.75,
"31403": 0
},
"1151": {
"11103": 0,
"11102": 0,
"12103": 1,
"12102": 1,
"13103": 0,
"13102": 0,
"20103": 0.75,
"21103": 0.75,
"23203": 0.5,
"31403": 0.5
},
"1161": {},
"1181": {},
"1191": {
"11103": 0,
"11102": 0,
"12103": 0.75,
"12102": 0.75,
"13103": 0,
"13102": 0,
"20103": 1,
"21103": 1,
"23203": 0.75,
"31403": 0
},
"1201": {},
"1211": {
"11103": 0,
"11102": 0,
"12103": 0.5,
"12102": 0.5,
"13103": 0,
"13102": 0,
"20103": 0.75,
"21103": 0.75,
"23203": 1,
"31403": 0.75
},
"1221": {},
"1241": {},
"1251": {},
"1271": {},
"1281": {
"11103": 0,
"11102": 0,
"12103": 0.75,
"12102": 0.75,
"13103": 0,
"13102": 0,
"20103": 0.5,
"21103": 0.5,
"23203": 0.5,
"31403": 1
},
"2011": {},
"2021": {}
}

View file

@ -437,13 +437,95 @@
position: relative;
z-index: 5;
}
.card .c .comment,
.card .C .comment {
background: linear-gradient(0deg, rgba(39, 211, 30, 0.3), rgb(39, 211, 30));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.card .b .comment,
.card .B .comment {
background: linear-gradient(0deg, rgba(94, 189, 249, 0.3), rgb(94, 189, 249));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.card .a .comment,
.card .A .comment {
background: linear-gradient(0deg, rgba(210, 86, 255, 0.3), rgb(210, 86, 255));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.card .s .comment,
.card .S .comment {
background: linear-gradient(0deg, rgba(255, 218, 190, 0.3), rgb(255, 218, 190));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.card .ss .comment,
.card .SS .comment {
background: linear-gradient(0deg, rgba(255, 225, 116, 0.4), rgb(255, 225, 116));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.card .sss .comment,
.card .SSS .comment {
background: linear-gradient(0deg, rgba(255, 163, 59, 0.4), rgb(255, 163, 59));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.card .ace .comment,
.card .ACE .comment {
background: linear-gradient(0deg, rgba(255, 59, 59, 0.4), rgb(255, 59, 59));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.card .equip-score {
display: flex;
justify-content: center;
font-size: 1.2em;
align-items: center;
gap: 0.2em;
}
.card .equip-score .comment-box {
font-size: 1.2em;
width: 2em;
display: flex;
justify-content: center;
align-items: center;
aspect-ratio: 1;
border-radius: 50%;
background-color: rgba(32, 32, 32, 0.4);
box-shadow: 0 0 1em rgba(0, 0, 0, 0.4);
border: 0.2em solid rgb(216, 216, 216);
position: relative;
z-index: 1;
}
.card .equip-score .value {
border: 0.1em solid rgb(155, 155, 155);
border-left: none;
padding: 0.1em 1em 0.1em 1em;
margin-left: -0.6em;
border-radius: 0 1em 1em 0;
}
.card .equip-score .value .subt {
font-size: 0.8em;
}
.card .equip-list {
width: 100%;
display: grid;
gap: 1em;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
padding: 0 1.8em;
align-items: stretch;
margin-top: 1em;
overflow: hidden;
}
.card .equip-list .box {
border-image-source: url("./images/equip_bg.png");
@ -569,8 +651,23 @@
white-space: nowrap;
text-align: center;
}
.card .equip-list .box .score {
display: flex;
justify-content: center;
gap: 0.2em;
font-size: 0.9em;
align-items: flex-end;
}
.card .equip-list .box .score .value {
font-size: 0.9em;
background: linear-gradient(0deg, rgba(255, 255, 255, 0.1), rgb(255, 255, 255));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.card .equip-list .box .property-list {
padding: 0 0.5em;
overflow: hidden;
}
.card .equip-list .box .property-list .properties {
display: flex;
@ -586,6 +683,21 @@
flex-grow: 0;
flex-shrink: 0;
}
.card .equip-list .box .property-list .properties .count {
display: flex;
align-items: center;
gap: 0.1em;
flex-grow: 0;
flex-shrink: 0;
}
.card .equip-list .box .property-list .properties .count span {
width: 0.3em;
aspect-ratio: 1;
border-right: 0.1em solid rgb(255, 255, 255);
border-top: 0.1em solid rgb(255, 255, 255);
rotate: 45deg;
margin-left: -0.15em;
}
.card .equip-list .box .property-list .properties .label {
flex-grow: 1;
flex-shrink: 1;
@ -594,10 +706,25 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
opacity: 1;
}
.card .equip-list .box .property-list .properties .label.hit0 {
opacity: 0.6;
}
.card .equip-list .box .property-list .properties .label.hit50 {
opacity: 0.8;
}
.card .equip-list .box .property-list .properties .label.hit75 {
opacity: 1;
}
.card .equip-list .box .property-list .properties .label.hit100 {
opacity: 1;
color: rgb(249, 189, 64);
}
.card .equip-list .box .property-list .properties .value {
color: rgb(249, 189, 64);
font-size: 0.7em;
margin-left: auto;
}
.card .equip-list .box .property-list .properties.main {
background-color: rgb(65, 147, 237);
@ -605,9 +732,17 @@
.card .equip-list .box .property-list .properties.main .prop-icon {
width: 1.2em;
margin-bottom: 0.2em;
filter: drop-shadow(0 0 0.4em rgba(0, 0, 0, 0.3));
}
.card .equip-list .box .property-list .properties.main .label {
color: rgb(255, 255, 255);
text-shadow: 0 0 0.4em rgba(0, 0, 0, 0.3);
font-size: 0.8em;
opacity: 1;
}
.card .equip-list .box .property-list .properties.main .value {
color: rgb(255, 255, 255);
text-shadow: 0 0 0.4em rgba(0, 0, 0, 0.3);
font-size: 1em;
}
.card .damage-title {

View file

@ -138,6 +138,17 @@
<div class="title">
<% include(sys.specialTitle, {en: 'METAL' , cn: '驱动盘信息' }) %>
</div>
{{if charData.equip_score !== false}}
<div class="equip-score {{charData.equip_comment}}">
<div class="comment-box">
<div class="comment">{{charData.equip_comment}}</div>
</div>
<div class="value">
<span>{{charData.equip_score}}</span>
<span class="subt"></span>
</div>
</div>
{{/if}}
<div class="equip-list">
{{each charData.equip equip}}
<div class="box">
@ -149,6 +160,12 @@
<div class="rarity-icon {{equip.rarity}}"></div>
</div>
<div class="name">{{equip.name}}</div>
{{if equip.score !== false}}
<div class="score {{equip.comment}}">
<div class="comment">{{equip.comment}}</div>
<div class="value">{{equip.score}}</div>
</div>
{{/if}}
<div class="property-list">
{{each equip.main_properties prop}}
@ -163,6 +180,13 @@
<div class="properties">
<div class="prop-icon {{prop.classname}}"></div>
<div class="label yellow">{{prop.property_name}}</div>
{{if prop.count}}
<div class="count">
<% for(let i=1 ; i <=prop.count ; i++) { %>
<span></span>
<% } %>
</div>
{{/if}}
<div class="value">{{prop.base}}</div>
</div>
{{/each}}
@ -177,7 +201,7 @@
<% } %>
</div>
{{if charData.damages && charData.damages.length}}
{{if charData?.damages && charData?.damages?.length}}
<div class="title damage-title">
<% include(sys.specialTitle, {en: 'DAMAGE' , cn: '伤害统计' }) %>
</div>

View file

@ -382,14 +382,139 @@
z-index: 5;
}
.c,
.C {
.comment {
background: linear-gradient(
0deg,
rgba(39, 211, 30, 0.3),
rgba(39, 211, 30, 1)
);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
}
.b,
.B {
.comment {
background: linear-gradient(
0deg,
rgba(94, 189, 249, 0.3),
rgba(94, 189, 249, 1)
);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
}
.a,
.A {
.comment {
background: linear-gradient(
0deg,
rgba(210, 86, 255, 0.3),
rgb(210, 86, 255)
);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
}
.s,
.S {
.comment {
background: linear-gradient(
0deg,
rgba(255, 218, 190, 0.3),
rgba(255, 218, 190, 1)
);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
}
.ss,
.SS {
.comment {
background: linear-gradient(
0deg,
rgba(255, 225, 116, 0.4),
rgba(255, 225, 116, 1)
);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
}
.sss,
.SSS {
.comment {
background: linear-gradient(
0deg,
rgba(255, 163, 59, 0.4),
rgba(255, 163, 59, 1)
);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
}
.ace,
.ACE {
.comment {
background: linear-gradient(
0deg,
rgba(255, 59, 59, 0.4),
rgb(255, 59, 59)
);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
}
.equip-score {
display: flex;
justify-content: center;
font-size: 1.2em;
align-items: center;
gap: 0.2em;
.comment-box {
font-size: 1.2em;
width: 2em;
display: flex;
justify-content: center;
align-items: center;
aspect-ratio: 1;
border-radius: 50%;
background-color: rgba(32, 32, 32, 0.4);
box-shadow: 0 0 1em rgba(0, 0, 0, 0.4);
border: 0.2em solid rgb(216, 216, 216);
position: relative;
z-index: 1;
}
.value {
border: 0.1em solid rgba(155, 155, 155);
border-left: none;
padding: 0.1em 1em 0.1em 1em;
margin-left: -0.6em;
border-radius: 0 1em 1em 0;
.subt {
font-size: 0.8em;
}
}
}
.equip-list {
width: 100%;
display: grid;
gap: 1em;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
padding: 0 1.8em;
align-items: stretch;
margin-top: 1em;
overflow: hidden;
.box {
$size: 3em;
border-image-source: url('./images/equip_bg.png');
@ -484,9 +609,28 @@
text-align: center;
}
.score {
display: flex;
justify-content: center;
gap: 0.2em;
font-size: 0.9em;
align-items: flex-end;
.value {
font-size: 0.9em;
background: linear-gradient(
0deg,
rgba(255, 255, 255, 0.1),
rgba(255, 255, 255, 1)
);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
}
.property-list {
padding: 0 0.5em;
overflow: hidden;
.properties {
display: flex;
align-items: center;
@ -502,6 +646,23 @@
flex-shrink: 0;
}
.count {
display: flex;
align-items: center;
gap: 0.1em;
flex-grow: 0;
flex-shrink: 0;
span {
// 箭头样式
width: 0.3em;
aspect-ratio: 1;
border-right: 0.1em solid rgb(255, 255, 255);
border-top: 0.1em solid rgb(255, 255, 255);
rotate: 45deg;
margin-left: -0.15em;
}
}
.label {
flex-grow: 1;
flex-shrink: 1;
@ -510,23 +671,44 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
opacity: 1;
&.hit0 {
opacity: 0.6;
}
&.hit50 {
opacity: 0.8;
}
&.hit75 {
opacity: 1;
}
&.hit100 {
opacity: 1;
color: rgb(249, 189, 64);
}
}
.value {
color: rgb(249, 189, 64);
font-size: 0.7em;
margin-left: auto;
}
&.main {
background-color: rgb(65, 147, 237);
.prop-icon {
width: 1.2em;
margin-bottom: 0.2em;
filter: drop-shadow(0 0 0.4em rgba(0, 0, 0, 0.3));
}
.label {
color: rgb(255, 255, 255);
text-shadow: 0 0 0.4em rgba(0, 0, 0, 0.3);
font-size: 0.8em;
opacity: 1;
}
.value {
color: rgb(255, 255, 255);
text-shadow: 0 0 0.4em rgba(0, 0, 0, 0.3);
font-size: 1em;
}
}