diff --git a/lib/convert/property.js b/lib/convert/property.js index fb4332d..53a27fc 100644 --- a/lib/convert/property.js +++ b/lib/convert/property.js @@ -44,28 +44,37 @@ export function idToClassName(_id) { /** * 获取属性标识 - * @param {string | number} _id 属性id + * @param {string | number} id 属性id * @returns {string | null} */ -export const idToSignName = _id => { - const id = _id.toString(); +export const idToSignName = id => { const result = propertyData[id]; if (!result) return null; return result[0]; }; /** - * 获取属性名称 - * @param {string | number} _id 属性id + * 获取属性全称 + * @param {string | number} id 属性id * @returns {string | null} */ -export const idToName = _id => { - const id = _id.toString(); +export const idToName = id => { const result = propertyData[id]; if (!result) return null; return result[1]; }; +/** + * 获取属性二字简称 + * @param {string | number} id 属性id + * @returns {string | null} + */ +export const idToShortName = id => { + const result = propertyData[id]; + if (!result) return null; + return result[2]; +}; + /** * 属性名转id * @param {string} propName 属性名 diff --git a/lib/score.js b/lib/score.js index fd70f63..c8fc88c 100644 --- a/lib/score.js +++ b/lib/score.js @@ -48,14 +48,7 @@ for (const charName in equipScore) { * @returns {number} */ export const getEquipPropertyEnhanceCount = (propertyID, value) => { - if (value.includes('%')) { - value = value.replace('%', ''); - } - value = Number(value); - propertyID = String(propertyID); - const baseValue = baseValueData[propertyID] || 0; - if (baseValue === 0) { - return 0; - } - return value / baseValue - 1; + const baseValue = baseValueData[propertyID]; + value = +value.replace('%', ''); + return value / baseValue - 1 || 0; }; diff --git a/model/avatar.js b/model/avatar.js index 816f818..78fe6a7 100644 --- a/model/avatar.js +++ b/model/avatar.js @@ -4,16 +4,16 @@ import { getSmallSquareAvatar, getSquareAvatar, } from '../lib/download.js'; -import { formatScoreWeight, scoreWeight } from '../lib/score.js'; +import { baseValueData, formatScoreWeight, scoreWeight } from '../lib/score.js'; import { avatar_ability, scoreFnc } from './damage/avatar.js'; +import { idToShortName } from '../lib/convert/property.js'; import { imageResourcesPath } from '../lib/path.js'; import { Equip, Weapon } from './equip.js'; import { Property } from './property.js'; import { Skill } from './skill.js'; - +import path from 'path'; import _ from 'lodash'; import fs from 'fs'; -import path from 'path'; /** * @class @@ -357,6 +357,7 @@ export class ZZZAvatarInfo { /** @type {number|boolean} */ get equip_score() { + if (!this.equip?.length) return false; if (this.scoreWeight) { let score = 0; for (const equip of this.equip) { @@ -434,6 +435,35 @@ export class ZZZAvatarInfo { return result; } + /** 词条统计 */ + get propertyStats() { + /** @type {{ [propID: string]: { id: number, name: string, weight: number, value: string, count: number } }} */ + const stats = {} + for (const equip of this.equip) { + for (const property of equip.properties) { + const propID = property.property_id + stats[propID] ??= { + id: propID, + name: idToShortName(propID), + weight: this.scoreWeight[propID] || 0, + value: '0', + count: 0 + } + stats[propID].count += property.count + 1 + } + } + const statsArr = Object.values(stats) + statsArr.forEach(stat => { + if (baseValueData[stat.id]) { + stat.value = (baseValueData[stat.id] * stat.count).toFixed(1) + if ([11102, 12102, 13102, 20103, 21103].includes(stat.id)) { + stat.value = `${stat.value}%` + } + } + }) + return _.orderBy(statsArr, ['count', 'weight'], ['desc', 'desc']) + } + /** 面板属性label效果 */ get_label(propID) { const base = this.scoreWeight?.[propID]; diff --git a/model/equip.js b/model/equip.js index 65c2a42..a683977 100644 --- a/model/equip.js +++ b/model/equip.js @@ -31,12 +31,10 @@ export class EquipProperty { this.base = base; this.base_score = 0 this.classname = property.idToClassName(property_id); + /** 词条强化次数 */ + this.count = getEquipPropertyEnhanceCount(property_id, base); } - /** @type {number} */ - get count() { - return getEquipPropertyEnhanceCount(this.property_id, this.base); - } } /** diff --git a/resources/map/Property2Name.json b/resources/map/Property2Name.json index ef2d0cb..092bfa2 100644 --- a/resources/map/Property2Name.json +++ b/resources/map/Property2Name.json @@ -1,21 +1,21 @@ { - "11102": ["HPRatio", "生命值百分比"], - "11103": ["HP", "生命值"], - "12102": ["ATKRatio", "攻击力百分比"], - "12103": ["ATK", "攻击力"], - "12202": ["Impact", "冲击力"], - "13102": ["DEFRatio", "防御力百分比"], - "13103": ["DEF", "防御力"], - "20103": ["CRITRate", "暴击率"], - "21103": ["CRITDMG", "暴击伤害"], - "23103": ["PenRatio", "穿透率"], - "23203": ["Pen", "穿透值"], - "30502": ["EnergyRegen", "能量回复"], - "31203": ["AnomalyProficiency", "异常精通"], - "31403": ["AnomalyMastery", "异常掌控"], - "31503": ["PhysicalDMGBonus", "物理属性伤害提高"], - "31603": ["FireDMGBonus", "火属性伤害提高"], - "31703": ["IceDMGBonus", "冰属性伤害提高"], - "31803": ["ElectricDMGBonus", "电属性伤害提高"], - "31903": ["EtherDMGBonus", "以太属性伤害提高"] + "11102": ["HPRatio", "生命值百分比", "生命"], + "11103": ["HP", "生命值", "生命"], + "12102": ["ATKRatio", "攻击力百分比", "攻击"], + "12103": ["ATK", "攻击力", "攻击"], + "12202": ["Impact", "冲击力", "冲击"], + "13102": ["DEFRatio", "防御力百分比", "防御"], + "13103": ["DEF", "防御力", "防御"], + "20103": ["CRITRate", "暴击率", "暴击"], + "21103": ["CRITDMG", "暴击伤害", "暴伤"], + "23103": ["PenRatio", "穿透率", "穿透"], + "23203": ["Pen", "穿透值", "穿透"], + "30502": ["EnergyRegen", "能量回复", "能量"], + "31203": ["AnomalyProficiency", "异常精通", "精通"], + "31403": ["AnomalyMastery", "异常掌控", "掌控"], + "31503": ["PhysicalDMGBonus", "物理属性伤害提高", "物伤"], + "31603": ["FireDMGBonus", "火属性伤害提高", "火伤"], + "31703": ["IceDMGBonus", "冰属性伤害提高", "冰伤"], + "31803": ["ElectricDMGBonus", "电属性伤害提高", "电伤"], + "31903": ["EtherDMGBonus", "以太属性伤害提高", "以伤"] } diff --git a/resources/panel/card.css b/resources/panel/card.css index 34b89cc..3341243 100644 --- a/resources/panel/card.css +++ b/resources/panel/card.css @@ -489,14 +489,22 @@ background-clip: text; color: transparent; } -.card .equip-score { +.card .equip-stats { + display: flex; + padding: 0 1.8em; + height: 6em; +} +.card .equip-stats .equip-score { + border: #707070 solid; + border-width: 0.2em 0 0.2em 0.2em; + border-radius: 0.6em 0 0 0.6em; display: flex; justify-content: center; - font-size: 1.2em; + font-size: 1em; align-items: center; - gap: 0.2em; + width: 30%; } -.card .equip-score .comment-box { +.card .equip-stats .equip-score .comment-box { font-size: 1.2em; width: 2em; display: flex; @@ -510,16 +518,75 @@ position: relative; z-index: 1; } -.card .equip-score .value { +.card .equip-stats .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 { +.card .equip-stats .equip-score .value .subt { font-size: 0.8em; } +.card .equip-stats .property-stats { + width: 70%; + height: 100%; + display: flex; + flex-direction: column; + flex-wrap: wrap; + font-size: 0.8em; + align-items: center; + border: #707070 solid; + border-width: 0.2em; + border-radius: 0 0.6em 0.6em 0; + overflow: hidden; +} +.card .equip-stats .property-stats .stat-item { + width: 33.33%; + height: 33.33%; + padding: 0 0.2em; + position: relative; + display: flex; + align-items: center; + white-space: nowrap; + color: #eee; + border: #707070 0.1em solid; +} +.card .equip-stats .property-stats .stat-item:nth-child(7) { + border-radius: 0 0.4em 0 0; +} +.card .equip-stats .property-stats .stat-item:nth-child(9) { + border-radius: 0 0 0.4em 0; +} +.card .equip-stats .property-stats .stat-item.great { + color: rgb(249, 189, 64); +} +.card .equip-stats .property-stats .stat-item.good { + color: rgb(238, 207, 139); +} +.card .equip-stats .property-stats .stat-item.useless { + color: #999999; +} +.card .equip-stats .property-stats .stat-item span.title { + padding-left: 0.1em; + text-align: left; + width: 48%; +} +.card .equip-stats .property-stats .stat-item span.title span.count { + display: inline-block; + text-align: center; + background-color: black; + width: 1.6em; + height: 1.6em; + border: #696969 0.15em solid; + border-radius: 0.4em; +} +.card .equip-stats .property-stats .stat-item span.value { + padding-right: 0.2em; + width: 52%; + overflow: hidden; + text-align: right; +} .card .equip-list { width: 100%; display: grid; diff --git a/resources/panel/card.html b/resources/panel/card.html index dfbd583..4459fd4 100644 --- a/resources/panel/card.html +++ b/resources/panel/card.html @@ -140,13 +140,27 @@ <% include(sys.specialTitle, {en: 'METAL' , cn: '驱动盘信息' }) %> {{if charData.equip_score !== false}} -
-
-
{{charData.equip_comment}}
+
+
+
+
{{charData.equip_comment}}
+
+
+ {{charData.equip_score.toFixed(2)}} + +
-
- {{charData.equip_score.toFixed(2)}} - +
+ {{set stats = charData.propertyStats.slice(0, 9)}} + {{each stats item}} +
+ {{item.count}} {{item.name}} + +{{item.value}} +
+ {{/each}} + <% for (let i = 0; i < 9-stats.length; i++) { %> +
+ <% } %>
{{/if}} diff --git a/resources/panel/card.scss b/resources/panel/card.scss index e06f608..e9890e6 100644 --- a/resources/panel/card.scss +++ b/resources/panel/card.scss @@ -478,34 +478,112 @@ } } - .equip-score { + .equip-stats { display: flex; - justify-content: center; - font-size: 1.2em; - align-items: center; - gap: 0.2em; - .comment-box { - font-size: 1.2em; - width: 2em; + padding: 0 1.8em; + height: 6em; + + .equip-score { + border: #707070 solid; + border-width: 0.2em 0 0.2em 0.2em; + border-radius: 0.6em 0 0 0.6em; display: flex; justify-content: center; + font-size: 1em; 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; + width: 30%; + .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; + } + } } - .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; + + .property-stats { + width: 70%; + height: 100%; + display: flex; + flex-direction: column; + flex-wrap: wrap; + font-size: 0.8em; + align-items: center; + border: #707070 solid; + border-width: 0.2em; + border-radius: 0 0.6em 0.6em 0; + overflow: hidden; + + .stat-item { + width: 33.33%; + height: 33.33%; + padding: 0 0.2em; + position: relative; + display: flex; + align-items: center; + white-space: nowrap; + color: #eee; + border: #707070 0.1em solid; + + &:nth-child(7) { + border-radius: 0 0.4em 0 0; + } + + &:nth-child(9) { + border-radius: 0 0 0.4em 0; + } + + &.great { + color: rgb(249, 189, 64); + } + + &.good { + color: rgb(238, 207, 139); + } + + &.useless { + color: #999999; + } + + span.title { + padding-left: 0.1em; + text-align: left; + width: 48%; + + span.count { + display: inline-block; + text-align: center; + background-color: black; + width: 1.6em; + height: 1.6em; + border: #696969 0.15em solid; + border-radius: 0.4em; + } + } + + span.value { + padding-right: 0.2em; + width: 52%; + overflow: hidden; + text-align: right; + } } } }