mirror of
https://github.com/ZZZure/ZZZ-Plugin.git
synced 2025-12-16 21:27:47 +00:00
feature:%XX伤害
This commit is contained in:
parent
83ca22c3b8
commit
9b7e609f6a
35 changed files with 1849 additions and 114 deletions
71
apps/damage.js
Normal file
71
apps/damage.js
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { getPanelOrigin, formatPanelData } from '../lib/avatar.js'
|
||||||
|
import { avatar_calc } from '../model/damage/avatar.js'
|
||||||
|
import { rulePrefix } from '../lib/common.js'
|
||||||
|
import { ZZZPlugin } from '../lib/plugin.js'
|
||||||
|
import settings from '../lib/settings.js'
|
||||||
|
|
||||||
|
export class Damage extends ZZZPlugin {
|
||||||
|
constructor() {
|
||||||
|
super({
|
||||||
|
name: '[ZZZ-Plugin]Damage',
|
||||||
|
dsc: 'zzzdamage',
|
||||||
|
event: 'message',
|
||||||
|
priority: settings.getConfig('priority')?.panel ?? 70,
|
||||||
|
rule: [
|
||||||
|
{
|
||||||
|
reg: `${rulePrefix}(.+)伤害\\d*$`,
|
||||||
|
fnc: 'charDamagePanel'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async charDamagePanel() {
|
||||||
|
const uid = await this.getUID()
|
||||||
|
if (!uid) {
|
||||||
|
return this.reply('UID为空')
|
||||||
|
}
|
||||||
|
const reg = new RegExp(`${rulePrefix}(.+)伤害(\\d*)$`)
|
||||||
|
const match = this.e.msg.match(reg)
|
||||||
|
if (!match) return false
|
||||||
|
const name = match[4]
|
||||||
|
const data = getPanelOrigin(uid, name)
|
||||||
|
if (!data) {
|
||||||
|
return this.reply(`未找到角色${name}的面板信息,请先刷新面板`)
|
||||||
|
}
|
||||||
|
const parsedData = formatPanelData(data)
|
||||||
|
const calc = avatar_calc(parsedData)
|
||||||
|
const damages = parsedData._damages = calc?.calc()
|
||||||
|
if (!calc || !damages?.length) return this.reply(`暂无角色${name}的伤害计算`)
|
||||||
|
let skillIndex = match[5] && match[5] - 1
|
||||||
|
if (skillIndex && skillIndex > damages.length)
|
||||||
|
skillIndex = damages.length - 1
|
||||||
|
else if (skillIndex < 0)
|
||||||
|
skillIndex = 0
|
||||||
|
const differences = calc.calc_differences(damages[skillIndex]?.skill)
|
||||||
|
if (skillIndex === '') {
|
||||||
|
const _s_ = differences[0]?.[0].damage.skill
|
||||||
|
skillIndex = ((_s_ && damages.findIndex(({ skill }) => skill.name === _s_.name && skill.type === _s_.type) + 1) || damages.length) - 1
|
||||||
|
}
|
||||||
|
const damage = damages[skillIndex]
|
||||||
|
const skill = damage.skill
|
||||||
|
await parsedData.get_detail_assets()
|
||||||
|
const finalData = {
|
||||||
|
uid,
|
||||||
|
charData: parsedData,
|
||||||
|
command: `%${parsedData.name_mi18n}伤害${skillIndex + 1}`,
|
||||||
|
damage,
|
||||||
|
damages,
|
||||||
|
differences,
|
||||||
|
skill: {
|
||||||
|
...skill,
|
||||||
|
index: skillIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const image = await this.render('panel/damage.html', finalData, { retType: 'base64' })
|
||||||
|
const res = await this.reply(image)
|
||||||
|
if (res?.message_id && parsedData.role_icon)
|
||||||
|
await redis.set(`ZZZ:PANEL:IMAGE:${res.message_id}`, parsedData.role_icon, { EX: 3600 * 3 })
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,7 @@ const helpData = [
|
||||||
desc: '查看玩家的角色和邦布列表',
|
desc: '查看玩家的角色和邦布列表',
|
||||||
needCK: true,
|
needCK: true,
|
||||||
needSK: false,
|
needSK: false,
|
||||||
commands: ['card', '卡片', '个人信息'],
|
commands: ['card', '卡片', '角色','个人信息'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '便签',
|
title: '便签',
|
||||||
|
|
|
||||||
|
|
@ -65,16 +65,39 @@ export const idToName = id => {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取属性二字简称
|
* 获取属性2字简称
|
||||||
* @param {string | number} id 属性id
|
* @param {string | number} id 属性id
|
||||||
* @returns {string | null}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export const idToShortName = id => {
|
export const idToShortName2 = id => {
|
||||||
const result = propertyData[id];
|
const result = propertyData[id];
|
||||||
if (!result) return null;
|
if (!result) return '';
|
||||||
return result[2];
|
return result[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取属性2~3字简称
|
||||||
|
* @param {string | number} id 属性id
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export const idToShortName3 = id => {
|
||||||
|
const result = propertyData[id];
|
||||||
|
if (!result) return '';
|
||||||
|
return result[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取属性2~3字简称
|
||||||
|
* @param {string | number} id 属性id
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export const nameToShortName3 = propName => {
|
||||||
|
for (const id in propertyData) {
|
||||||
|
if (propertyData[id]?.[1] === propName) return propertyData[id][3];
|
||||||
|
};
|
||||||
|
return propName;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 属性名转id
|
* 属性名转id
|
||||||
* @param {string} propName 属性名
|
* @param {string} propName 属性名
|
||||||
|
|
@ -82,6 +105,6 @@ export const idToShortName = id => {
|
||||||
export const nameToId = (propName) => {
|
export const nameToId = (propName) => {
|
||||||
for (const id in propertyData) {
|
for (const id in propertyData) {
|
||||||
if (propertyData[id]?.[1] === propName) return Number(id);
|
if (propertyData[id]?.[1] === propName) return Number(id);
|
||||||
}
|
};
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import {
|
||||||
getSquareAvatar,
|
getSquareAvatar,
|
||||||
} from '../lib/download.js';
|
} from '../lib/download.js';
|
||||||
import { baseValueData, formatScoreWeight, scoreWeight } from '../lib/score.js';
|
import { baseValueData, formatScoreWeight, scoreWeight } from '../lib/score.js';
|
||||||
import { avatar_ability, scoreFnc } from './damage/avatar.js';
|
import { avatar_calc, scoreFnc } from './damage/avatar.js';
|
||||||
import { idToShortName } from '../lib/convert/property.js';
|
import { idToShortName2 } from '../lib/convert/property.js';
|
||||||
import { imageResourcesPath } from '../lib/path.js';
|
import { imageResourcesPath } from '../lib/path.js';
|
||||||
import { Equip, Weapon } from './equip.js';
|
import { Equip, Weapon } from './equip.js';
|
||||||
import { Property } from './property.js';
|
import { Property } from './property.js';
|
||||||
|
|
@ -352,9 +352,10 @@ export class ZZZAvatarInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import("./damage/Calculator.ts").damage} */
|
/** @type {import("./damage/Calculator.ts").damage[]} */
|
||||||
get damages() {
|
get damages() {
|
||||||
return avatar_ability(this);
|
if (this._damages) return this._damages;
|
||||||
|
return this._damages = avatar_calc(this)?.calc();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {number|boolean} */
|
/** @type {number|boolean} */
|
||||||
|
|
@ -449,7 +450,7 @@ export class ZZZAvatarInfo {
|
||||||
const propID = property.property_id
|
const propID = property.property_id
|
||||||
stats[propID] ??= {
|
stats[propID] ??= {
|
||||||
id: propID,
|
id: propID,
|
||||||
name: idToShortName(propID),
|
name: idToShortName2(propID),
|
||||||
weight: this.scoreWeight[propID] || 0,
|
weight: this.scoreWeight[propID] || 0,
|
||||||
value: '0',
|
value: '0',
|
||||||
count: 0
|
count: 0
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,27 @@
|
||||||
import { getMapData } from '../../utils/file.js';
|
|
||||||
import { elementEnum, anomalyEnum } from './BuffManager.js';
|
import { elementEnum, anomalyEnum } from './BuffManager.js';
|
||||||
|
import * as prop from '../../lib/convert/property.js';
|
||||||
|
import { getMapData } from '../../utils/file.js';
|
||||||
import { charData } from './avatar.js';
|
import { charData } from './avatar.js';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
const elementType2element = (elementType) => elementEnum[[0, 1, 2, 3, -1, 4][elementType - 200]];
|
const elementType2element = (elementType) => elementEnum[[0, 1, 2, 3, -1, 4][elementType - 200]];
|
||||||
|
const baseValueData = {
|
||||||
|
"生命值百分比": [0.03, '3.0%'],
|
||||||
|
"生命值": [112, '112'],
|
||||||
|
"攻击力百分比": [0.03, '3.0%'],
|
||||||
|
"攻击力": [19, '19'],
|
||||||
|
"防御力百分比": [0.048, '4.8%'],
|
||||||
|
"防御力": [15, '15'],
|
||||||
|
"暴击率": [0.024, '2.4%'],
|
||||||
|
"暴击伤害": [0.048, '4.8%'],
|
||||||
|
"穿透值": [9, '9'],
|
||||||
|
"异常精通": [9, '9']
|
||||||
|
};
|
||||||
const AnomalyData = getMapData('AnomalyData');
|
const AnomalyData = getMapData('AnomalyData');
|
||||||
export class Calculator {
|
export class Calculator {
|
||||||
buffM;
|
buffM;
|
||||||
avatar;
|
avatar;
|
||||||
skills = [];
|
skills = [];
|
||||||
|
usefulBuffs = [];
|
||||||
cache = Object.create(null);
|
cache = Object.create(null);
|
||||||
props = {};
|
props = {};
|
||||||
skill;
|
skill;
|
||||||
|
|
@ -68,6 +82,7 @@ export class Calculator {
|
||||||
logger.debug(`${logger.green(skill.type)}${skill.name}伤害计算:`);
|
logger.debug(`${logger.green(skill.type)}${skill.name}伤害计算:`);
|
||||||
if (skill.dmg) {
|
if (skill.dmg) {
|
||||||
const dmg = skill.dmg(this);
|
const dmg = skill.dmg(this);
|
||||||
|
dmg.skill ||= skill;
|
||||||
logger.debug('自定义计算最终伤害:', dmg.result);
|
logger.debug('自定义计算最终伤害:', dmg.result);
|
||||||
return dmg;
|
return dmg;
|
||||||
}
|
}
|
||||||
|
|
@ -114,15 +129,18 @@ export class Calculator {
|
||||||
areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs);
|
areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs);
|
||||||
areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs);
|
areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs);
|
||||||
areas.LevelArea ??= this.get_LevelArea();
|
areas.LevelArea ??= this.get_LevelArea();
|
||||||
props.异常暴击率 = this.get_AnomalyCRITRate(skill, usefulBuffs);
|
if (skill.type !== '紊乱') {
|
||||||
props.异常暴击伤害 = this.get_AnomalyCRITDMG(skill, usefulBuffs);
|
props.异常暴击率 ??= this.get_AnomalyCRITRate(skill, usefulBuffs);
|
||||||
|
props.异常暴击伤害 ??= this.get_AnomalyCRITDMG(skill, usefulBuffs);
|
||||||
areas.CriticalArea ??= 1 + props.异常暴击率 * (props.异常暴击伤害 - 1);
|
areas.CriticalArea ??= 1 + props.异常暴击率 * (props.异常暴击伤害 - 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
props.暴击率 = this.get_CRITRate(skill, usefulBuffs);
|
props.暴击率 ??= this.get_CRITRate(skill, usefulBuffs);
|
||||||
props.暴击伤害 = this.get_CRITDMG(skill, usefulBuffs);
|
props.暴击伤害 ??= this.get_CRITDMG(skill, usefulBuffs);
|
||||||
areas.CriticalArea ??= 1 + props.暴击率 * (props.暴击伤害 - 1);
|
areas.CriticalArea ??= 1 + props.暴击率 * (props.暴击伤害 - 1);
|
||||||
}
|
}
|
||||||
|
areas.CriticalArea ??= 1;
|
||||||
logger.debug(`暴击期望:${areas.CriticalArea}`);
|
logger.debug(`暴击期望:${areas.CriticalArea}`);
|
||||||
areas.BoostArea ??= this.get_BoostArea(skill, usefulBuffs);
|
areas.BoostArea ??= this.get_BoostArea(skill, usefulBuffs);
|
||||||
areas.VulnerabilityArea ??= this.get_VulnerabilityArea(skill, usefulBuffs);
|
areas.VulnerabilityArea ??= this.get_VulnerabilityArea(skill, usefulBuffs);
|
||||||
|
|
@ -138,7 +156,8 @@ export class Calculator {
|
||||||
critDMG: BasicArea * 暴击伤害 * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea,
|
critDMG: BasicArea * 暴击伤害 * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea,
|
||||||
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea
|
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea
|
||||||
};
|
};
|
||||||
const damage = { skill, props, areas, result };
|
const damage = { skill, usefulBuffs: _.sortBy(this.usefulBuffs, ['type', 'value']).reverse(), props, areas, result };
|
||||||
|
this.usefulBuffs = [];
|
||||||
if (skill.after) {
|
if (skill.after) {
|
||||||
damage.add = (d) => {
|
damage.add = (d) => {
|
||||||
if (typeof d === 'string')
|
if (typeof d === 'string')
|
||||||
|
|
@ -158,6 +177,7 @@ export class Calculator {
|
||||||
damage.fnc(v => v * n);
|
damage.fnc(v => v * n);
|
||||||
};
|
};
|
||||||
skill.after({ avatar: this.avatar, calc: this, usefulBuffs, skill, damage });
|
skill.after({ avatar: this.avatar, calc: this, usefulBuffs, skill, damage });
|
||||||
|
delete damage.add, delete damage.fnc, delete damage.x;
|
||||||
}
|
}
|
||||||
logger.debug('最终伤害:', result);
|
logger.debug('最终伤害:', result);
|
||||||
if (!skill.banCache)
|
if (!skill.banCache)
|
||||||
|
|
@ -175,6 +195,86 @@ export class Calculator {
|
||||||
}
|
}
|
||||||
}).filter(v => v && v.result?.expectDMG && !v.skill?.isHide);
|
}).filter(v => v && v.result?.expectDMG && !v.skill?.isHide);
|
||||||
}
|
}
|
||||||
|
calc_differences(skill, types) {
|
||||||
|
if (!skill) {
|
||||||
|
skill = this.skills.find((skill) => skill.isMain)
|
||||||
|
|| this.calc().sort((a, b) => b.result.expectDMG - a.result.expectDMG)[0]?.skill;
|
||||||
|
}
|
||||||
|
if (!types || !types.length) {
|
||||||
|
types = Object.entries(this.avatar.scoreWeight)
|
||||||
|
.reduce((acc, [id, weight]) => {
|
||||||
|
if (weight > 0) {
|
||||||
|
const type = prop.idToName(id);
|
||||||
|
if (type && baseValueData[type]) {
|
||||||
|
acc.push({ type, weight });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, [])
|
||||||
|
.slice(0, 7)
|
||||||
|
.sort((a, b) => b.weight - a.weight)
|
||||||
|
.map(({ type }) => type);
|
||||||
|
}
|
||||||
|
const base = {};
|
||||||
|
types.forEach(type => base[type] = type.includes('百分比') ? this.avatar.base_properties[type.includes('攻击力') ? 'ATK' : type.includes('生命值') ? 'HP' : 'DEF'] * baseValueData[type][0] : baseValueData[type][0]);
|
||||||
|
logger.debug(logger.red('词条变化值:'), base);
|
||||||
|
const buffs = types.map(t => ({
|
||||||
|
name: t,
|
||||||
|
shortName: prop.nameToShortName3(t),
|
||||||
|
type: t.replace('百分比', ''),
|
||||||
|
value: base[t],
|
||||||
|
valueBase: baseValueData[t][1]
|
||||||
|
}));
|
||||||
|
return this._calc_differences(skill, buffs);
|
||||||
|
}
|
||||||
|
_calc_differences(skill, buffs) {
|
||||||
|
if (typeof skill === 'string') {
|
||||||
|
const MySkill = this.skills.find(s => s.type === skill);
|
||||||
|
if (!MySkill)
|
||||||
|
return [];
|
||||||
|
return this._calc_differences(MySkill, buffs);
|
||||||
|
}
|
||||||
|
const oriDamage = this.calc_skill(skill);
|
||||||
|
const result = [];
|
||||||
|
for (const i_del in buffs) {
|
||||||
|
result[i_del] = [];
|
||||||
|
const data_del = buffs[i_del];
|
||||||
|
const { type: type_del, name: name_del = type_del, value: value_del } = data_del;
|
||||||
|
logger.debug(logger.blue(`差异计算:${name_del}`));
|
||||||
|
this.buffM.buffs.push({
|
||||||
|
name: logger.green(`差异计算:${name_del}`),
|
||||||
|
type: type_del,
|
||||||
|
value: ({ calc }) => -calc.calc_value(value_del)
|
||||||
|
});
|
||||||
|
for (const i_add in buffs) {
|
||||||
|
const data_add = buffs[i_add];
|
||||||
|
data_add.name ??= data_add.type;
|
||||||
|
const { type: type_add, name: name_add = type_add, value: value_add } = data_add;
|
||||||
|
const data = result[i_del][i_add] = {
|
||||||
|
add: data_add,
|
||||||
|
del: data_del,
|
||||||
|
damage: oriDamage,
|
||||||
|
difference: 0
|
||||||
|
};
|
||||||
|
if (name_del === name_add)
|
||||||
|
continue;
|
||||||
|
logger.debug(logger.yellow(`差异计算:${name_del}->${name_add}`));
|
||||||
|
this.cache = Object.create(null);
|
||||||
|
this.buffM.buffs.push({
|
||||||
|
name: logger.green(`差异计算:${name_del}->${name_add}`),
|
||||||
|
type: type_add,
|
||||||
|
value: value_add
|
||||||
|
});
|
||||||
|
const newDamage = this.calc_skill(skill);
|
||||||
|
this.buffM.buffs.pop();
|
||||||
|
data.damage = newDamage;
|
||||||
|
data.difference = newDamage.result.expectDMG - oriDamage.result.expectDMG;
|
||||||
|
logger.debug(logger.magenta(`差异计算:${name_del}->${name_add} 伤害变化:${data.difference}`));
|
||||||
|
}
|
||||||
|
this.buffM.buffs.pop();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
default(param, value) {
|
default(param, value) {
|
||||||
if (typeof param === 'object') {
|
if (typeof param === 'object') {
|
||||||
this.defaultSkill = param;
|
this.defaultSkill = param;
|
||||||
|
|
@ -271,14 +371,16 @@ export class Calculator {
|
||||||
}, this).reduce((previousValue, buff) => {
|
}, this).reduce((previousValue, buff) => {
|
||||||
const { value } = buff;
|
const { value } = buff;
|
||||||
let add = 0;
|
let add = 0;
|
||||||
if (isRatio && typeof value === 'number' && value < 1) {
|
if (isRatio && typeof value === 'number' && Math.abs(value) < 1) {
|
||||||
add = value * initial;
|
add = value * initial;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
add = this.calc_value(value, buff);
|
add = this.calc_value(value, buff);
|
||||||
if (add < 1 && isRatio && (typeof value === 'string' || Array.isArray(value)))
|
if (Math.abs(add) < 1 && isRatio && (typeof value === 'string' || Array.isArray(value)))
|
||||||
add *= initial;
|
add *= initial;
|
||||||
}
|
}
|
||||||
|
if (!this.usefulBuffs.find(b => b.name === buff.name && b.type === buff.type && add === buff.value))
|
||||||
|
this.usefulBuffs.push({ ...buff, value: add });
|
||||||
logger.debug(`\tBuff:${buff.name}对${buff.range || '全类型'}增加${add}${buff.element || ''}${type}`);
|
logger.debug(`\tBuff:${buff.name}对${buff.range || '全类型'}增加${add}${buff.element || ''}${type}`);
|
||||||
return previousValue + add;
|
return previousValue + add;
|
||||||
}, initial);
|
}, initial);
|
||||||
|
|
@ -317,7 +419,8 @@ export class Calculator {
|
||||||
return VulnerabilityArea;
|
return VulnerabilityArea;
|
||||||
}
|
}
|
||||||
get_ResistanceArea(skill, usefulBuffs) {
|
get_ResistanceArea(skill, usefulBuffs) {
|
||||||
const ResistanceArea = this.get('无视抗性', 1 + this.enemy.resistance, skill, usefulBuffs);
|
let ResistanceArea = this.get('无视抗性', 1 + this.enemy.resistance, skill, usefulBuffs);
|
||||||
|
ResistanceArea = Math.min(2, ResistanceArea);
|
||||||
logger.debug(`抗性区:${ResistanceArea}`);
|
logger.debug(`抗性区:${ResistanceArea}`);
|
||||||
return ResistanceArea;
|
return ResistanceArea;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import type { BuffManager, anomaly, buff, buffType, element } from './BuffManager.ts'
|
import type { BuffManager, anomaly, buff, buffType, element } from './BuffManager.ts'
|
||||||
import type { ZZZAvatarInfo } from '../avatar.js'
|
import type { ZZZAvatarInfo } from '../avatar.js'
|
||||||
import { getMapData } from '../../utils/file.js'
|
|
||||||
import { elementEnum, anomalyEnum } from './BuffManager.js'
|
import { elementEnum, anomalyEnum } from './BuffManager.js'
|
||||||
|
import * as prop from '../../lib/convert/property.js'
|
||||||
|
import { getMapData } from '../../utils/file.js'
|
||||||
import { charData } from './avatar.js'
|
import { charData } from './avatar.js'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
|
|
@ -29,6 +30,8 @@ export interface skill {
|
||||||
* 当为数组类型时(多类型共存),满足数组内其一类型即可,判断规则同上
|
* 当为数组类型时(多类型共存),满足数组内其一类型即可,判断规则同上
|
||||||
*/
|
*/
|
||||||
redirect?: string | string[] | anomaly[] | "追加攻击"[]
|
redirect?: string | string[] | anomaly[] | "追加攻击"[]
|
||||||
|
/** 是否为主要技能。`true`时%XX伤害 默认计算该技能 */
|
||||||
|
isMain?: boolean
|
||||||
/** 角色面板伤害统计中是否隐藏显示 */
|
/** 角色面板伤害统计中是否隐藏显示 */
|
||||||
isHide?: boolean
|
isHide?: boolean
|
||||||
/** 禁用伤害计算cache */
|
/** 禁用伤害计算cache */
|
||||||
|
|
@ -41,14 +44,19 @@ export interface skill {
|
||||||
}) => boolean)
|
}) => boolean)
|
||||||
/** 自定义计算逻辑 */
|
/** 自定义计算逻辑 */
|
||||||
dmg?: (calc: Calculator) => damage
|
dmg?: (calc: Calculator) => damage
|
||||||
/** 伤害计算前调用,可自由定义各属性等 */
|
/**
|
||||||
|
* 伤害计算前调用,可自由定义各属性等
|
||||||
|
* 此操作只作用于当前技能
|
||||||
|
*/
|
||||||
before?: ({ avatar, calc, usefulBuffs, skill, props, areas }: {
|
before?: ({ avatar, calc, usefulBuffs, skill, props, areas }: {
|
||||||
avatar: ZZZAvatarInfo
|
avatar: ZZZAvatarInfo
|
||||||
calc: Calculator
|
calc: Calculator
|
||||||
usefulBuffs: buff[]
|
usefulBuffs: buff[]
|
||||||
/** 技能自身 */
|
/** 技能自身 */
|
||||||
skill: skill
|
skill: skill
|
||||||
|
/** 属性数据。设置后不会更改 */
|
||||||
props: damage['props']
|
props: damage['props']
|
||||||
|
/** 乘区数据。设置后不会更改 */
|
||||||
areas: damage['areas']
|
areas: damage['areas']
|
||||||
}) => void
|
}) => void
|
||||||
/** 伤害计算后调用,可对结果进行修改等 */
|
/** 伤害计算后调用,可对结果进行修改等 */
|
||||||
|
|
@ -65,6 +73,8 @@ export interface skill {
|
||||||
export interface damage {
|
export interface damage {
|
||||||
/** 技能类型 */
|
/** 技能类型 */
|
||||||
skill: skill
|
skill: skill
|
||||||
|
/** 有益Buffs */
|
||||||
|
usefulBuffs: buff[]
|
||||||
/** 技能属性 */
|
/** 技能属性 */
|
||||||
props?: skill['props']
|
props?: skill['props']
|
||||||
/** 各乘区数据 */
|
/** 各乘区数据 */
|
||||||
|
|
@ -102,6 +112,21 @@ export interface damage {
|
||||||
|
|
||||||
const elementType2element = (elementType: number) => elementEnum[[0, 1, 2, 3, -1, 4][elementType - 200]] as element
|
const elementType2element = (elementType: number) => elementEnum[[0, 1, 2, 3, -1, 4][elementType - 200]] as element
|
||||||
|
|
||||||
|
const baseValueData = {
|
||||||
|
"生命值百分比": [0.03, '3.0%'],
|
||||||
|
"生命值": [112, '112'],
|
||||||
|
"攻击力百分比": [0.03, '3.0%'],
|
||||||
|
"攻击力": [19, '19'],
|
||||||
|
"防御力百分比": [0.048, '4.8%'],
|
||||||
|
"防御力": [15, '15'],
|
||||||
|
"暴击率": [0.024, '2.4%'],
|
||||||
|
"暴击伤害": [0.048, '4.8%'],
|
||||||
|
"穿透值": [9, '9'],
|
||||||
|
"异常精通": [9, '9']
|
||||||
|
} as const
|
||||||
|
|
||||||
|
type statKeys = keyof typeof baseValueData
|
||||||
|
|
||||||
const AnomalyData = getMapData('AnomalyData') as {
|
const AnomalyData = getMapData('AnomalyData') as {
|
||||||
name: string,
|
name: string,
|
||||||
element: element,
|
element: element,
|
||||||
|
|
@ -129,6 +154,7 @@ export class Calculator {
|
||||||
readonly buffM: BuffManager
|
readonly buffM: BuffManager
|
||||||
readonly avatar: ZZZAvatarInfo
|
readonly avatar: ZZZAvatarInfo
|
||||||
readonly skills: skill[] = []
|
readonly skills: skill[] = []
|
||||||
|
private usefulBuffs: buff[] = []
|
||||||
private cache: { [type: string]: damage } = Object.create(null)
|
private cache: { [type: string]: damage } = Object.create(null)
|
||||||
private props: Exclude<damage['props'], undefined> = {}
|
private props: Exclude<damage['props'], undefined> = {}
|
||||||
/** 当前正在计算的技能 */
|
/** 当前正在计算的技能 */
|
||||||
|
|
@ -206,6 +232,7 @@ export class Calculator {
|
||||||
logger.debug(`${logger.green(skill.type)}${skill.name}伤害计算:`)
|
logger.debug(`${logger.green(skill.type)}${skill.name}伤害计算:`)
|
||||||
if (skill.dmg) {
|
if (skill.dmg) {
|
||||||
const dmg = skill.dmg(this)
|
const dmg = skill.dmg(this)
|
||||||
|
dmg.skill ||= skill
|
||||||
logger.debug('自定义计算最终伤害:', dmg.result)
|
logger.debug('自定义计算最终伤害:', dmg.result)
|
||||||
return dmg
|
return dmg
|
||||||
}
|
}
|
||||||
|
|
@ -248,14 +275,17 @@ export class Calculator {
|
||||||
areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs)
|
areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs)
|
||||||
areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs)
|
areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs)
|
||||||
areas.LevelArea ??= this.get_LevelArea()
|
areas.LevelArea ??= this.get_LevelArea()
|
||||||
props.异常暴击率 = this.get_AnomalyCRITRate(skill, usefulBuffs)
|
if (skill.type !== '紊乱') { // 紊乱暂无异常暴击区
|
||||||
props.异常暴击伤害 = this.get_AnomalyCRITDMG(skill, usefulBuffs)
|
props.异常暴击率 ??= this.get_AnomalyCRITRate(skill, usefulBuffs)
|
||||||
|
props.异常暴击伤害 ??= this.get_AnomalyCRITDMG(skill, usefulBuffs)
|
||||||
areas.CriticalArea ??= 1 + props.异常暴击率! * (props.异常暴击伤害! - 1)
|
areas.CriticalArea ??= 1 + props.异常暴击率! * (props.异常暴击伤害! - 1)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
props.暴击率 = this.get_CRITRate(skill, usefulBuffs)
|
props.暴击率 ??= this.get_CRITRate(skill, usefulBuffs)
|
||||||
props.暴击伤害 = this.get_CRITDMG(skill, usefulBuffs)
|
props.暴击伤害 ??= this.get_CRITDMG(skill, usefulBuffs)
|
||||||
areas.CriticalArea ??= 1 + props.暴击率! * (props.暴击伤害! - 1)
|
areas.CriticalArea ??= 1 + props.暴击率! * (props.暴击伤害! - 1)
|
||||||
}
|
}
|
||||||
|
areas.CriticalArea ??= 1
|
||||||
logger.debug(`暴击期望:${areas.CriticalArea}`)
|
logger.debug(`暴击期望:${areas.CriticalArea}`)
|
||||||
areas.BoostArea ??= this.get_BoostArea(skill, usefulBuffs)
|
areas.BoostArea ??= this.get_BoostArea(skill, usefulBuffs)
|
||||||
areas.VulnerabilityArea ??= this.get_VulnerabilityArea(skill, usefulBuffs)
|
areas.VulnerabilityArea ??= this.get_VulnerabilityArea(skill, usefulBuffs)
|
||||||
|
|
@ -274,7 +304,8 @@ export class Calculator {
|
||||||
critDMG: BasicArea * 暴击伤害! * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea,
|
critDMG: BasicArea * 暴击伤害! * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea,
|
||||||
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea
|
expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea
|
||||||
}
|
}
|
||||||
const damage: damage = { skill, props, areas, result }
|
const damage: damage = { skill, usefulBuffs: _.sortBy(this.usefulBuffs, ['type', 'value']).reverse(), props, areas, result }
|
||||||
|
this.usefulBuffs = []
|
||||||
if (skill.after) {
|
if (skill.after) {
|
||||||
damage.add = (d) => {
|
damage.add = (d) => {
|
||||||
if (typeof d === 'string') d = this.calc_skill(d)
|
if (typeof d === 'string') d = this.calc_skill(d)
|
||||||
|
|
@ -292,6 +323,7 @@ export class Calculator {
|
||||||
damage.fnc!(v => v * n)
|
damage.fnc!(v => v * n)
|
||||||
}
|
}
|
||||||
skill.after({ avatar: this.avatar, calc: this, usefulBuffs, skill, damage })
|
skill.after({ avatar: this.avatar, calc: this, usefulBuffs, skill, damage })
|
||||||
|
delete damage.add, delete damage.fnc, delete damage.x
|
||||||
}
|
}
|
||||||
logger.debug('最终伤害:', result)
|
logger.debug('最终伤害:', result)
|
||||||
if (!skill.banCache) this.cache[skill.type] = damage
|
if (!skill.banCache) this.cache[skill.type] = damage
|
||||||
|
|
@ -310,6 +342,113 @@ export class Calculator {
|
||||||
}).filter(v => v && v.result?.expectDMG && !v.skill?.isHide) as damage[]
|
}).filter(v => v && v.result?.expectDMG && !v.skill?.isHide) as damage[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算词条伤害差异
|
||||||
|
* @param types 需进行比较的词条数组
|
||||||
|
*/
|
||||||
|
calc_differences(skill?: skill, types?: statKeys[]) {
|
||||||
|
if (!skill) {
|
||||||
|
skill = this.skills.find((skill) => skill.isMain) // 主技能
|
||||||
|
|| this.calc().sort((a, b) => b.result.expectDMG - a.result.expectDMG)[0]?.skill // 伤害最高技能
|
||||||
|
}
|
||||||
|
// 未指定types时,筛选评分权重大于0的词条进行差异计算
|
||||||
|
if (!types || !types.length) {
|
||||||
|
types = Object.entries(this.avatar.scoreWeight)
|
||||||
|
.reduce((acc: { type: statKeys, weight: number }[], [id, weight]) => {
|
||||||
|
if (weight > 0) {
|
||||||
|
const type = prop.idToName(id) as statKeys
|
||||||
|
if (type && baseValueData[type]) {
|
||||||
|
acc.push({ type, weight })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, [])
|
||||||
|
.slice(0, 7) // 默认最多7个
|
||||||
|
.sort((a, b) => b.weight - a.weight) // 按权重从大到小排序
|
||||||
|
.map(({ type }) => type)
|
||||||
|
}
|
||||||
|
const base: { [type: string]: number } = {}
|
||||||
|
types.forEach(type => base[type] = type.includes('百分比') ? this.avatar.base_properties[
|
||||||
|
type.includes('攻击力') ? 'ATK' : type.includes('生命值') ? 'HP' : 'DEF'
|
||||||
|
] * baseValueData[type][0] : baseValueData[type][0])
|
||||||
|
logger.debug(logger.red('词条变化值:'), base)
|
||||||
|
const buffs = types.map(t => ({
|
||||||
|
name: t,
|
||||||
|
shortName: prop.nameToShortName3(t),
|
||||||
|
type: t.replace('百分比', '') as buff['type'],
|
||||||
|
value: base[t],
|
||||||
|
valueBase: baseValueData[t][1]
|
||||||
|
}))
|
||||||
|
return this._calc_differences(skill, buffs)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 计算已注册技能差异 */
|
||||||
|
_calc_differences<B extends { name: skill['type'], type: buff['type'], value: buff['value'] }>(
|
||||||
|
skill: string,
|
||||||
|
buffs: B[]
|
||||||
|
): { add: B, del: B, damage: damage, difference: number }[][]
|
||||||
|
/* 计算技能差异 */
|
||||||
|
_calc_differences<B extends { name: string, type: buff['type'], value: buff['value'] }>(
|
||||||
|
skill: skill,
|
||||||
|
buffs: B[]
|
||||||
|
): { add: B, del: B, damage: damage, difference: number }[][]
|
||||||
|
/**
|
||||||
|
* 以buff形式两两组合进行差异计算
|
||||||
|
* @param buffs 需要进行组合差异计算的buffs
|
||||||
|
* @returns 差异计算结果。`buffs.length维`结果数组
|
||||||
|
*/
|
||||||
|
_calc_differences<B extends { name: string, type: buff['type'], value: buff['value'] }>(
|
||||||
|
skill: skill['type'] | skill,
|
||||||
|
buffs: B[]
|
||||||
|
): { add: B, del: B, damage: damage, difference: number }[][] {
|
||||||
|
if (typeof skill === 'string') {
|
||||||
|
const MySkill = this.skills.find(s => s.type === skill)
|
||||||
|
if (!MySkill) return []
|
||||||
|
return this._calc_differences(MySkill, buffs)
|
||||||
|
}
|
||||||
|
const oriDamage = this.calc_skill(skill)
|
||||||
|
const result: { del: B, add: B, damage: damage, difference: number }[][] = []
|
||||||
|
for (const i_del in buffs) {
|
||||||
|
result[i_del] = []
|
||||||
|
const data_del = buffs[i_del]
|
||||||
|
const { type: type_del, name: name_del = type_del, value: value_del } = data_del
|
||||||
|
logger.debug(logger.blue(`差异计算:${name_del}`))
|
||||||
|
// @ts-ignore
|
||||||
|
this.buffM.buffs.push({
|
||||||
|
name: logger.green(`差异计算:${name_del}`),
|
||||||
|
type: type_del,
|
||||||
|
value: ({ calc }) => -calc.calc_value(value_del) // 转为负值
|
||||||
|
})
|
||||||
|
for (const i_add in buffs) {
|
||||||
|
const data_add = buffs[i_add]
|
||||||
|
data_add.name ??= data_add.type
|
||||||
|
const { type: type_add, name: name_add = type_add, value: value_add } = data_add
|
||||||
|
const data = result[i_del][i_add] = {
|
||||||
|
add: data_add,
|
||||||
|
del: data_del,
|
||||||
|
damage: oriDamage,
|
||||||
|
difference: 0
|
||||||
|
}
|
||||||
|
if (name_del === name_add) continue
|
||||||
|
logger.debug(logger.yellow(`差异计算:${name_del}->${name_add}`))
|
||||||
|
this.cache = Object.create(null)
|
||||||
|
// @ts-ignore
|
||||||
|
this.buffM.buffs.push({
|
||||||
|
name: logger.green(`差异计算:${name_del}->${name_add}`),
|
||||||
|
type: type_add,
|
||||||
|
value: value_add
|
||||||
|
})
|
||||||
|
const newDamage = this.calc_skill(skill)
|
||||||
|
this.buffM.buffs.pop()
|
||||||
|
data.damage = newDamage
|
||||||
|
data.difference = newDamage.result.expectDMG - oriDamage.result.expectDMG
|
||||||
|
logger.debug(logger.magenta(`差异计算:${name_del}->${name_add} 伤害变化:${data.difference}`))
|
||||||
|
}
|
||||||
|
this.buffM.buffs.pop()
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置后续新增buff参数的默认值
|
* 设置后续新增buff参数的默认值
|
||||||
* @param obj 直接覆盖默认值
|
* @param obj 直接覆盖默认值
|
||||||
|
|
@ -414,7 +553,7 @@ export class Calculator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取局内属性原始值
|
* 获取局内属性原始值
|
||||||
* @param isRatio 是否支持buff.value为数值/字符串/数组类型且<1时按初始数值百分比提高处理
|
* @param isRatio 是否支持buff.value为数值/字符串/数组类型且<1时按 **`初始数值`** 百分比提高处理
|
||||||
*/
|
*/
|
||||||
get(type: buff['type'], initial: number, skill: skill, usefulBuffs: buff[] = this.buffM.buffs, isRatio = false): number {
|
get(type: buff['type'], initial: number, skill: skill, usefulBuffs: buff[] = this.buffM.buffs, isRatio = false): number {
|
||||||
return this.props[type] ??= this.buffM._filter(usefulBuffs, {
|
return this.props[type] ??= this.buffM._filter(usefulBuffs, {
|
||||||
|
|
@ -425,13 +564,15 @@ export class Calculator {
|
||||||
}, this).reduce((previousValue, buff) => {
|
}, this).reduce((previousValue, buff) => {
|
||||||
const { value } = buff
|
const { value } = buff
|
||||||
let add = 0
|
let add = 0
|
||||||
if (isRatio && typeof value === 'number' && value < 1) { // 值小于1时,认为是百分比
|
if (isRatio && typeof value === 'number' && Math.abs(value) < 1) { // 绝对值小于1时,认为是百分比
|
||||||
add = value * initial
|
add = value * initial
|
||||||
} else {
|
} else {
|
||||||
add = this.calc_value(value, buff)
|
add = this.calc_value(value, buff)
|
||||||
if (add < 1 && isRatio && (typeof value === 'string' || Array.isArray(value)))
|
if (Math.abs(add) < 1 && isRatio && (typeof value === 'string' || Array.isArray(value)))
|
||||||
add *= initial
|
add *= initial
|
||||||
}
|
}
|
||||||
|
if (!this.usefulBuffs.find(b => b.name === buff.name && b.type === buff.type && add === buff.value))
|
||||||
|
this.usefulBuffs.push({ ...buff, value: add })
|
||||||
logger.debug(`\tBuff:${buff.name}对${buff.range || '全类型'}增加${add}${buff.element || ''}${type}`)
|
logger.debug(`\tBuff:${buff.name}对${buff.range || '全类型'}增加${add}${buff.element || ''}${type}`)
|
||||||
return previousValue + add
|
return previousValue + add
|
||||||
}, initial)
|
}, initial)
|
||||||
|
|
@ -484,7 +625,8 @@ export class Calculator {
|
||||||
|
|
||||||
/** 抗性区 */
|
/** 抗性区 */
|
||||||
get_ResistanceArea(skill: skill, usefulBuffs: buff[]) {
|
get_ResistanceArea(skill: skill, usefulBuffs: buff[]) {
|
||||||
const ResistanceArea = this.get('无视抗性', 1 + this.enemy.resistance, skill, usefulBuffs)
|
let ResistanceArea = this.get('无视抗性', 1 + this.enemy.resistance, skill, usefulBuffs)
|
||||||
|
ResistanceArea = Math.min(2, ResistanceArea)
|
||||||
logger.debug(`抗性区:${ResistanceArea}`)
|
logger.debug(`抗性区:${ResistanceArea}`)
|
||||||
return ResistanceArea
|
return ResistanceArea
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,10 +104,10 @@ async function importFile(type, name, isWatch = false) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await init();
|
await init();
|
||||||
export function avatar_ability(avatar) {
|
export function avatar_calc(avatar) {
|
||||||
const m = calcFnc.character[avatar.id];
|
const m = calcFnc.character[avatar.id];
|
||||||
if (!m)
|
if (!m)
|
||||||
return [];
|
return;
|
||||||
const buffM = new BuffManager(avatar);
|
const buffM = new BuffManager(avatar);
|
||||||
const calc = new Calculator(buffM);
|
const calc = new Calculator(buffM);
|
||||||
logger.debug('initial_properties', avatar.initial_properties);
|
logger.debug('initial_properties', avatar.initial_properties);
|
||||||
|
|
@ -120,7 +120,7 @@ export function avatar_ability(avatar) {
|
||||||
if (m.calc)
|
if (m.calc)
|
||||||
m.calc(buffM, calc, avatar);
|
m.calc(buffM, calc, avatar);
|
||||||
logger.debug(`Buff*${buffM.buffs.length}:`, buffM.buffs);
|
logger.debug(`Buff*${buffM.buffs.length}:`, buffM.buffs);
|
||||||
return calc.calc();
|
return calc;
|
||||||
}
|
}
|
||||||
export function weapon_buff(weapon, buffM) {
|
export function weapon_buff(weapon, buffM) {
|
||||||
const name = weapon?.name;
|
const name = weapon?.name;
|
||||||
|
|
|
||||||
|
|
@ -137,10 +137,10 @@ async function importFile(type: 'weapon' | 'set', name: string, isWatch = false)
|
||||||
|
|
||||||
await init()
|
await init()
|
||||||
|
|
||||||
/** 角色计算 */
|
/** 角色计算实例 */
|
||||||
export function avatar_ability(avatar: ZZZAvatarInfo) {
|
export function avatar_calc(avatar: ZZZAvatarInfo) {
|
||||||
const m = calcFnc.character[avatar.id]
|
const m = calcFnc.character[avatar.id]
|
||||||
if (!m) return []
|
if (!m) return
|
||||||
const buffM = new BuffManager(avatar)
|
const buffM = new BuffManager(avatar)
|
||||||
const calc = new Calculator(buffM)
|
const calc = new Calculator(buffM)
|
||||||
logger.debug('initial_properties', avatar.initial_properties)
|
logger.debug('initial_properties', avatar.initial_properties)
|
||||||
|
|
@ -150,7 +150,7 @@ export function avatar_ability(avatar: ZZZAvatarInfo) {
|
||||||
if (m.skills) calc.new(m.skills)
|
if (m.skills) calc.new(m.skills)
|
||||||
if (m.calc) m.calc(buffM, calc, avatar)
|
if (m.calc) m.calc(buffM, calc, avatar)
|
||||||
logger.debug(`Buff*${buffM.buffs.length}:`, buffM.buffs)
|
logger.debug(`Buff*${buffM.buffs.length}:`, buffM.buffs)
|
||||||
return calc.calc()
|
return calc
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 武器加成 */
|
/** 武器加成 */
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,11 @@ export const buffs = [
|
||||||
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
||||||
export const skills = [
|
export const skills = [
|
||||||
{ name: '灼烧', type: '灼烧' },
|
{ name: '灼烧', type: '灼烧' },
|
||||||
{ name: '普攻:火力镇压四段', type: 'AQ4' },
|
{
|
||||||
|
name: '普攻:火力镇压四段',
|
||||||
|
isMain: true,
|
||||||
|
type: 'AQ4'
|
||||||
|
},
|
||||||
{ name: '闪避反击:逆火', type: 'CF' },
|
{ name: '闪避反击:逆火', type: 'CF' },
|
||||||
{ name: '强化特殊技:盛燃烈火', type: 'EQ' },
|
{ name: '强化特殊技:盛燃烈火', type: 'EQ' },
|
||||||
{ name: '连携技:昂扬烈焰', type: 'RL' },
|
{ name: '连携技:昂扬烈焰', type: 'RL' },
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ export const skills = [
|
||||||
name: '普攻:协奏狙杀·冥狱',
|
name: '普攻:协奏狙杀·冥狱',
|
||||||
type: 'AXQ',
|
type: 'AXQ',
|
||||||
redirect: ['AXQ', '追加攻击'],
|
redirect: ['AXQ', '追加攻击'],
|
||||||
|
isMain: true,
|
||||||
after: ({ damage }) => damage.add('AXQ0')
|
after: ({ damage }) => damage.add('AXQ0')
|
||||||
},
|
},
|
||||||
{ name: '闪避反击:极魂罚', type: 'CF' },
|
{ name: '闪避反击:极魂罚', type: 'CF' },
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ export const skills = [
|
||||||
type: 'EQ',
|
type: 'EQ',
|
||||||
after: ({ damage }) => damage.add('EQ0')
|
after: ({ damage }) => damage.add('EQ0')
|
||||||
},
|
},
|
||||||
{ name: '连携技:月辉丝·绊', type: 'RL' },
|
{ name: '连携技:月辉丝·绊', isMain: true, type: 'RL' },
|
||||||
{ name: '终结技:月辉丝·弦音', type: 'RZ' },
|
{ name: '终结技:月辉丝·弦音', type: 'RZ' },
|
||||||
{
|
{
|
||||||
name: '6影月辉丝·弦',
|
name: '6影月辉丝·弦',
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,12 @@ export const skills = [
|
||||||
isHide: true,
|
isHide: true,
|
||||||
after: ({ damage }) => damage.x(2)
|
after: ({ damage }) => damage.x(2)
|
||||||
},
|
},
|
||||||
{ name: '强化特殊技:小心裙角', type: 'EQ', after: ({ damage }) => damage.add('EQ0') },
|
{
|
||||||
|
name: '强化特殊技:小心裙角',
|
||||||
|
type: 'EQ',
|
||||||
|
isMain: true,
|
||||||
|
after: ({ damage }) => damage.add('EQ0')
|
||||||
|
},
|
||||||
{ name: '连携技:抱歉…', type: 'RL' },
|
{ name: '连携技:抱歉…', type: 'RL' },
|
||||||
{ name: '终结技:非、非常抱歉!', type: 'RZ' }
|
{ name: '终结技:非、非常抱歉!', type: 'RZ' }
|
||||||
]
|
]
|
||||||
|
|
@ -36,7 +36,7 @@ export const skills = [
|
||||||
{ name: '感电每次', type: '感电' },
|
{ name: '感电每次', type: '感电' },
|
||||||
{ name: '普攻:穿云五段', type: 'AP5' },
|
{ name: '普攻:穿云五段', type: 'AP5' },
|
||||||
{ name: '普攻:落羽', type: 'AX' },
|
{ name: '普攻:落羽', type: 'AX' },
|
||||||
{ name: '冲刺攻击:飞弦·斩', type: 'CCQ3' },
|
{ name: '冲刺攻击:飞弦·斩', isMain: true, type: 'CCQ3' },
|
||||||
{ name: '强化特殊技:地网', type: 'EQ' },
|
{ name: '强化特殊技:地网', type: 'EQ' },
|
||||||
{ name: '连携技:会·离', type: 'RL' },
|
{ name: '连携技:会·离', type: 'RL' },
|
||||||
{ name: '终结技:残心', type: 'RZ' }
|
{ name: '终结技:残心', type: 'RZ' }
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@
|
||||||
// calc.new({
|
// calc.new({
|
||||||
// name: '蓄力攻击:三段蓄',
|
// name: '蓄力攻击:三段蓄',
|
||||||
// type: 'AX3',
|
// type: 'AX3',
|
||||||
|
// isMain: true,
|
||||||
// after: ({ avatar, damage }) => avatar.rank >= 6 && damage.add('AX2')
|
// after: ({ avatar, damage }) => avatar.rank >= 6 && damage.add('AX2')
|
||||||
// })
|
// })
|
||||||
// calc.new({ name: '强化特殊技:飞雪', type: 'EQ1' })
|
// calc.new({ name: '强化特殊技:飞雪', type: 'EQ1' })
|
||||||
|
|
@ -164,6 +165,7 @@ export const skills = [
|
||||||
{
|
{
|
||||||
name: '蓄力攻击:三段蓄',
|
name: '蓄力攻击:三段蓄',
|
||||||
type: 'AX3',
|
type: 'AX3',
|
||||||
|
isMain: true,
|
||||||
after: ({ avatar, damage }) => avatar.rank >= 6 && damage.add('AX2')
|
after: ({ avatar, damage }) => avatar.rank >= 6 && damage.add('AX2')
|
||||||
},
|
},
|
||||||
{ name: '强化特殊技:飞雪', type: 'EQ1' },
|
{ name: '强化特殊技:飞雪', type: 'EQ1' },
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ export const skills = [
|
||||||
{
|
{
|
||||||
name: '强化E极性紊乱',
|
name: '强化E极性紊乱',
|
||||||
type: '紊乱',
|
type: '紊乱',
|
||||||
|
isMain: true,
|
||||||
banCache: true,
|
banCache: true,
|
||||||
before: ({ calc, areas }) => {
|
before: ({ calc, areas }) => {
|
||||||
const skill = { type: '紊乱' }
|
const skill = { type: '紊乱' }
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ export const skills = [
|
||||||
{
|
{
|
||||||
name: '强化特殊技:全弹连射',
|
name: '强化特殊技:全弹连射',
|
||||||
type: 'EQ',
|
type: 'EQ',
|
||||||
|
isMain: true,
|
||||||
after: ({ damage }) => damage.add('EQ2')
|
after: ({ damage }) => damage.add('EQ2')
|
||||||
},
|
},
|
||||||
{ name: '连携技:歼灭模式', type: 'RL' },
|
{ name: '连携技:歼灭模式', type: 'RL' },
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ export const buffs = [
|
||||||
{
|
{
|
||||||
name: '核心被动:燃油特调',
|
name: '核心被动:燃油特调',
|
||||||
type: '增伤',
|
type: '增伤',
|
||||||
value: ({ calc }) => Math.min(30, Math.floor(calc.get_AnomalyProficiency() / 10)) * 0.01,
|
value: ({ calc }) => Math.min(30, calc.get_AnomalyProficiency() / 10) * 0.01,
|
||||||
isForever: true,
|
isForever: true,
|
||||||
range: ['TY', 'Y6Y']
|
range: ['TY', 'Y6Y']
|
||||||
},
|
},
|
||||||
|
|
@ -46,6 +46,7 @@ export const skills = [
|
||||||
{
|
{
|
||||||
name: '核心被动:余烬',
|
name: '核心被动:余烬',
|
||||||
type: 'TY',
|
type: 'TY',
|
||||||
|
isMain: true,
|
||||||
redirect: 'L'
|
redirect: 'L'
|
||||||
},
|
},
|
||||||
// { name: '普攻:炽焰直调式五段', type: 'AP5' },
|
// { name: '普攻:炽焰直调式五段', type: 'AP5' },
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export const buffs = [
|
||||||
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
||||||
export const skills = [
|
export const skills = [
|
||||||
{ name: '感电每次', type: '感电' },
|
{ name: '感电每次', type: '感电' },
|
||||||
{ name: '紊乱', type: '紊乱' },
|
{ name: '紊乱', isMain: true, type: '紊乱' },
|
||||||
{ name: '闪避反击:违章处罚', type: 'CF' },
|
{ name: '闪避反击:违章处罚', type: 'CF' },
|
||||||
{
|
{
|
||||||
name: '强化特殊技:超规工程清障',
|
name: '强化特殊技:超规工程清障',
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ export const skills = [
|
||||||
{
|
{
|
||||||
name: '特殊技:噬爪·噩梦袭影',
|
name: '特殊技:噬爪·噩梦袭影',
|
||||||
type: 'EPLP',
|
type: 'EPLP',
|
||||||
|
isMain: true,
|
||||||
redirect: ['EPLP', '追加攻击']
|
redirect: ['EPLP', '追加攻击']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export const buffs = [
|
||||||
|
|
||||||
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
||||||
export const skills = [
|
export const skills = [
|
||||||
{ name: '强击', type: '强击' },
|
{ name: '强击', isMain: true, type: '强击' },
|
||||||
{ name: '普攻:准备发车四段', type: 'AP4' },
|
{ name: '普攻:准备发车四段', type: 'AP4' },
|
||||||
{ name: '闪避反击:动力漂移', type: 'CF' },
|
{ name: '闪避反击:动力漂移', type: 'CF' },
|
||||||
{ name: '强化特殊技:引擎转(每圈)', type: 'EQZ' },
|
{ name: '强化特殊技:引擎转(每圈)', type: 'EQZ' },
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export const buffs = [
|
||||||
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
||||||
export const skills = [
|
export const skills = [
|
||||||
{ name: '强击', type: '强击' },
|
{ name: '强击', type: '强击' },
|
||||||
{ name: '普攻:猫猫爪刺四段', type: 'AP4' },
|
{ name: '普攻:猫猫爪刺四段', isMain: true, type: 'AP4' },
|
||||||
{ name: '闪避反击:虚影双刺', type: 'CF' },
|
{ name: '闪避反击:虚影双刺', type: 'CF' },
|
||||||
{ name: '强化特殊技:超~凶奇袭!', type: 'EQ' },
|
{ name: '强化特殊技:超~凶奇袭!', type: 'EQ' },
|
||||||
{ name: '连携技:刃爪挥击', type: 'RL' },
|
{ name: '连携技:刃爪挥击', type: 'RL' },
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ export const buffs = [
|
||||||
|
|
||||||
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
||||||
export const skills = [
|
export const skills = [
|
||||||
{ name: '强击', type: '强击' },
|
{ name: '强击', isMain: true, type: '强击' },
|
||||||
{ name: '紊乱', type: '紊乱' },
|
{ name: '紊乱', type: '紊乱' },
|
||||||
{ name: '普攻:跳步刃舞六段(狂热)', type: 'AP6' },
|
{ name: '普攻:跳步刃舞六段(狂热)', type: 'AP6' },
|
||||||
{ name: '普攻:萨霍夫跳0', type: 'AX0', isHide: true },
|
{ name: '普攻:萨霍夫跳0', type: 'AX0', isHide: true },
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ export const skills = [
|
||||||
},
|
},
|
||||||
{ name: '普攻:间奏/终曲每[震音]', type: 'AQ', before },
|
{ name: '普攻:间奏/终曲每[震音]', type: 'AQ', before },
|
||||||
{ name: '特殊技:《风铃与旧约》', type: 'EP', before },
|
{ name: '特殊技:《风铃与旧约》', type: 'EP', before },
|
||||||
{ name: '和弦追加[震音]', type: 'EQZ', before },
|
{ name: '和弦追加[震音]', isMain: true, type: 'EQZ', before },
|
||||||
{ name: '天赋追加[震音]', type: 'EZ', before },
|
{ name: '天赋追加[震音]', type: 'EZ', before },
|
||||||
{
|
{
|
||||||
name: '追加[音簇]*3',
|
name: '追加[音簇]*3',
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ export const buffs = [
|
||||||
value: 0.6,
|
value: 0.6,
|
||||||
range: ['EQ']
|
range: ['EQ']
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: '6影',
|
name: '6影',
|
||||||
type: '穿透率',
|
type: '穿透率',
|
||||||
|
|
@ -40,7 +39,11 @@ export const buffs = [
|
||||||
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
||||||
export const skills = [
|
export const skills = [
|
||||||
{ name: '碎冰', type: '碎冰' },
|
{ name: '碎冰', type: '碎冰' },
|
||||||
{ name: '普攻:急冻修剪法三段', type: 'AQ3' },
|
{
|
||||||
|
name: '普攻:急冻修剪法三段',
|
||||||
|
isMain: true,
|
||||||
|
type: 'AQ3'
|
||||||
|
},
|
||||||
{ name: '闪避反击:暗礁', type: 'CF' },
|
{ name: '闪避反击:暗礁', type: 'CF' },
|
||||||
{ name: '冲刺攻击:寒潮', type: 'CCP' },
|
{ name: '冲刺攻击:寒潮', type: 'CCP' },
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export const skills = [
|
||||||
{ name: '蓄力普攻:五段一级', type: 'AX51' },
|
{ name: '蓄力普攻:五段一级', type: 'AX51' },
|
||||||
{ name: '蓄力普攻:五段二级', type: 'AX52' },
|
{ name: '蓄力普攻:五段二级', type: 'AX52' },
|
||||||
{ name: '闪避反击:保持清洁', type: 'CF' },
|
{ name: '闪避反击:保持清洁', type: 'CF' },
|
||||||
{ name: '蓄力强化特殊技:狂猎时刻', type: 'EQX' },
|
{ name: '蓄力强化特殊技:狂猎时刻', isMain: true, type: 'EQX' },
|
||||||
{ name: '连携技:遵命', type: 'RL' },
|
{ name: '连携技:遵命', type: 'RL' },
|
||||||
{ name: '终结技:不辱使命', type: 'RZ' }
|
{ name: '终结技:不辱使命', type: 'RZ' }
|
||||||
]
|
]
|
||||||
|
|
@ -41,15 +41,18 @@ export const buffs = [
|
||||||
element: ['Fire', 'Ice'],
|
element: ['Fire', 'Ice'],
|
||||||
value: ({ calc }) => {
|
value: ({ calc }) => {
|
||||||
const Impact = calc.get_Impact()
|
const Impact = calc.get_Impact()
|
||||||
const step = 0.0125 + Math.max(0, Math.floor((Impact - 170) / 10) * 25 / 10000)
|
const step = 0.0125 + Math.max(0, (Impact - 170) / 10 * 25 / 10000)
|
||||||
return Math.min(0.75, step * 20)
|
return Math.min(0.75, step * 20)
|
||||||
|
},
|
||||||
|
is: {
|
||||||
|
team: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
/** @type {import('../../Calculator.ts').Calculator['skills']} */
|
||||||
export const skills = [
|
export const skills = [
|
||||||
{ name: '普攻:强力终结一击', type: 'AQ5Q' },
|
{ name: '普攻:强力终结一击', isMain: true, type: 'AQ5Q' },
|
||||||
{ name: '闪避反击:烈闪', type: 'CF' },
|
{ name: '闪避反击:烈闪', type: 'CF' },
|
||||||
{ name: '快速支援:烈闪-守', type: 'LK' },
|
{ name: '快速支援:烈闪-守', type: 'LK' },
|
||||||
{ name: '强化E:V式日轮升拳-全冲程', type: 'EQ1' },
|
{ name: '强化E:V式日轮升拳-全冲程', type: 'EQ1' },
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ export const skills = [
|
||||||
name: '特殊技:苍光',
|
name: '特殊技:苍光',
|
||||||
type: 'EPC',
|
type: 'EPC',
|
||||||
redirect: ['EPC', '追加攻击'],
|
redirect: ['EPC', '追加攻击'],
|
||||||
|
isMain: true,
|
||||||
after: ({ damage }) => damage.add('EPC0')
|
after: ({ damage }) => damage.add('EPC0')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ export const skills = [
|
||||||
},
|
},
|
||||||
{ name: '闪避反击:獠牙折转!', type: 'CF' },
|
{ name: '闪避反击:獠牙折转!', type: 'CF' },
|
||||||
{ name: '强化特殊技:全垒打短按', type: 'EQP' },
|
{ name: '强化特殊技:全垒打短按', type: 'EQP' },
|
||||||
{ name: '强化特殊技:全垒打长按', type: 'EQX' },
|
{ name: '强化特殊技:全垒打长按', isMain: true, type: 'EQX' },
|
||||||
{
|
{
|
||||||
name: '连携技:大满贯!',
|
name: '连携技:大满贯!',
|
||||||
type: 'RL',
|
type: 'RL',
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
{
|
{
|
||||||
"11102": ["HPRatio", "生命值百分比", "生命"],
|
"11102": ["HPRatio", "生命值百分比", "生命", "大生命"],
|
||||||
"11103": ["HP", "生命值", "生命"],
|
"11103": ["HP", "生命值", "生命", "小生命"],
|
||||||
"12102": ["ATKRatio", "攻击力百分比", "攻击"],
|
"12102": ["ATKRatio", "攻击力百分比", "攻击", "大攻击"],
|
||||||
"12103": ["ATK", "攻击力", "攻击"],
|
"12103": ["ATK", "攻击力", "攻击", "小攻击"],
|
||||||
"12202": ["Impact", "冲击力", "冲击"],
|
"12202": ["Impact", "冲击力", "冲击", "冲击力"],
|
||||||
"13102": ["DEFRatio", "防御力百分比", "防御"],
|
"13102": ["DEFRatio", "防御力百分比", "防御", "大防御"],
|
||||||
"13103": ["DEF", "防御力", "防御"],
|
"13103": ["DEF", "防御力", "防御", "小防御"],
|
||||||
"20103": ["CRITRate", "暴击率", "暴击"],
|
"20103": ["CRITRate", "暴击率", "暴击", "暴击率"],
|
||||||
"21103": ["CRITDMG", "暴击伤害", "暴伤"],
|
"21103": ["CRITDMG", "暴击伤害", "暴伤", "暴伤"],
|
||||||
"23103": ["PenRatio", "穿透率", "穿透"],
|
"23103": ["PenRatio", "穿透率", "穿透", "穿透率"],
|
||||||
"23203": ["Pen", "穿透值", "穿透"],
|
"23203": ["Pen", "穿透值", "穿透", "穿透值"],
|
||||||
"30502": ["EnergyRegen", "能量回复", "回能"],
|
"30502": ["EnergyRegen", "能量回复", "回能", "回能"],
|
||||||
"31203": ["AnomalyProficiency", "异常精通", "精通"],
|
"31203": ["AnomalyProficiency", "异常精通", "精通", "精通"],
|
||||||
"31402": ["AnomalyMastery", "异常掌控", "掌控"],
|
"31402": ["AnomalyMastery", "异常掌控", "掌控", "掌控"],
|
||||||
"31503": ["PhysicalDMGBonus", "物理属性伤害提高", "物伤"],
|
"31503": ["PhysicalDMGBonus", "物理属性伤害提高", "物伤", "物伤"],
|
||||||
"31603": ["FireDMGBonus", "火属性伤害提高", "火伤"],
|
"31603": ["FireDMGBonus", "火属性伤害提高", "火伤", "火伤"],
|
||||||
"31703": ["IceDMGBonus", "冰属性伤害提高", "冰伤"],
|
"31703": ["IceDMGBonus", "冰属性伤害提高", "冰伤", "冰伤"],
|
||||||
"31803": ["ElectricDMGBonus", "电属性伤害提高", "电伤"],
|
"31803": ["ElectricDMGBonus", "电属性伤害提高", "电伤", "电伤"],
|
||||||
"31903": ["EtherDMGBonus", "以太属性伤害提高", "以伤"]
|
"31903": ["EtherDMGBonus", "以太属性伤害提高", "以伤", "以太伤"]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -255,30 +255,6 @@
|
||||||
.card .basic .info .char_info .addition .role_ranks.r6 span:nth-child(6) {
|
.card .basic .info .char_info .addition .role_ranks.r6 span:nth-child(6) {
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
}
|
}
|
||||||
.card .basic .info .char_info .addition .role_ranks span:nth-child(7) {
|
|
||||||
background-image: url("./images/ranks/7.png");
|
|
||||||
}
|
|
||||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(1) {
|
|
||||||
opacity: 1 !important;
|
|
||||||
}
|
|
||||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(2) {
|
|
||||||
opacity: 1 !important;
|
|
||||||
}
|
|
||||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(3) {
|
|
||||||
opacity: 1 !important;
|
|
||||||
}
|
|
||||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(4) {
|
|
||||||
opacity: 1 !important;
|
|
||||||
}
|
|
||||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(5) {
|
|
||||||
opacity: 1 !important;
|
|
||||||
}
|
|
||||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(6) {
|
|
||||||
opacity: 1 !important;
|
|
||||||
}
|
|
||||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(7) {
|
|
||||||
opacity: 1 !important;
|
|
||||||
}
|
|
||||||
.card .basic .info .property_info {
|
.card .basic .info .property_info {
|
||||||
background-color: rgb(47, 47, 47);
|
background-color: rgb(47, 47, 47);
|
||||||
border-left: 0.1em solid rgb(0, 0, 0);
|
border-left: 0.1em solid rgb(0, 0, 0);
|
||||||
|
|
@ -854,7 +830,7 @@
|
||||||
padding-top: 1.2em;
|
padding-top: 1.2em;
|
||||||
}
|
}
|
||||||
.card .damagelist {
|
.card .damagelist {
|
||||||
margin: 0 2em;
|
margin: 0 1.2em;
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
@ -866,12 +842,10 @@
|
||||||
}
|
}
|
||||||
.card .damagelist .dmg-tr {
|
.card .damagelist .dmg-tr {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1.5fr 1fr 1fr;
|
grid-template-columns: 0.25fr 1.6fr 1fr 1fr;
|
||||||
border-bottom: 0.1em solid rgba(255, 255, 255, 0.2);
|
border-bottom: 0.1em solid rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
.card .damagelist .dmg-tr:first-child {
|
.card .damagelist .dmg-tr:first-child {
|
||||||
border-top: 0.2em solid rgba(255, 255, 255, 0.2);
|
|
||||||
border-bottom: 0.2em solid rgba(255, 255, 255, 0.2);
|
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
background: rgba(0, 0, 0, 0.2);
|
background: rgba(0, 0, 0, 0.2);
|
||||||
text-shadow: 0 0 0.2em rgba(0, 0, 0, 0.6);
|
text-shadow: 0 0 0.2em rgba(0, 0, 0, 0.6);
|
||||||
|
|
@ -881,13 +855,28 @@
|
||||||
text-align: center !important;
|
text-align: center !important;
|
||||||
background: none !important;
|
background: none !important;
|
||||||
}
|
}
|
||||||
|
.card .damagelist .dmg-tr:nth-child(even) {
|
||||||
|
background-color: rgba(255, 255, 255, 0.12);
|
||||||
|
}
|
||||||
|
.card .damagelist .dmg-tr:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.card .damagelist .info-tr {
|
||||||
|
font-size: 0.8em !important;
|
||||||
|
display: grid !important;
|
||||||
|
grid-template-columns: 1fr !important;
|
||||||
|
padding: 0.3em !important;
|
||||||
|
color: #bbb !important;
|
||||||
|
}
|
||||||
|
.card .damagelist .info-tr span {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
.card .damagelist .dmg-td {
|
.card .damagelist .dmg-td {
|
||||||
padding: 0.5em 0.5em;
|
padding: 0.5em 0.5em;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
border-right: 0.1em solid rgba(255, 255, 255, 0.2);
|
border-right: 0.1em solid rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
.card .damagelist .dmg-td:first-child {
|
.card .damagelist .dmg-td:nth-child(2) {
|
||||||
text-align: left;
|
|
||||||
background: rgba(0, 0, 0, 0.2);
|
background: rgba(0, 0, 0, 0.2);
|
||||||
color: rgb(206, 190, 149);
|
color: rgb(206, 190, 149);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -243,17 +243,23 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="damagelist">
|
<div class="damagelist">
|
||||||
<div class="dmg-tr titlebar no-zzz-font">
|
<div class="dmg-tr titlebar no-zzz-font">
|
||||||
<div class="dmg-td">类型</div>
|
<div class="td dmg-td">%</div>
|
||||||
|
<div class="dmg-td">技能类型</div>
|
||||||
<div class="dmg-td">暴击伤害</div>
|
<div class="dmg-td">暴击伤害</div>
|
||||||
<div class="dmg-td">期望伤害</div>
|
<div class="dmg-td">期望伤害</div>
|
||||||
</div>
|
</div>
|
||||||
{{each damages damage}}
|
{{each damages damage,index}}
|
||||||
<div class="dmg-tr">
|
<div class="dmg-tr">
|
||||||
|
<div class="dmg-td">{{index+1}}</div>
|
||||||
<div class="dmg-td no-zzz-font">{{damage.skill.name}}</div>
|
<div class="dmg-td no-zzz-font">{{damage.skill.name}}</div>
|
||||||
<div class="dmg-td">{{damage.result.critDMG.toFixed(0)}}</div>
|
<div class="dmg-td">{{damage.result.critDMG.toFixed(0)}}</div>
|
||||||
<div class="dmg-td">{{damage.result.expectDMG.toFixed(0)}}</div>
|
<div class="dmg-td">{{damage.result.expectDMG.toFixed(0)}}</div>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
<div class="tr dmg-tr info-tr no-zzz-font">
|
||||||
|
<div>伤害计算默认取有弱点、角色等级、1级基础防御力为50的敌方数据,且不考虑失衡易伤区</div>
|
||||||
|
<div>可通过<span>%{{charData.name_mi18n}}伤害+序号</span>查看指定技能伤害详情 如<span>%{{charData.name_mi18n}}伤害1</span></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@for $i from 1 through 7 {
|
@for $i from 1 through 6 {
|
||||||
span:nth-child(#{$i}) {
|
span:nth-child(#{$i}) {
|
||||||
background-image: url('./images/ranks/#{$i}.png');
|
background-image: url('./images/ranks/#{$i}.png');
|
||||||
}
|
}
|
||||||
|
|
@ -843,7 +843,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.damagelist {
|
.damagelist {
|
||||||
margin: 0 2em;
|
margin: 0 1.2em;
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
@ -855,12 +855,10 @@
|
||||||
|
|
||||||
.dmg-tr {
|
.dmg-tr {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1.5fr 1fr 1fr;
|
grid-template-columns: 0.25fr 1.6fr 1fr 1fr;
|
||||||
border-bottom: 0.1em solid rgba(255, 255, 255, 0.2);
|
border-bottom: 0.1em solid rgba(255, 255, 255, 0.2);
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
border-top: 0.2em solid rgba(255, 255, 255, 0.2);
|
|
||||||
border-bottom: 0.2em solid rgba(255, 255, 255, 0.2);
|
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
background: rgba(0, 0, 0, 0.2);
|
background: rgba(0, 0, 0, 0.2);
|
||||||
text-shadow: 0 0 0.2em rgba(0, 0, 0, 0.6);
|
text-shadow: 0 0 0.2em rgba(0, 0, 0, 0.6);
|
||||||
|
|
@ -870,14 +868,32 @@
|
||||||
background: none !important;
|
background: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
background-color: rgba(255, 255, 255, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-tr {
|
||||||
|
font-size: 0.8em !important;
|
||||||
|
display: grid !important;
|
||||||
|
grid-template-columns: 1fr !important;
|
||||||
|
padding: 0.3em !important;
|
||||||
|
color: #bbb !important;
|
||||||
|
span {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dmg-td {
|
.dmg-td {
|
||||||
padding: 0.5em 0.5em;
|
padding: 0.5em 0.5em;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
border-right: 0.1em solid rgba(255, 255, 255, 0.2);
|
border-right: 0.1em solid rgba(255, 255, 255, 0.2);
|
||||||
&:first-child {
|
&:nth-child(2) {
|
||||||
text-align: left;
|
|
||||||
background: rgba(0, 0, 0, 0.2);
|
background: rgba(0, 0, 0, 0.2);
|
||||||
color: rgb(206, 190, 149);
|
color: rgb(206, 190, 149);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
557
resources/panel/damage.css
Normal file
557
resources/panel/damage.css
Normal file
|
|
@ -0,0 +1,557 @@
|
||||||
|
@charset "UTF-8";
|
||||||
|
.damage {
|
||||||
|
padding-top: 0.8em;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
/* 伤害统计 */
|
||||||
|
/* 乘区数据 */
|
||||||
|
/* buff统计 */
|
||||||
|
/* 差异计算 */
|
||||||
|
}
|
||||||
|
.damage .uid {
|
||||||
|
font-size: 0.6em;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
border-image-source: url("./images/CurseBG08.png");
|
||||||
|
border-image-slice: 30 60 30 60 fill;
|
||||||
|
border-image-width: 0.5em 1em 0.5em 1em;
|
||||||
|
border-image-outset: 0em 0em 0em 0em;
|
||||||
|
border-image-repeat: stretch stretch;
|
||||||
|
padding: 0.5em 1.2em;
|
||||||
|
font-size: 1em;
|
||||||
|
top: 0.5em;
|
||||||
|
left: 0.5em;
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
stroke: 0.05em rgba(0, 0, 0, 0.6);
|
||||||
|
-webkit-text-stroke: 0.05em rgba(0, 0, 0, 0.6);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.damage .star {
|
||||||
|
width: 5.5em;
|
||||||
|
height: 1.5em;
|
||||||
|
}
|
||||||
|
.damage .star.star0 {
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-image: url("./images/star/0.png");
|
||||||
|
}
|
||||||
|
.damage .star.star1 {
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-image: url("./images/star/1.png");
|
||||||
|
}
|
||||||
|
.damage .star.star2 {
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-image: url("./images/star/2.png");
|
||||||
|
}
|
||||||
|
.damage .star.star3 {
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-image: url("./images/star/3.png");
|
||||||
|
}
|
||||||
|
.damage .star.star4 {
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-image: url("./images/star/4.png");
|
||||||
|
}
|
||||||
|
.damage .star.star5 {
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-image: url("./images/star/5.png");
|
||||||
|
}
|
||||||
|
.damage .basic {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.damage .basic .char {
|
||||||
|
width: 55%;
|
||||||
|
position: relative;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.damage .basic .char .avatar {
|
||||||
|
height: 100%;
|
||||||
|
padding-top: 1em;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.damage .basic .char .avatar img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: top center;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.damage .basic .char .skills {
|
||||||
|
position: absolute;
|
||||||
|
width: 120%;
|
||||||
|
height: 3.5em;
|
||||||
|
background: url("./images/skill_bg.png");
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
bottom: 3em;
|
||||||
|
right: -1.6em;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
padding-left: 2.5em;
|
||||||
|
padding-bottom: 0.2em;
|
||||||
|
}
|
||||||
|
.damage .basic .char .skills .skill {
|
||||||
|
width: 1.4em;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
margin-right: 1.38em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.damage .basic .info {
|
||||||
|
width: 45%;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 1.2em;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info {
|
||||||
|
width: 140%;
|
||||||
|
position: relative;
|
||||||
|
right: 20%;
|
||||||
|
padding: 0.3em 0.2em;
|
||||||
|
padding-right: 20%;
|
||||||
|
padding-left: 8%;
|
||||||
|
border-image-slice: 0 30 0 40 fill;
|
||||||
|
border-image-width: 0em 1.5em 0em 2em;
|
||||||
|
border-image-outset: 0 0 0 0;
|
||||||
|
border-image-repeat: stretch stretch;
|
||||||
|
border-image-source: url("./images/CurseBG04.png");
|
||||||
|
filter: drop-shadow(0 0 0.1em rgb(0, 0, 0));
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .base {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.2em;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .base .rank {
|
||||||
|
width: 1.2em;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .base .property {
|
||||||
|
width: 1em;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .base .name {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 0.7em;
|
||||||
|
gap: 0.2em;
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .level {
|
||||||
|
background-color: #000;
|
||||||
|
padding: 0em 0.7em;
|
||||||
|
border-radius: 1em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.1em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks span {
|
||||||
|
width: 1.2em;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
border-radius: 1em;
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks span:nth-child(1) {
|
||||||
|
background-image: url("./images/ranks/1.png");
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r1 span:nth-child(1) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks span:nth-child(2) {
|
||||||
|
background-image: url("./images/ranks/2.png");
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r2 span:nth-child(1) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r2 span:nth-child(2) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks span:nth-child(3) {
|
||||||
|
background-image: url("./images/ranks/3.png");
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r3 span:nth-child(1) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r3 span:nth-child(2) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r3 span:nth-child(3) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks span:nth-child(4) {
|
||||||
|
background-image: url("./images/ranks/4.png");
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r4 span:nth-child(1) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r4 span:nth-child(2) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r4 span:nth-child(3) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r4 span:nth-child(4) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks span:nth-child(5) {
|
||||||
|
background-image: url("./images/ranks/5.png");
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r5 span:nth-child(1) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r5 span:nth-child(2) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r5 span:nth-child(3) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r5 span:nth-child(4) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r5 span:nth-child(5) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks span:nth-child(6) {
|
||||||
|
background-image: url("./images/ranks/6.png");
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r6 span:nth-child(1) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r6 span:nth-child(2) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r6 span:nth-child(3) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r6 span:nth-child(4) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r6 span:nth-child(5) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .char_info .addition .role_ranks.r6 span:nth-child(6) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info {
|
||||||
|
background-color: rgb(47, 47, 47);
|
||||||
|
border-left: 0.1em solid rgb(0, 0, 0);
|
||||||
|
padding-top: 0.2em;
|
||||||
|
background: url("./images/BgFrame01.png") center/150% no-repeat;
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info .title {
|
||||||
|
font-size: 0.6em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info .title .special-title {
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info .list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.2em;
|
||||||
|
padding-bottom: 0.2em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info .list .properties {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4em;
|
||||||
|
padding: 0.05em 1em 0em 0.05em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info .list .properties:nth-child(odd) {
|
||||||
|
background-color: rgba(221, 224, 221, 0.25);
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info .list .properties .prop-icon {
|
||||||
|
width: 1em;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin: 0 0.4em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info .list .properties .label {
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
font-size: 0.65em;
|
||||||
|
color: rgb(166, 166, 166);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info .list .properties .label.yellow {
|
||||||
|
color: rgb(247, 199, 54);
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info .list .properties .label.blue {
|
||||||
|
color: rgb(65, 147, 237);
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info .list .properties .label.white {
|
||||||
|
color: rgb(233, 233, 233);
|
||||||
|
}
|
||||||
|
.damage .basic .info .property_info .list .properties .value {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info {
|
||||||
|
border-image-slice: 118 0 68 43 fill;
|
||||||
|
border-image-width: 4.5em 0em 2.7em 1.7em;
|
||||||
|
border-image-outset: 0em 0em 0em 0em;
|
||||||
|
border-image-repeat: stretch stretch;
|
||||||
|
border-image-source: url("./images/weapon_bg.png");
|
||||||
|
margin-top: -0.8em;
|
||||||
|
width: 115%;
|
||||||
|
margin-left: -15%;
|
||||||
|
font-size: 0.8em;
|
||||||
|
padding: 2em 1.2em;
|
||||||
|
padding-bottom: 3em;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .info {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .info .base {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .info .base .rarity-icon {
|
||||||
|
width: 2em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .info .base .name {
|
||||||
|
text-shadow: 0 0 0.2em rgb(0, 0, 0);
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .info .main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: stretch;
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .info .main .addition {
|
||||||
|
font-size: 0.8em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .info .main .addition .level {
|
||||||
|
-webkit-clip-path: polygon(0.2em 0%, calc(100% - 0.2em) 0%, 100% 0.2em, 100% calc(100% - 0.2em), calc(100% - 0.2em) 100%, 0.2em 100%, 0% calc(100% - 0.2em), 0% 0.2em);
|
||||||
|
clip-path: polygon(0.2em 0%, calc(100% - 0.2em) 0%, 100% 0.2em, 100% calc(100% - 0.2em), calc(100% - 0.2em) 100%, 0.2em 100%, 0% calc(100% - 0.2em), 0% 0.2em);
|
||||||
|
padding: 0 0.4em;
|
||||||
|
font-size: 0.9em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: rgb(43, 38, 40);
|
||||||
|
margin: 0.1em 0;
|
||||||
|
background-color: rgb(243, 203, 69);
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .info .main .properties {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: rgb(65, 147, 237);
|
||||||
|
gap: 0.2em;
|
||||||
|
padding: 0 0.5em;
|
||||||
|
border-radius: 1em;
|
||||||
|
margin: 0.2em 0;
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .info .main .properties.sub {
|
||||||
|
background-color: rgb(0, 0, 0);
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .info .main .properties .prop-icon {
|
||||||
|
width: 1em;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .info .main .properties .label {
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
font-size: 0.7em;
|
||||||
|
color: rgb(222, 222, 222);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 1.2em;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1;
|
||||||
|
height: 70%;
|
||||||
|
margin-right: -1em;
|
||||||
|
}
|
||||||
|
.damage .basic .info .weapon_info .icon img {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.damage .damage-data {
|
||||||
|
border-image-source: url("./images/BgFrame01.png");
|
||||||
|
border-image-slice: 200 100 70 280 fill;
|
||||||
|
border-image-width: 2em 1em 0.7em 2.8em;
|
||||||
|
border-image-outset: 2em 1em 0.7em 2.8em;
|
||||||
|
border-image-repeat: stretch stretch;
|
||||||
|
padding-bottom: 3.3em;
|
||||||
|
margin-top: -1.4em;
|
||||||
|
position: relative;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
.damage .title:nth-child(n+2) {
|
||||||
|
padding-top: 0.5em;
|
||||||
|
}
|
||||||
|
.damage .data-list {
|
||||||
|
margin: 0 1.2em;
|
||||||
|
text-align: center;
|
||||||
|
backdrop-filter: blur(0.2em);
|
||||||
|
border-radius: 0.5em;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 0 3em rgba(0, 0, 0, 0.6);
|
||||||
|
border: 0.1em solid rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
.damage .data-list .tr {
|
||||||
|
display: grid;
|
||||||
|
border-bottom: 0.1em solid rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
.damage .data-list .tr:first-child {
|
||||||
|
font-size: 1.1em;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
text-shadow: 0 0 0.2em rgba(0, 0, 0, 0.6);
|
||||||
|
color: rgb(206, 190, 149);
|
||||||
|
}
|
||||||
|
.damage .data-list .tr:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.damage .data-list .tr:nth-child(even) {
|
||||||
|
background-color: rgba(255, 255, 255, 0.12);
|
||||||
|
}
|
||||||
|
.damage .data-list .td {
|
||||||
|
padding: 0.5em 0.5em;
|
||||||
|
font-size: 0.9em;
|
||||||
|
border-right: 0.1em solid rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
.damage .data-list .td:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
.damage .data-list .info-tr {
|
||||||
|
font-size: 0.8em !important;
|
||||||
|
display: grid !important;
|
||||||
|
grid-template-columns: 1fr !important;
|
||||||
|
padding: 0.3em !important;
|
||||||
|
color: #bbb !important;
|
||||||
|
}
|
||||||
|
.damage .data-list .info-tr span {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
.damage .damage-list .dmg-tr {
|
||||||
|
grid-template-columns: 0.25fr 1.6fr 1fr 1fr;
|
||||||
|
}
|
||||||
|
.damage .damage-list .dmg-tr.current {
|
||||||
|
background: rgb(120, 104, 73);
|
||||||
|
}
|
||||||
|
.damage .damage-list .dmg-tr.current .dmg-td:nth-child(2) {
|
||||||
|
color: rgb(251, 198, 65) !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
}
|
||||||
|
.damage .damage-list .dmg-td:nth-child(2) {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: rgb(206, 190, 149);
|
||||||
|
}
|
||||||
|
.damage .area-list .area-tr {
|
||||||
|
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
|
||||||
|
}
|
||||||
|
.damage .area-list .area-tr:nth-child(odd) {
|
||||||
|
font-size: 1.1em;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
text-shadow: 0 0 0.2em rgba(0, 0, 0, 0.6);
|
||||||
|
color: rgb(206, 190, 149);
|
||||||
|
}
|
||||||
|
.damage .area-list .area-tr.anomaly {
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
}
|
||||||
|
.damage .buff-list .buff-tr {
|
||||||
|
grid-template-columns: 0.7fr 5fr 3fr 2fr;
|
||||||
|
}
|
||||||
|
.damage .buff-list .buff-td:nth-child(2) {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: rgb(206, 190, 149);
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-tr.d2 {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-tr.d3 {
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-tr.d4 {
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-tr.d5 {
|
||||||
|
grid-template-columns: repeat(6, 1fr);
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-tr.d6 {
|
||||||
|
grid-template-columns: repeat(7, 1fr);
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-tr.d7 {
|
||||||
|
grid-template-columns: repeat(8, 1fr);
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-tr.d8 {
|
||||||
|
grid-template-columns: repeat(9, 1fr);
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-tr.d9 {
|
||||||
|
grid-template-columns: repeat(10, 1fr);
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-td {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-td span {
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-td.zero {
|
||||||
|
background-color: #222;
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-td:first-child {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: rgb(206, 190, 149);
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-td.positive {
|
||||||
|
background-color: rgb(82, 38, 32);
|
||||||
|
}
|
||||||
|
.damage .difference-list .difference-td.negative {
|
||||||
|
background-color: rgb(22, 65, 33);
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
margin-top: -3.3em;
|
||||||
|
position: relative;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*# sourceMappingURL=damage.css.map */
|
||||||
257
resources/panel/damage.html
Normal file
257
resources/panel/damage.html
Normal file
|
|
@ -0,0 +1,257 @@
|
||||||
|
{{extend defaultLayout}}
|
||||||
|
|
||||||
|
{{block 'css'}}
|
||||||
|
<link rel="stylesheet" href="{{@sys.currentPath}}/damage.css">
|
||||||
|
{{/block}}
|
||||||
|
|
||||||
|
{{block 'main'}}
|
||||||
|
<div class="damage">
|
||||||
|
<div class="uid">UID {{uid}}</div>
|
||||||
|
<div class="basic">
|
||||||
|
<div class="char">
|
||||||
|
<div class="avatar">
|
||||||
|
<img src="{{charData.role_icon}}" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="skills">
|
||||||
|
<div class="skill">{{charData.skills[0].level}}</div>
|
||||||
|
<div class="skill">{{charData.skills[2].level}}</div>
|
||||||
|
<div class="skill">{{charData.skills[5].level}}</div>
|
||||||
|
<div class="skill">{{charData.skills[1].level}}</div>
|
||||||
|
<div class="skill">{{charData.skills[3].level}}</div>
|
||||||
|
<div class="skill">{{charData.skills[4].level}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<div class="char_info">
|
||||||
|
<div class="base">
|
||||||
|
<div class="rank rank-icon {{charData.rarity}}"></div>
|
||||||
|
<div class="property {{charData.element_str}}"></div>
|
||||||
|
<div class="name">{{charData.full_name_mi18n}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="addition">
|
||||||
|
<div class="level">Lv.{{charData.level}}</div>
|
||||||
|
<div class="role_ranks r{{charData.rank}}">
|
||||||
|
<span></span><span></span><span></span><span></span><span></span><span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="property_info">
|
||||||
|
<div class="title">
|
||||||
|
<% include(sys.specialTitle, {en: 'PROPERTY' , cn: '属性' , count: 6 }) %>
|
||||||
|
</div>
|
||||||
|
{{set basic_properties = charData.basic_properties}}
|
||||||
|
<div class="list">
|
||||||
|
<div class="properties">
|
||||||
|
<div class="prop-icon hpmax"></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 {{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 {{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 {{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 {{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 {{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 {{charData.get_label(31402)}}">异常掌控</div>
|
||||||
|
<div class="value">{{basic_properties.elementabnormalpower.final}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="properties">
|
||||||
|
<div class="prop-icon elementmystery"></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 {{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 {{charData.get_label(30502)}}">能量回复</div>
|
||||||
|
<div class="value">{{basic_properties.sprecover.final}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="weapon_info">
|
||||||
|
{{if charData.weapon}}
|
||||||
|
<div class="info">
|
||||||
|
<div class="base">
|
||||||
|
<div class="rarity-icon {{charData.weapon.rarity}}"></div>
|
||||||
|
<div class="name">{{charData.weapon.name}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="main">
|
||||||
|
<div class="addition">
|
||||||
|
<div class="star star{{charData.weapon.star}}"></div>
|
||||||
|
<div class="level">Lv.{{charData.weapon.level}}</div>
|
||||||
|
</div>
|
||||||
|
{{each charData.weapon.main_properties prop}}
|
||||||
|
<div class="properties">
|
||||||
|
<div class="prop-icon {{prop.classname}}"></div>
|
||||||
|
<div class="label">{{prop.property_name}}</div>
|
||||||
|
<div class="value">{{prop.base}}</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
{{each charData.weapon.properties prop}}
|
||||||
|
<div class="properties sub">
|
||||||
|
<div class="prop-icon {{prop.classname}}"></div>
|
||||||
|
<div class="label">{{prop.property_name}}</div>
|
||||||
|
<div class="value">{{prop.base}}</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="icon">
|
||||||
|
<img src="{{charData.weapon.square_icon}}" alt="">
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="info empty">
|
||||||
|
<div class="base">
|
||||||
|
<div class="rarity-icon"></div>
|
||||||
|
<div class="name"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="damage-data">
|
||||||
|
<div class="title">
|
||||||
|
<% include(sys.specialTitle, {en: 'DAMAGE' , cn: '伤害统计' }) %>
|
||||||
|
</div>
|
||||||
|
<div class="data-list damage-list">
|
||||||
|
<div class="tr dmg-tr titlebar no-zzz-font">
|
||||||
|
<div class="td dmg-td">%</div>
|
||||||
|
<div class="td dmg-td">技能类型</div>
|
||||||
|
<div class="td dmg-td">暴击伤害</div>
|
||||||
|
<div class="td dmg-td">期望伤害</div>
|
||||||
|
</div>
|
||||||
|
{{each damages d,index}}
|
||||||
|
{{if index == skill.index}}
|
||||||
|
<div class="tr dmg-tr current">
|
||||||
|
{{else}}
|
||||||
|
<div class="tr dmg-tr">
|
||||||
|
{{/if}}
|
||||||
|
<div class="td dmg-td">{{index+1}}</div>
|
||||||
|
<div class="td dmg-td no-zzz-font">{{d.skill.name}}</div>
|
||||||
|
<div class="td dmg-td">{{d.result.critDMG.toFixed(0)}}</div>
|
||||||
|
<div class="td dmg-td">{{d.result.expectDMG.toFixed(0)}}</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
<div class="tr dmg-tr info-tr no-zzz-font">
|
||||||
|
<div>伤害计算默认取有弱点、角色等级、1级基础防御力为50的敌方数据,且不考虑失衡易伤区</div>
|
||||||
|
<div>当前指令:<span>{{command}}</span></div>
|
||||||
|
<div>下列计算以 <span>{{damage.skill.name}}</span> 为计算目标</div>
|
||||||
|
<div>可通过 <span>%{{charData.name_mi18n}}伤害123</span> 切换需要查看的伤害计算</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="title">
|
||||||
|
<% include(sys.specialTitle, {en: 'AREA' , cn: '乘区数据' }) %>
|
||||||
|
</div>
|
||||||
|
<div class="data-list area-list">
|
||||||
|
{{set areas = damage.areas}}
|
||||||
|
<div class="tr area-tr titlebar no-zzz-font">
|
||||||
|
<div class="td area-td">基础区</div>
|
||||||
|
<div class="td area-td">暴击区</div>
|
||||||
|
<div class="td area-td">增伤区</div>
|
||||||
|
<div class="td area-td">易伤区</div>
|
||||||
|
<div class="td area-td">抗性区</div>
|
||||||
|
<div class="td area-td">防御区</div>
|
||||||
|
</div>
|
||||||
|
<div class="tr area-tr titlebar">
|
||||||
|
<div class="td area-td">{{(areas.BasicArea || 1).toFixed(0)}}</div>
|
||||||
|
<div class="td area-td">{{(areas.CriticalArea || 1).toFixed(2)}}</div>
|
||||||
|
<div class="td area-td">{{(areas.BoostArea || 1).toFixed(2)}}</div>
|
||||||
|
<div class="td area-td">{{(areas.VulnerabilityArea || 1).toFixed(2)}}</div>
|
||||||
|
<div class="td area-td">{{(areas.ResistanceArea || 1).toFixed(2)}}</div>
|
||||||
|
<div class="td area-td">{{(areas.DefenceArea || 1).toFixed(4)}}</div>
|
||||||
|
</div>
|
||||||
|
{{if areas.AnomalyProficiencyArea}}
|
||||||
|
<div class="tr area-tr anomaly titlebar no-zzz-font">
|
||||||
|
<div class="td area-td">异常精通区</div>
|
||||||
|
<div class="td area-td">异常增伤区</div>
|
||||||
|
<div class="td area-td">等级区</div>
|
||||||
|
</div>
|
||||||
|
<div class="tr area-tr anomaly titlebar">
|
||||||
|
<div class="td area-td">{{(areas.AnomalyProficiencyArea || 1).toFixed(2)}}</div>
|
||||||
|
<div class="td area-td">{{(areas.AnomalyBoostArea || 1).toFixed(2)}}</div>
|
||||||
|
<div class="td area-td">{{(areas.LevelArea || 1).toFixed(2)}}</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
<div class="tr area-tr info-tr no-zzz-font">
|
||||||
|
<div>注:一个技能可能分为多个出伤部分分别计算累加,此时该数据仅为一部分的乘区,下同</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="title">
|
||||||
|
<% include(sys.specialTitle, {en: 'BUFF' , cn: 'Buff统计' }) %>
|
||||||
|
</div>
|
||||||
|
<div class="data-list buff-list">
|
||||||
|
<div class="tr buff-tr titlebar no-zzz-font">
|
||||||
|
<div class="td buff-td">%</div>
|
||||||
|
<div class="td buff-td">名称</div>
|
||||||
|
<div class="td buff-td">增益类型</div>
|
||||||
|
<div class="td buff-td">增益值</div>
|
||||||
|
</div>
|
||||||
|
{{each damage.usefulBuffs buff,index}}
|
||||||
|
<div class="tr buff-tr titlebar">
|
||||||
|
<div class="td buff-td">{{index+1}}</div>
|
||||||
|
<div class="td buff-td no-zzz-font">{{buff.name}}</div>
|
||||||
|
<div class="td buff-td no-zzz-font">{{buff.type}}</div>
|
||||||
|
<div class="td buff-td">{{buff.value % 1 == 0 ? buff.value < 2 ? buff.value.toFixed(2) : buff.value : buff.value.toFixed(2)}}</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{if differences.length > 1}}
|
||||||
|
<div class="title">
|
||||||
|
<% include(sys.specialTitle, {en: 'STAT' , cn: '词条差异计算' }) %>
|
||||||
|
</div>
|
||||||
|
<div class="data-list difference-list">
|
||||||
|
<div class="tr difference-tr d{{differences.length}}">
|
||||||
|
<div class="td difference-td no-zzz-font">词条变化</div>
|
||||||
|
{{each differences[0] d}}
|
||||||
|
<div class="td difference-td no-zzz-font">
|
||||||
|
{{d.add.shortName}}
|
||||||
|
<span>+{{d.add.valueBase}}</span>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{each differences diff}}
|
||||||
|
<div class="tr difference-tr d{{differences.length}}">
|
||||||
|
<div class="td difference-td no-zzz-font">
|
||||||
|
{{diff[0].del.shortName}}
|
||||||
|
<span>-{{diff[0].del.valueBase}}</span>
|
||||||
|
</div>
|
||||||
|
{{each diff d}}
|
||||||
|
<div class="td difference-td no-zzz-font {{d.difference > 0 ? 'positive' : d.difference < 0 ? 'negative' : 'zero'}}">{{d.difference > 0 ? '+' + d.difference.toFixed(0) : d.difference.toFixed(0)}}</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
<div class="tr difference-tr info-tr no-zzz-font">
|
||||||
|
<div>反映在上述buff作用下置换<span>单位词条</span>后的<span>{{skill.name}}</span>期望伤害变化</div>
|
||||||
|
<div><span>横轴</span>表示<span>增加</span>的单位词条,<span>纵轴</span>表示<span>减少</span>的单位词条,对应坐标即为<span>期望伤害变化</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/block}}
|
||||||
547
resources/panel/damage.scss
Normal file
547
resources/panel/damage.scss
Normal file
|
|
@ -0,0 +1,547 @@
|
||||||
|
.damage {
|
||||||
|
padding-top: 0.8em;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.uid {
|
||||||
|
font-size: 0.6em;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
border-image-source: url('./images/CurseBG08.png');
|
||||||
|
border-image-slice: 30 60 30 60 fill;
|
||||||
|
border-image-width: 0.5em 1em 0.5em 1em;
|
||||||
|
border-image-outset: 0em 0em 0em 0em;
|
||||||
|
border-image-repeat: stretch stretch;
|
||||||
|
padding: 0.5em 1.2em;
|
||||||
|
font-size: 1em;
|
||||||
|
top: 0.5em;
|
||||||
|
left: 0.5em;
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
stroke: 0.05em rgba(0, 0, 0, 0.6);
|
||||||
|
-webkit-text-stroke: 0.05em rgba(0, 0, 0, 0.6);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.star {
|
||||||
|
width: 5.5em;
|
||||||
|
height: 1.5em;
|
||||||
|
|
||||||
|
@for $i from 0 through 5 {
|
||||||
|
&.star#{$i} {
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-image: url('./images/star/#{$i}.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.basic {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.char {
|
||||||
|
width: 55%;
|
||||||
|
position: relative;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
height: 100%;
|
||||||
|
padding-top: 1em;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: top center;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.skills {
|
||||||
|
position: absolute;
|
||||||
|
width: 120%;
|
||||||
|
height: 3.5em;
|
||||||
|
background: url('./images/skill_bg.png');
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
bottom: 3em;
|
||||||
|
right: -1.6em;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
padding-left: 2.5em;
|
||||||
|
padding-bottom: 0.2em;
|
||||||
|
|
||||||
|
.skill {
|
||||||
|
width: 1.4em;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
margin-right: 1.38em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
width: 45%;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 1.2em;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
.char_info {
|
||||||
|
width: 140%;
|
||||||
|
position: relative;
|
||||||
|
right: 20%;
|
||||||
|
padding: 0.3em 0.2em;
|
||||||
|
padding-right: 20%;
|
||||||
|
padding-left: 8%;
|
||||||
|
border-image-slice: 0 30 0 40 fill;
|
||||||
|
border-image-width: 0em 1.5em 0em 2em;
|
||||||
|
border-image-outset: 0 0 0 0;
|
||||||
|
border-image-repeat: stretch stretch;
|
||||||
|
border-image-source: url('./images/CurseBG04.png');
|
||||||
|
filter: drop-shadow(0 0 0.1em rgb(0, 0, 0));
|
||||||
|
|
||||||
|
.base {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.2em;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.rank {
|
||||||
|
width: 1.2em;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.property {
|
||||||
|
width: 1em;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.addition {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 0.7em;
|
||||||
|
gap: 0.2em;
|
||||||
|
padding-left: 1em;
|
||||||
|
|
||||||
|
.level {
|
||||||
|
background-color: #000;
|
||||||
|
padding: 0em 0.7em;
|
||||||
|
border-radius: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.role_ranks {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.1em;
|
||||||
|
|
||||||
|
span {
|
||||||
|
width: 1.2em;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
border-radius: 1em;
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@for $i from 1 through 6 {
|
||||||
|
span:nth-child(#{$i}) {
|
||||||
|
background-image: url('./images/ranks/#{$i}.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.r#{$i} {
|
||||||
|
@for $j from 1 through $i {
|
||||||
|
span:nth-child(#{$j}) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.property_info {
|
||||||
|
background-color: rgb(47, 47, 47);
|
||||||
|
border-left: 0.1em solid rgb(0, 0, 0);
|
||||||
|
padding-top: 0.2em;
|
||||||
|
background: url('./images/BgFrame01.png') center / 150% no-repeat;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 0.6em;
|
||||||
|
|
||||||
|
.special-title {
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.2em;
|
||||||
|
padding-bottom: 0.2em;
|
||||||
|
|
||||||
|
.properties {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4em;
|
||||||
|
padding: 0.05em 1em 0em 0.05em;
|
||||||
|
|
||||||
|
&:nth-child(odd) {
|
||||||
|
background-color: rgba(221, 224, 221, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.prop-icon {
|
||||||
|
width: 1em;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin: 0 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
font-size: 0.65em;
|
||||||
|
color: rgb(166, 166, 166);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&.yellow {
|
||||||
|
color: rgb(247, 199, 54);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.blue {
|
||||||
|
color: rgb(65, 147, 237);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.white {
|
||||||
|
color: rgb(233, 233, 233);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapon_info {
|
||||||
|
border-image-slice: 118 0 68 43 fill;
|
||||||
|
border-image-width: 4.5em 0em 2.7em 1.7em;
|
||||||
|
border-image-outset: 0em 0em 0em 0em;
|
||||||
|
border-image-repeat: stretch stretch;
|
||||||
|
border-image-source: url('./images/weapon_bg.png');
|
||||||
|
margin-top: -0.8em;
|
||||||
|
width: 115%;
|
||||||
|
margin-left: -15%;
|
||||||
|
font-size: 0.8em;
|
||||||
|
padding: 2em 1.2em;
|
||||||
|
padding-bottom: 3em;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.info {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
.base {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
|
||||||
|
.rarity-icon {
|
||||||
|
width: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
text-shadow: 0 0 0.2em rgb(0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: stretch;
|
||||||
|
width: max-content;
|
||||||
|
|
||||||
|
.addition {
|
||||||
|
font-size: 0.8em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4em;
|
||||||
|
|
||||||
|
.level {
|
||||||
|
$label-width: 0.2em;
|
||||||
|
-webkit-clip-path: polygon(
|
||||||
|
$label-width 0%,
|
||||||
|
calc(100% - $label-width) 0%,
|
||||||
|
100% $label-width,
|
||||||
|
100% calc(100% - $label-width),
|
||||||
|
calc(100% - $label-width) 100%,
|
||||||
|
$label-width 100%,
|
||||||
|
0% calc(100% - $label-width),
|
||||||
|
0% $label-width
|
||||||
|
);
|
||||||
|
clip-path: polygon(
|
||||||
|
$label-width 0%,
|
||||||
|
calc(100% - $label-width) 0%,
|
||||||
|
100% $label-width,
|
||||||
|
100% calc(100% - $label-width),
|
||||||
|
calc(100% - $label-width) 100%,
|
||||||
|
$label-width 100%,
|
||||||
|
0% calc(100% - $label-width),
|
||||||
|
0% $label-width
|
||||||
|
);
|
||||||
|
padding: 0 0.4em;
|
||||||
|
font-size: 0.9em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: rgb(43, 38, 40);
|
||||||
|
margin: 0.1em 0;
|
||||||
|
background-color: rgb(243, 203, 69);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.properties {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: rgb(65, 147, 237);
|
||||||
|
gap: 0.2em;
|
||||||
|
padding: 0 0.5em;
|
||||||
|
border-radius: 1em;
|
||||||
|
margin: 0.2em 0;
|
||||||
|
|
||||||
|
&.sub {
|
||||||
|
background-color: rgb(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.prop-icon {
|
||||||
|
width: 1em;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
font-size: 0.7em;
|
||||||
|
color: rgb(222, 222, 222);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 1.2em;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1;
|
||||||
|
height: 70%;
|
||||||
|
margin-right: -1em;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.damage-data {
|
||||||
|
border-image-source: url('./images/BgFrame01.png');
|
||||||
|
border-image-slice: 200 100 70 280 fill;
|
||||||
|
border-image-width: 2em 1em 0.7em 2.8em;
|
||||||
|
border-image-outset: 2em 1em 0.7em 2.8em;
|
||||||
|
border-image-repeat: stretch stretch;
|
||||||
|
padding-bottom: 3.3em;
|
||||||
|
margin-top: -1.4em;
|
||||||
|
position: relative;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title:nth-child(n+2) {
|
||||||
|
padding-top: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-list {
|
||||||
|
margin: 0 1.2em;
|
||||||
|
text-align: center;
|
||||||
|
backdrop-filter: blur(0.2em);
|
||||||
|
border-radius: 0.5em;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 0 3em rgba(0, 0, 0, 0.6);
|
||||||
|
border: 0.1em solid rgba(255, 255, 255, 0.3);
|
||||||
|
|
||||||
|
.tr {
|
||||||
|
display: grid;
|
||||||
|
border-bottom: 0.1em solid rgba(255, 255, 255, 0.3);
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
font-size: 1.1em;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
text-shadow: 0 0 0.2em rgba(0, 0, 0, 0.6);
|
||||||
|
color: rgb(206, 190, 149);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
background-color: rgba(255, 255, 255, 0.12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.td {
|
||||||
|
padding: 0.5em 0.5em;
|
||||||
|
font-size: 0.9em;
|
||||||
|
border-right: 0.1em solid rgba(255, 255, 255, 0.3);
|
||||||
|
&:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-tr {
|
||||||
|
font-size: 0.8em !important;
|
||||||
|
display: grid !important;
|
||||||
|
grid-template-columns: 1fr !important;
|
||||||
|
padding: 0.3em !important;
|
||||||
|
color: #bbb !important;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 伤害统计 */
|
||||||
|
.damage-list {
|
||||||
|
.dmg-tr {
|
||||||
|
grid-template-columns: 0.25fr 1.6fr 1fr 1fr;
|
||||||
|
|
||||||
|
&.current {
|
||||||
|
background: rgb(120, 104, 73);
|
||||||
|
|
||||||
|
.dmg-td:nth-child(2) {
|
||||||
|
color: rgb(251, 198, 65) !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmg-td {
|
||||||
|
&:nth-child(2) {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: rgb(206, 190, 149);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 乘区数据 */
|
||||||
|
.area-list {
|
||||||
|
.area-tr {
|
||||||
|
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
|
||||||
|
|
||||||
|
&:nth-child(odd) {
|
||||||
|
font-size: 1.1em;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
text-shadow: 0 0 0.2em rgba(0, 0, 0, 0.6);
|
||||||
|
color: rgb(206, 190, 149);
|
||||||
|
}
|
||||||
|
&.anomaly {
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.area-td {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buff统计 */
|
||||||
|
.buff-list {
|
||||||
|
.buff-tr {
|
||||||
|
grid-template-columns: 0.7fr 5fr 3fr 2fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buff-td {
|
||||||
|
&:nth-child(2) {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: rgb(206, 190, 149);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 差异计算 */
|
||||||
|
.difference-list {
|
||||||
|
.difference-tr {
|
||||||
|
@for $i from 2 through 9 {
|
||||||
|
&.d#{$i} {
|
||||||
|
grid-template-columns: repeat($i + 1, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.difference-td {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.zero {
|
||||||
|
background-color: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: rgb(206, 190, 149);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.positive {
|
||||||
|
background-color: rgb(82, 38, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.negative {
|
||||||
|
background-color: rgb(22, 65, 33);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
margin-top: -3.3em;
|
||||||
|
position: relative;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue