mirror of
https://github.com/ZZZure/ZZZ-Plugin.git
synced 2025-12-16 13:17:32 +00:00
Upd:角色面板属性颜色根据词条权重切换
This commit is contained in:
parent
289a0a9a6d
commit
06ec5152a0
9 changed files with 74 additions and 53 deletions
12
lib/score.js
12
lib/score.js
|
|
@ -6,7 +6,7 @@ import { nameToId } from './convert/property.js';
|
|||
export const baseValueData = getMapData('EquipBaseValue');
|
||||
const equipScore = getMapData('EquipScore');
|
||||
/** @type {{ [charID: string]: { [propID: string]: number } }} */
|
||||
export const scoreData = {};
|
||||
export const scoreData = Object.create(null);
|
||||
for (const charName in equipScore) {
|
||||
// 兼容原ID格式
|
||||
if (+charName) {
|
||||
|
|
@ -16,17 +16,17 @@ for (const charName in equipScore) {
|
|||
const charID = charNameToID(charName);
|
||||
if (!charID)
|
||||
continue;
|
||||
scoreData[charID] = {};
|
||||
scoreData[charID] = Object.create(null);
|
||||
for (const propName in equipScore[charName]) {
|
||||
const propID = nameToId(propName);
|
||||
if (!propID)
|
||||
if (!propID || !equipScore[charName][propName])
|
||||
continue;
|
||||
scoreData[charID][propID] = equipScore[charName][propName];
|
||||
};
|
||||
/** 小生命、小攻击、小防御映射为大生命、大攻击、大防御的1/3 */
|
||||
for (const [small, big] of [[11103, 11102], [12103, 12102], [13103, 13102]]) {
|
||||
if (!scoreData[charID][small] && scoreData[charID][big]) {
|
||||
scoreData[charID][small] = scoreData[charID][big] / 3;
|
||||
if (scoreData[charID][big]) {
|
||||
scoreData[charID][small] ??= scoreData[charID][big] / 3;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -38,7 +38,7 @@ for (const charName in equipScore) {
|
|||
*/
|
||||
export const hasScoreData = charID => {
|
||||
return (
|
||||
scoreData.hasOwnProperty(charID) &&
|
||||
scoreData[charID] &&
|
||||
Object.keys(scoreData[charID]).length > 0
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { Equip, Weapon } from './equip.js';
|
|||
import { Property } from './property.js';
|
||||
import { Skill } from './skill.js';
|
||||
import { avatar_ability } from './damage/avatar.js';
|
||||
import { hasScoreData } from '../lib/score.js';
|
||||
import { hasScoreData, scoreData } from '../lib/score.js';
|
||||
|
||||
import _ from 'lodash';
|
||||
import fs from 'fs';
|
||||
|
|
@ -433,6 +433,15 @@ export class ZZZAvatarInfo {
|
|||
return result;
|
||||
}
|
||||
|
||||
/** 面板属性label效果 */
|
||||
get_label(propID) {
|
||||
const base = scoreData[this.id][propID];
|
||||
if (!base) return '';
|
||||
return base === 1 ? 'yellow' :
|
||||
base >= 0.75 ? 'blue' :
|
||||
base >= 0.5 ? 'white' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取基础资源
|
||||
* @returns {Promise<void>}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ let depth = 0, weakMapCheck = new WeakMap();
|
|||
export class BuffManager {
|
||||
avatar;
|
||||
buffs = [];
|
||||
setCount = {};
|
||||
defaultBuff = {};
|
||||
setCount = Object.create(null);
|
||||
defaultBuff = Object.create(null);
|
||||
constructor(avatar) {
|
||||
this.avatar = avatar;
|
||||
}
|
||||
|
|
@ -56,25 +56,26 @@ export class BuffManager {
|
|||
}
|
||||
if (!buff.name && (buff.source || this.defaultBuff.source) === 'Set' && this.defaultBuff.name && typeof buff.check === 'number')
|
||||
buff.name = this.defaultBuff.name + buff.check;
|
||||
const oriBuff = buff;
|
||||
buff = _.merge({
|
||||
status: true,
|
||||
isForever: false,
|
||||
is: {},
|
||||
is: Object.create(null),
|
||||
...this.defaultBuff
|
||||
}, buff);
|
||||
if (buff.isForever)
|
||||
buff.is.forever = true;
|
||||
if (buff.range && !Array.isArray(buff.range))
|
||||
buff.range = [buff.range];
|
||||
buff.range = oriBuff.range = [buff.range];
|
||||
if (!buff.source) {
|
||||
if (buff.name.includes('核心') || buff.name.includes('天赋'))
|
||||
buff.source = 'Talent';
|
||||
buff.source = oriBuff.source = 'Talent';
|
||||
else if (buff.name.includes('额外能力'))
|
||||
buff.source = 'Addition';
|
||||
buff.source = oriBuff.source = 'Addition';
|
||||
else if (buff.name.includes('影'))
|
||||
buff.source = 'Rank';
|
||||
buff.source = oriBuff.source = 'Rank';
|
||||
else if (buff.name.includes('技'))
|
||||
buff.source = 'Skill';
|
||||
buff.source = oriBuff.source = 'Skill';
|
||||
}
|
||||
if (!buff.name || !buff.value || !buff.source || !buffTypeEnum[buffTypeEnum[buff.type]])
|
||||
return logger.warn('无效buff:', buff);
|
||||
|
|
@ -89,7 +90,7 @@ export class BuffManager {
|
|||
buff.check = ({ avatar, buffM, calc }) => professionCheck(avatar) && (!oriCheck || oriCheck({ avatar, buffM, calc }));
|
||||
}
|
||||
else if (buff.source === 'Rank') {
|
||||
buff.check ??= +buff.name.match(/\d/)?.[0];
|
||||
buff.check ??= oriBuff.check = +buff.name.match(/\d/)?.[0];
|
||||
}
|
||||
this.buffs.push(buff);
|
||||
return this.buffs;
|
||||
|
|
|
|||
|
|
@ -131,16 +131,16 @@ export class BuffManager {
|
|||
readonly avatar: ZZZAvatarInfo
|
||||
readonly buffs: buff[] = []
|
||||
/** 套装计数 */
|
||||
setCount: { [name: string]: number } = {}
|
||||
defaultBuff: { [key in keyof buff]?: buff[key] } = {}
|
||||
setCount: { [name: string]: number } = Object.create(null)
|
||||
defaultBuff: { [key in keyof buff]?: buff[key] } = Object.create(null)
|
||||
|
||||
constructor(avatar: ZZZAvatarInfo) {
|
||||
this.avatar = avatar
|
||||
}
|
||||
|
||||
/** 注册buff */
|
||||
/** 注册并格式化buff */
|
||||
new(buff: buff): buff[]
|
||||
/** 注册buffs */
|
||||
/** 注册并格式化buffs */
|
||||
new(buffs: buff[]): buff[]
|
||||
new(buff: buff | buff[]) {
|
||||
if (Array.isArray(buff)) {
|
||||
|
|
@ -150,21 +150,22 @@ export class BuffManager {
|
|||
// 简化参数
|
||||
if (!buff.name && (buff.source || this.defaultBuff.source) === 'Set' && this.defaultBuff.name && typeof buff.check === 'number')
|
||||
buff.name = this.defaultBuff.name + buff.check
|
||||
const oriBuff = buff
|
||||
buff = _.merge({
|
||||
status: true,
|
||||
isForever: false,
|
||||
is: {},
|
||||
is: Object.create(null),
|
||||
...this.defaultBuff
|
||||
}, buff)
|
||||
if (buff.isForever)
|
||||
buff.is.forever = true
|
||||
if (buff.range && !Array.isArray(buff.range))
|
||||
buff.range = [buff.range]
|
||||
buff.range = oriBuff.range = [buff.range]
|
||||
if (!buff.source) {
|
||||
if (buff.name.includes('核心') || buff.name.includes('天赋')) buff.source = 'Talent'
|
||||
else if (buff.name.includes('额外能力')) buff.source = 'Addition'
|
||||
else if (buff.name.includes('影')) buff.source = 'Rank'
|
||||
else if (buff.name.includes('技')) buff.source = 'Skill'
|
||||
if (buff.name.includes('核心') || buff.name.includes('天赋')) buff.source = oriBuff.source = 'Talent'
|
||||
else if (buff.name.includes('额外能力')) buff.source = oriBuff.source = 'Addition'
|
||||
else if (buff.name.includes('影')) buff.source = oriBuff.source = 'Rank'
|
||||
else if (buff.name.includes('技')) buff.source = oriBuff.source = 'Skill'
|
||||
}
|
||||
if (!buff.name || !buff.value || !buff.source || !buffTypeEnum[buffTypeEnum[buff.type]])
|
||||
return logger.warn('无效buff:', buff)
|
||||
|
|
@ -177,8 +178,9 @@ export class BuffManager {
|
|||
}
|
||||
const oriCheck = typeof buff.check === 'function' && buff.check
|
||||
buff.check = ({ avatar, buffM, calc }) => professionCheck(avatar) && (!oriCheck || oriCheck({ avatar, buffM, calc }))
|
||||
// 影画buff影画数检查
|
||||
} else if (buff.source === 'Rank') {
|
||||
buff.check ??= +buff.name.match(/\d/)!?.[0]
|
||||
buff.check ??= oriBuff.check = +buff.name.match(/\d/)!?.[0]
|
||||
}
|
||||
this.buffs.push(buff)
|
||||
return this.buffs
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ export class Calculator {
|
|||
buffM;
|
||||
avatar;
|
||||
skills = [];
|
||||
cache = {};
|
||||
props = {};
|
||||
cache = Object.create(null);
|
||||
props = Object.create(null);
|
||||
skill;
|
||||
defaultSkill = {};
|
||||
defaultSkill = Object.create(null);
|
||||
enemy;
|
||||
constructor(buffM) {
|
||||
this.buffM = buffM;
|
||||
|
|
@ -38,16 +38,17 @@ export class Calculator {
|
|||
skill.forEach(s => this.new(s));
|
||||
return this.skills;
|
||||
}
|
||||
const oriSkill = skill;
|
||||
skill = _.merge({
|
||||
...this.defaultSkill
|
||||
}, skill);
|
||||
if (!skill.element)
|
||||
skill.element = elementType2element(this.avatar.element_type);
|
||||
skill.element = oriSkill.element = elementType2element(this.avatar.element_type);
|
||||
if (!skill.name || !skill.type)
|
||||
return logger.warn('无效skill:', skill);
|
||||
if (skill.check && +skill.check) {
|
||||
const num = skill.check;
|
||||
skill.check = ({ avatar }) => avatar.rank >= num;
|
||||
skill.check = oriSkill.check = ({ avatar }) => avatar.rank >= num;
|
||||
}
|
||||
this.skills.push(skill);
|
||||
return this.skills;
|
||||
|
|
@ -70,13 +71,13 @@ export class Calculator {
|
|||
logger.debug('自定义计算最终伤害:', dmg.result);
|
||||
return dmg;
|
||||
}
|
||||
const props = this.props = skill.props || {};
|
||||
const props = this.props = skill.props || Object.create(null);
|
||||
const usefulBuffs = this.buffM.filter({
|
||||
element: skill.element,
|
||||
range: [skill.type],
|
||||
redirect: skill.redirect
|
||||
}, this);
|
||||
const areas = {};
|
||||
const areas = Object.create(null);
|
||||
if (skill.before)
|
||||
skill.before({ avatar: this.avatar, calc: this, usefulBuffs, skill, props, areas });
|
||||
const isAnomaly = typeof anomalyEnum[skill.type] === 'number';
|
||||
|
|
|
|||
|
|
@ -129,11 +129,11 @@ export class Calculator {
|
|||
readonly buffM: BuffManager
|
||||
readonly avatar: ZZZAvatarInfo
|
||||
readonly skills: skill[] = []
|
||||
private cache: { [type: string]: damage } = {}
|
||||
private props: Exclude<damage['props'], undefined> = {}
|
||||
private cache: { [type: string]: damage } = Object.create(null)
|
||||
private props: Exclude<damage['props'], undefined> = Object.create(null)
|
||||
/** 当前正在计算的技能 */
|
||||
skill: skill
|
||||
defaultSkill: { [key in keyof skill]?: skill[key] } = {}
|
||||
defaultSkill: { [key in keyof skill]?: skill[key] } = Object.create(null)
|
||||
enemy: enemy
|
||||
|
||||
constructor(buffM: BuffManager) {
|
||||
|
|
@ -161,23 +161,24 @@ export class Calculator {
|
|||
}
|
||||
}
|
||||
|
||||
/** 注册skill */
|
||||
/** 注册并格式化skill */
|
||||
new(skill: skill): skill[]
|
||||
/** 注册skills */
|
||||
/** 注册并格式化skills */
|
||||
new(skills: skill[]): skill[]
|
||||
new(skill: skill | skill[]) {
|
||||
if (Array.isArray(skill)) {
|
||||
skill.forEach(s => this.new(s))
|
||||
return this.skills
|
||||
}
|
||||
const oriSkill = skill
|
||||
skill = _.merge({
|
||||
...this.defaultSkill
|
||||
}, skill)
|
||||
if (!skill.element) skill.element = elementType2element(this.avatar.element_type)
|
||||
if (!skill.element) skill.element = oriSkill.element = elementType2element(this.avatar.element_type)
|
||||
if (!skill.name || !skill.type) return logger.warn('无效skill:', skill)
|
||||
if (skill.check && +skill.check) {
|
||||
const num = skill.check as unknown as number
|
||||
skill.check = ({ avatar }) => avatar.rank >= num
|
||||
skill.check = oriSkill.check = ({ avatar }) => avatar.rank >= num
|
||||
}
|
||||
this.skills.push(skill)
|
||||
return this.skills
|
||||
|
|
@ -208,14 +209,14 @@ export class Calculator {
|
|||
logger.debug('自定义计算最终伤害:', dmg.result)
|
||||
return dmg
|
||||
}
|
||||
const props = this.props = skill.props || {}
|
||||
const props = this.props = skill.props || Object.create(null)
|
||||
/** 缩小筛选范围 */
|
||||
const usefulBuffs = this.buffM.filter({
|
||||
element: skill.element,
|
||||
range: [skill.type],
|
||||
redirect: skill.redirect
|
||||
}, this)
|
||||
const areas = {} as damage['areas']
|
||||
const areas = Object.create(null) as damage['areas']
|
||||
if (skill.before) skill.before({ avatar: this.avatar, calc: this, usefulBuffs, skill, props, areas })
|
||||
const isAnomaly = typeof anomalyEnum[skill.type as anomaly] === 'number'
|
||||
if (!areas.BasicArea) {
|
||||
|
|
|
|||
|
|
@ -328,6 +328,9 @@
|
|||
.card .basic .info .property_info .list .properties .label.blue {
|
||||
color: rgb(65, 147, 237);
|
||||
}
|
||||
.card .basic .info .property_info .list .properties .label.white {
|
||||
color: rgb(233, 233, 233);
|
||||
}
|
||||
.card .basic .info .property_info .list .properties .value {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
|
|
|
|||
|
|
@ -43,52 +43,52 @@
|
|||
<div class="list">
|
||||
<div class="properties">
|
||||
<div class="prop-icon hpmax"></div>
|
||||
<div class="label yellow">生命值</div>
|
||||
<div class="label {{charData.get_label(11102)}}">生命值</div>
|
||||
<div class="value">{{basic_properties.hpmax.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon attack"></div>
|
||||
<div class="label yellow">攻击力</div>
|
||||
<div class="label {{charData.get_label(12102)}}">攻击力</div>
|
||||
<div class="value">{{basic_properties.attack.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon def"></div>
|
||||
<div class="label yellow">防御力</div>
|
||||
<div class="label {{charData.get_label(13102)}}">防御力</div>
|
||||
<div class="value">{{basic_properties.def.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon breakstun"></div>
|
||||
<div class="label">冲击力</div>
|
||||
<div class="label {{charData.get_label(12202)}}">冲击力</div>
|
||||
<div class="value">{{basic_properties.breakstun.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon crit"></div>
|
||||
<div class="label blue">暴击率</div>
|
||||
<div class="label {{charData.get_label(20103)}}">暴击率</div>
|
||||
<div class="value">{{basic_properties.crit.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon critdam"></div>
|
||||
<div class="label blue">暴击伤害</div>
|
||||
<div class="label {{charData.get_label(21103)}}">暴击伤害</div>
|
||||
<div class="value">{{basic_properties.critdam.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon elementabnormalpower"></div>
|
||||
<div class="label">异常掌控</div>
|
||||
<div class="label {{charData.get_label(31403)}}">异常掌控</div>
|
||||
<div class="value">{{basic_properties.elementabnormalpower.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon elementmystery"></div>
|
||||
<div class="label">异常精通</div>
|
||||
<div class="label {{charData.get_label(31203)}}">异常精通</div>
|
||||
<div class="value">{{basic_properties.elementmystery.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon penratio"></div>
|
||||
<div class="label">穿透率</div>
|
||||
<div class="label {{charData.get_label(23103)}}">穿透率</div>
|
||||
<div class="value">{{basic_properties.penratio.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon sprecover"></div>
|
||||
<div class="label">能量回复</div>
|
||||
<div class="label {{charData.get_label(30502)}}">能量回复</div>
|
||||
<div class="value">{{basic_properties.sprecover.final}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -231,6 +231,10 @@
|
|||
&.blue {
|
||||
color: rgb(65, 147, 237);
|
||||
}
|
||||
|
||||
&.white {
|
||||
color: rgb(233, 233, 233);
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue