From a1a3b2b17164eadeb3bb40d391c644ae436fe1c3 Mon Sep 17 00:00:00 2001 From: UCPr <2032385471@qq.com> Date: Fri, 15 Aug 2025 23:51:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=B4=AF=E7=A9=BF=E4=BC=A4?= =?UTF-8?q?=E5=AE=B3=E8=AE=A1=E7=AE=97=E7=AD=89=EF=BC=9B=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=BB=AA=E7=8E=84=E4=BC=A4=E5=AE=B3=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 +- model/avatar.js | 3 +- model/damage/BuffManager.js | 26 +-- model/damage/BuffManager.ts | 12 +- model/damage/Calculator.js | 154 ++++++++++------- model/damage/Calculator.ts | 220 ++++++++++++++++--------- model/damage/README.md | 63 +++++-- model/damage/avatar.js | 2 +- model/damage/avatar.ts | 2 +- model/damage/character/仪玄/calc.js | 103 ++++++++++++ model/damage/character/仪玄/data.json | 43 +++++ model/damage/character/爱丽丝/calc.js | 2 +- model/damage/character/爱丽丝/score.js | 1 + model/damage/character/简/calc.js | 3 +- model/damage/character/薇薇安/calc.js | 2 +- model/damage/set/云岿如我.js | 13 ++ model/damage/weapon/青溟笼舍.js | 18 ++ resources/map/AnomalyData.json | 13 ++ resources/panel/damage.css | 2 +- resources/panel/damage.html | 12 +- resources/panel/damage.scss | 2 +- 21 files changed, 524 insertions(+), 184 deletions(-) create mode 100644 model/damage/character/仪玄/calc.js create mode 100644 model/damage/character/仪玄/data.json create mode 100644 model/damage/set/云岿如我.js create mode 100644 model/damage/weapon/青溟笼舍.js diff --git a/README.md b/README.md index 46d0e64..f24766f 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,6 @@ > 插件依靠社区维护,发起者随缘更新,但是ZZZure组织成员会对PR进行合并,你可以在PR页面@协助者进行合并。 > > 在你使用之前请**务必**完整阅读 `README` 内容,如因无视 `README` 遇到的问题,在提问时难免遭受嘲笑。 -> -> **自定义词条权重**和**自定义伤害计算**请查看[此教程](./model/damage/README.md) # 安装 @@ -45,6 +43,10 @@ git clone --depth=1 https://gitee.com/bietiaop/ZZZ-Plugin.git ./plugins/ZZZ-Plug
+## 自定义评分权重、伤害计算 + +**自定义评分权重**和**自定义伤害计算**请查看[此教程](./model/damage/README.md) + ## 攻略、图鉴 **攻略、图鉴建议使用第三方插件**,本插件的攻略功能是在没有专业插件的情况下的保底功能。 @@ -86,7 +88,11 @@ git clone --depth=1 https://gitee.com/bietiaop/ZZZ-Plugin.git ./plugins/ZZZ-Plug 绑定设备**无法100%解决**账号异常问题。 -若更新面板遇见账号异常问题,可尝试 **%更新展柜面板**,这将调用[Enka](https://enka.network/?zzz)接口更新游戏内展示的角色的数据。如若通过此方法更新的角色数据与实际不一致,请[提出issue](https://github.com/ZZZure/ZZZ-Plugin/issues/new) +## 更新展柜面板 + +若通过默认的米游社更新面板遇见账号异常问题,可尝试 **%更新展柜面板**,这将调用[Enka](https://enka.network/?zzz)接口更新游戏内展示的角色的数据。如若通过此方法更新的角色数据与实际不一致,请[提出issue](https://github.com/ZZZure/ZZZ-Plugin/issues/new) + +该服务可能偶尔无法使用,如更新展柜面板一直请求失败,可通过锅巴修改`自定义enkaApi地址`项来自定义请求链接,请求和返回与Enka格式一致皆可 ## 角色图缺失 diff --git a/model/avatar.js b/model/avatar.js index 8136cfd..fe76e89 100644 --- a/model/avatar.js +++ b/model/avatar.js @@ -313,7 +313,7 @@ export class ZZZAvatarInfo { */ const get = (name) => { const data = basic_properties[name] - return Number(data.base || data.final) + return Number(data?.base || data?.final || 0) } return this._base_properties = { HP: get('hpmax'), @@ -334,6 +334,7 @@ export class ZZZAvatarInfo { * @param {keyof ZZZAvatarInfo['basic_properties']} name */ const get = (name) => { + if (!basic_properties[name]) return 0 const data = basic_properties[name].final return Number(data.includes('%') ? data.replace('%', '') / 100 : data) } diff --git a/model/damage/BuffManager.js b/model/damage/BuffManager.js index faec682..85cc988 100644 --- a/model/damage/BuffManager.js +++ b/model/damage/BuffManager.js @@ -28,17 +28,20 @@ export var buffTypeEnum; buffTypeEnum[buffTypeEnum["\u65E0\u89C6\u9632\u5FA1"] = 5] = "\u65E0\u89C6\u9632\u5FA1"; buffTypeEnum[buffTypeEnum["\u7A7F\u900F\u503C"] = 6] = "\u7A7F\u900F\u503C"; buffTypeEnum[buffTypeEnum["\u7A7F\u900F\u7387"] = 7] = "\u7A7F\u900F\u7387"; - buffTypeEnum[buffTypeEnum["\u66B4\u51FB\u7387"] = 8] = "\u66B4\u51FB\u7387"; - buffTypeEnum[buffTypeEnum["\u66B4\u51FB\u4F24\u5BB3"] = 9] = "\u66B4\u51FB\u4F24\u5BB3"; - buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u7CBE\u901A"] = 10] = "\u5F02\u5E38\u7CBE\u901A"; - buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u589E\u4F24"] = 11] = "\u5F02\u5E38\u589E\u4F24"; - buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u66B4\u51FB\u7387"] = 12] = "\u5F02\u5E38\u66B4\u51FB\u7387"; - buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u66B4\u51FB\u4F24\u5BB3"] = 13] = "\u5F02\u5E38\u66B4\u51FB\u4F24\u5BB3"; - buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u6301\u7EED\u65F6\u95F4"] = 14] = "\u5F02\u5E38\u6301\u7EED\u65F6\u95F4"; - buffTypeEnum[buffTypeEnum["\u751F\u547D\u503C"] = 15] = "\u751F\u547D\u503C"; - buffTypeEnum[buffTypeEnum["\u9632\u5FA1\u529B"] = 16] = "\u9632\u5FA1\u529B"; - buffTypeEnum[buffTypeEnum["\u51B2\u51FB\u529B"] = 17] = "\u51B2\u51FB\u529B"; - buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u638C\u63A7"] = 18] = "\u5F02\u5E38\u638C\u63A7"; + buffTypeEnum[buffTypeEnum["\u5931\u8861\u6613\u4F24"] = 8] = "\u5931\u8861\u6613\u4F24"; + buffTypeEnum[buffTypeEnum["\u66B4\u51FB\u7387"] = 9] = "\u66B4\u51FB\u7387"; + buffTypeEnum[buffTypeEnum["\u66B4\u51FB\u4F24\u5BB3"] = 10] = "\u66B4\u51FB\u4F24\u5BB3"; + buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u7CBE\u901A"] = 11] = "\u5F02\u5E38\u7CBE\u901A"; + buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u589E\u4F24"] = 12] = "\u5F02\u5E38\u589E\u4F24"; + buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u66B4\u51FB\u7387"] = 13] = "\u5F02\u5E38\u66B4\u51FB\u7387"; + buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u66B4\u51FB\u4F24\u5BB3"] = 14] = "\u5F02\u5E38\u66B4\u51FB\u4F24\u5BB3"; + buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u6301\u7EED\u65F6\u95F4"] = 15] = "\u5F02\u5E38\u6301\u7EED\u65F6\u95F4"; + buffTypeEnum[buffTypeEnum["\u8D2F\u7A7F\u529B"] = 16] = "\u8D2F\u7A7F\u529B"; + buffTypeEnum[buffTypeEnum["\u8D2F\u7A7F\u589E\u4F24"] = 17] = "\u8D2F\u7A7F\u589E\u4F24"; + buffTypeEnum[buffTypeEnum["\u751F\u547D\u503C"] = 18] = "\u751F\u547D\u503C"; + buffTypeEnum[buffTypeEnum["\u9632\u5FA1\u529B"] = 19] = "\u9632\u5FA1\u529B"; + buffTypeEnum[buffTypeEnum["\u51B2\u51FB\u529B"] = 20] = "\u51B2\u51FB\u529B"; + buffTypeEnum[buffTypeEnum["\u5F02\u5E38\u638C\u63A7"] = 21] = "\u5F02\u5E38\u638C\u63A7"; })(buffTypeEnum || (buffTypeEnum = {})); let depth = 0, weakMapCheck = new WeakMap(); export class BuffManager { @@ -59,7 +62,6 @@ export class BuffManager { const oriBuff = buff; buff = _.merge({ status: true, - is: {}, ...this.defaultBuff }, buff); if (buff.range && !Array.isArray(buff.range)) diff --git a/model/damage/BuffManager.ts b/model/damage/BuffManager.ts index 2b0c5f6..d75d9c8 100644 --- a/model/damage/BuffManager.ts +++ b/model/damage/BuffManager.ts @@ -25,11 +25,13 @@ export type buffSource = '音擎' | '套装' | '技能' | '影画' | '核心被 export enum buffTypeEnum { // 通用乘区 - 攻击力, 倍率, 增伤, 易伤, 无视抗性, 无视防御, 穿透值, 穿透率, + 攻击力, 倍率, 增伤, 易伤, 无视抗性, 无视防御, 穿透值, 穿透率, 失衡易伤, // 直伤乘区 暴击率, 暴击伤害, // 异常乘区 异常精通, 异常增伤, 异常暴击率, 异常暴击伤害, 异常持续时间, + // 贯穿乘区 + 贯穿力, 贯穿增伤, // 其他属性,一般不直接影响伤害,但可能用于buff是否生效判断/转模 生命值, 防御力, 冲击力, 异常掌控 } @@ -52,7 +54,7 @@ export interface buff { * - 一般情况下此值即为提高值 * - 当buff增益类型为**攻击力/冲击力/异常精通/异常掌控/防御力/生命值**时,若此值 **<1**,则将此值理解为**初始属性**的**百分比提高** * @string - * 角色自身的buff提高值可能随技能/天赋等级提高而提高,此时可以于data.json的"buff"中添加对应的倍率信息(同上支持百分比提高),此时value即为键名,其首字母必须为对应技能的基类(参考技能类型命名标准) + * 角色自身的buff提高值可能随技能/天赋等级提高而提高,此时可以于data.json的"buff"中添加倍率数组(同上支持百分比提高),此时value即为键名,其首字母必须为对应技能的基类(参考技能类型命名标准) * @array * 根据buff.source自动选择对应等级/星级的值(同上支持百分比提高),支持的source: * - 音擎:音擎进阶星级 @@ -74,7 +76,7 @@ export interface buff { range?: string[] | anomaly[] | "追加攻击"[] /** * Buff增益技能类型**生效技能** - * - 不同于**range**,仅全匹配时该值生效,不会向后覆盖生效 + * - 不同于**range**,仅全匹配type时该值生效,不会向后覆盖生效 * - 无**range**且无**include**则该buff对**exclude**以外的全部技能生效 * - **range**与**include**符合其一则认为buff生效 * - 当技能参数存在**redirect**时,**range**与**include**的区别在于**include**不会尝试匹配**redirect** @@ -82,7 +84,7 @@ export interface buff { include?: string[] /** * Buff增益技能类型**排除技能** - * - 与**include**相同,仅全匹配时该值生效,不会向后覆盖生效 + * - 与**include**相同,仅全匹配type时该值生效,不会向后覆盖生效 * - 优先级高于**range**与**include** */ exclude?: string[] @@ -142,7 +144,7 @@ export class BuffManager { const oriBuff = buff buff = _.merge({ status: true, - is: {}, + // is: {}, ...this.defaultBuff }, buff) if (buff.range && !Array.isArray(buff.range)) diff --git a/model/damage/Calculator.js b/model/damage/Calculator.js index be58d3d..4f70337 100644 --- a/model/damage/Calculator.js +++ b/model/damage/Calculator.js @@ -50,7 +50,7 @@ export class Calculator { this.enemy = { level: this.avatar.level, basicDEF: 50, - resistance: 0.2 + resistance: -0.2 }; } get initial_properties() { @@ -81,12 +81,17 @@ export class Calculator { const num = skill.check; skill.check = oriSkill.check = ({ avatar }) => avatar.rank >= num; } + skill.isAnomalyDMG ??= oriSkill.isAnomalyDMG = typeof anomalyEnum[skill.type.slice(0, 2)] === 'number'; + skill.isSheerDMG ??= oriSkill.isSheerDMG = this.avatar.avatar_profession === 6 && elementType2element(this.avatar.element_type) === skill.element && !skill.isAnomalyDMG; this.skills.push(skill); return this.skills; } + find_skill(key, value) { + return this.skills.find(skill => skill[key] === value); + } calc_skill(skill) { if (typeof skill === 'string') { - const MySkill = this.skills.find(s => s.type === skill); + const MySkill = this.find_skill('type', skill); if (!MySkill) return; return this.calc_skill(MySkill); @@ -115,7 +120,7 @@ export class Calculator { if (skill.before) skill.before({ avatar: this.avatar, calc: this, usefulBuffs, skill, props, areas }); logger.debug(`有效buff*${usefulBuffs.length}/${this.buffM.buffs.length}`); - const isAnomaly = typeof anomalyEnum[skill.type.slice(0, 2)] === 'number'; + const { isAnomalyDMG = false, isSheerDMG = false } = skill; if (!areas.BasicArea) { let Multiplier = props.倍率; if (!Multiplier) { @@ -138,7 +143,7 @@ export class Calculator { logger.warn('无效的技能倍率:', skill); } } - else if (isAnomaly) { + else if (isAnomalyDMG) { Multiplier = (skill.type.startsWith('紊乱') ? this.get_DiscoverMultiplier(skill) : this.get_AnomalyMultiplier(skill, usefulBuffs, skill.name.includes('每') ? 1 : 0)) || 0; @@ -154,40 +159,51 @@ export class Calculator { logger.debug(`最终倍率:${Multiplier}`); } props.倍率 = Multiplier; - this.get_ATK(skill, usefulBuffs); - areas.BasicArea = props.攻击力 * props.倍率; - } - logger.debug(`基础伤害区:${areas.BasicArea}`); - if (isAnomaly) { - areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs); - areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs); - areas.LevelArea ??= this.get_LevelArea(); - if (!skill.type.startsWith('紊乱')) { - props.异常暴击率 ??= this.get_AnomalyCRITRate(skill, usefulBuffs); - props.异常暴击伤害 ??= this.get_AnomalyCRITDMG(skill, usefulBuffs); - areas.CriticalArea ??= 1 + props.异常暴击率 * (props.异常暴击伤害 - 1); + if (isSheerDMG) { + areas.BasicArea = this.get_SheerForce(skill, usefulBuffs) * Multiplier; + } + else { + areas.BasicArea = this.get_ATK(skill, usefulBuffs) * Multiplier; } } - else { - props.暴击率 ??= this.get_CRITRate(skill, usefulBuffs); - props.暴击伤害 ??= this.get_CRITDMG(skill, usefulBuffs); - areas.CriticalArea ??= 1 + props.暴击率 * (props.暴击伤害 - 1); + logger.debug(`基础伤害区:${areas.BasicArea}`); + let CRITRate = 0, CRITDMG = 0; + if (!areas.CriticalArea) { + if (isAnomalyDMG) { + if (!skill.type.startsWith('紊乱')) { + CRITRate = this.get_AnomalyCRITRate(skill, usefulBuffs); + CRITDMG = this.get_AnomalyCRITDMG(skill, usefulBuffs); + } + } + else { + CRITRate = this.get_CRITRate(skill, usefulBuffs); + CRITDMG = this.get_CRITDMG(skill, usefulBuffs); + } + areas.CriticalArea = 1 + CRITRate * CRITDMG; } - areas.CriticalArea ??= 1; - logger.debug(`暴击期望:${areas.CriticalArea}`); + areas.CriticalArea !== 1 && logger.debug(`暴击期望:${areas.CriticalArea}`); areas.BoostArea ??= this.get_BoostArea(skill, usefulBuffs); areas.VulnerabilityArea ??= this.get_VulnerabilityArea(skill, usefulBuffs); areas.ResistanceArea ??= this.get_ResistanceArea(skill, usefulBuffs); - areas.DefenceArea ??= this.get_DefenceArea(skill, usefulBuffs); - const { BasicArea, CriticalArea, BoostArea, VulnerabilityArea, ResistanceArea, DefenceArea, AnomalyProficiencyArea, LevelArea, AnomalyBoostArea } = areas; - const { 暴击伤害, 异常暴击伤害 } = props; - const result = isAnomaly ? + areas.DefenceArea ??= isSheerDMG ? 1 : this.get_DefenceArea(skill, usefulBuffs); + areas.StunVulnerabilityArea ??= this.get_StunVulnerabilityArea(skill, usefulBuffs); + if (isAnomalyDMG) { + areas.AnomalyProficiencyArea ??= this.get_AnomalyProficiencyArea(skill, usefulBuffs); + areas.AnomalyBoostArea ??= this.get_AnomalyBoostArea(skill, usefulBuffs); + areas.LevelArea ??= this.get_LevelArea(); + } + if (isSheerDMG) { + areas.SheerBoostArea ??= this.get_SheerBoostArea(skill, usefulBuffs); + } + const { BasicArea, CriticalArea, BoostArea, VulnerabilityArea, ResistanceArea, DefenceArea, AnomalyProficiencyArea, LevelArea, AnomalyBoostArea, StunVulnerabilityArea, SheerBoostArea = 1 } = areas; + const commonArea = BasicArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea * StunVulnerabilityArea; + const result = isAnomalyDMG ? { - critDMG: (CriticalArea !== 1) ? BasicArea * 异常暴击伤害 * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea : 0, - expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea + critDMG: (CriticalArea !== 1) ? commonArea * (CRITDMG + 1) * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea : 0, + expectDMG: commonArea * CriticalArea * AnomalyProficiencyArea * LevelArea * AnomalyBoostArea } : { - critDMG: BasicArea * 暴击伤害 * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea, - expectDMG: BasicArea * CriticalArea * BoostArea * VulnerabilityArea * ResistanceArea * DefenceArea + critDMG: commonArea * (CRITDMG + 1) * SheerBoostArea, + expectDMG: commonArea * CriticalArea * SheerBoostArea }; const damage = { skill, usefulBuffs: _.sortBy(Array.from(this.usefulBuffResults.values()), ['type', 'value']).reverse(), props, areas, result }; this.usefulBuffResults.clear(); @@ -319,11 +335,11 @@ export class Calculator { } calc_differences(buffs, skill) { if (!skill) { - skill = this.skills.find((skill) => skill.isMain) + skill = this.find_skill('isMain', true) || this.calc().sort((a, b) => b.result.expectDMG - a.result.expectDMG)[0]?.skill; } else if (typeof skill === 'string') { - const MySkill = this.skills.find(s => s.type === skill); + const MySkill = this.find_skill('type', skill); if (!MySkill) return []; return this.calc_differences(buffs, MySkill); @@ -479,7 +495,7 @@ export class Calculator { } get_ATK(skill, usefulBuffs) { let ATK = this.get('攻击力', this.initial_properties.ATK, skill, usefulBuffs, true); - ATK = Math.max(0, Math.min(ATK, 10000)); + ATK = min_max(0, 10000, ATK); logger.debug(`攻击力:${ATK}`); return ATK; } @@ -490,29 +506,37 @@ export class Calculator { } get_CRITRate(skill, usefulBuffs) { let CRITRate = this.get('暴击率', this.initial_properties.CRITRate, skill, usefulBuffs); - CRITRate = Math.max(0, Math.min(CRITRate, 1)); + CRITRate = min_max(0, 1, CRITRate); logger.debug(`暴击率:${CRITRate}`); return CRITRate; } get_CRITDMG(skill, usefulBuffs) { - let CRITDMG = this.get('暴击伤害', this.initial_properties.CRITDMG + 1, skill, usefulBuffs); - CRITDMG = Math.max(0, Math.min(CRITDMG, 5)); + let CRITDMG = this.get('暴击伤害', this.initial_properties.CRITDMG, skill, usefulBuffs); + CRITDMG = min_max(0, 5, CRITDMG); logger.debug(`暴击伤害:${CRITDMG}`); return CRITDMG; } get_BoostArea(skill, usefulBuffs) { - const BoostArea = this.get('增伤', 1, skill, usefulBuffs); + let BoostArea = this.get('增伤', 1, skill, usefulBuffs); + BoostArea = min_max(0, 6, BoostArea); logger.debug(`增伤区:${BoostArea}`); return BoostArea; } get_VulnerabilityArea(skill, usefulBuffs) { - const VulnerabilityArea = this.get('易伤', 1, skill, usefulBuffs); + let VulnerabilityArea = this.get('易伤', 1, skill, usefulBuffs); + VulnerabilityArea = min_max(0.2, 2, VulnerabilityArea); logger.debug(`易伤区:${VulnerabilityArea}`); return VulnerabilityArea; } + get_StunVulnerabilityArea(skill, usefulBuffs) { + let StunVulnerabilityArea = this.get('失衡易伤', 1, skill, usefulBuffs); + StunVulnerabilityArea = min_max(0.2, 5, StunVulnerabilityArea); + StunVulnerabilityArea !== 1 && logger.debug(`失衡易伤区:${StunVulnerabilityArea}`); + return StunVulnerabilityArea; + } get_ResistanceArea(skill, usefulBuffs) { - let ResistanceArea = this.get('无视抗性', 1 + this.enemy.resistance, skill, usefulBuffs); - ResistanceArea = Math.min(2, ResistanceArea); + let ResistanceArea = this.get('无视抗性', 1 - this.enemy.resistance, skill, usefulBuffs); + ResistanceArea = min_max(0, 2, ResistanceArea); logger.debug(`抗性区:${ResistanceArea}`); return ResistanceArea; } @@ -542,7 +566,7 @@ export class Calculator { const PenRatio = this.get_PenRatio(skill, usefulBuffs); const defence = DEF * (1 - IgnoreDEF); const effective_defence = Math.max(0, defence * (1 - PenRatio) - Pen); - const DefenceArea = base / (effective_defence + base); + const DefenceArea = min_max(0, 1, base / (effective_defence + base)); logger.debug(`防御区:${DefenceArea}`); return DefenceArea; } @@ -552,31 +576,37 @@ export class Calculator { return LevelArea; } get_AnomalyProficiency(skill, usefulBuffs) { - let AnomalyProficiency = this.get('异常精通', this.initial_properties.AnomalyProficiency, skill, usefulBuffs); - AnomalyProficiency = Math.max(0, Math.min(AnomalyProficiency, 1000)); + const AnomalyProficiency = this.get('异常精通', this.initial_properties.AnomalyProficiency, skill, usefulBuffs); logger.debug(`异常精通:${AnomalyProficiency}`); return AnomalyProficiency; } + get_AnomalyMastery(skill, usefulBuffs) { + let AnomalyMastery = this.get('异常掌控', this.initial_properties.AnomalyMastery, skill, usefulBuffs, true); + AnomalyMastery = min_max(0, 1000, AnomalyMastery); + logger.debug(`异常掌控:${AnomalyMastery}`); + return AnomalyMastery; + } get_AnomalyProficiencyArea(skill, usefulBuffs) { const AnomalyProficiency = this.get_AnomalyProficiency(skill, usefulBuffs); - const AnomalyProficiencyArea = AnomalyProficiency / 100; + const AnomalyProficiencyArea = min_max(0, 10, AnomalyProficiency / 100); logger.debug(`异常精通区:${AnomalyProficiencyArea}`); return AnomalyProficiencyArea; } get_AnomalyBoostArea(skill, usefulBuffs) { - const AnomalyBoostArea = this.get('异常增伤', 1, skill, usefulBuffs); - AnomalyBoostArea && logger.debug(`异常增伤区:${AnomalyBoostArea}`); + let AnomalyBoostArea = this.get('异常增伤', 1, skill, usefulBuffs); + AnomalyBoostArea = min_max(0, 3, AnomalyBoostArea); + AnomalyBoostArea !== 1 && logger.debug(`异常增伤区:${AnomalyBoostArea}`); return AnomalyBoostArea; } get_AnomalyCRITRate(skill, usefulBuffs) { let AnomalyCRITRate = this.get('异常暴击率', 0, skill, usefulBuffs); - AnomalyCRITRate = Math.max(0, Math.min(AnomalyCRITRate, 1)); + AnomalyCRITRate = min_max(0, 1, AnomalyCRITRate); AnomalyCRITRate && logger.debug(`异常暴击率:${AnomalyCRITRate}`); return AnomalyCRITRate; } get_AnomalyCRITDMG(skill, usefulBuffs) { - let AnomalyCRITDMG = this.get('异常暴击伤害', 1, skill, usefulBuffs); - AnomalyCRITDMG = Math.max(0, Math.min(AnomalyCRITDMG, 5)); + let AnomalyCRITDMG = this.get('异常暴击伤害', 0, skill, usefulBuffs); + AnomalyCRITDMG = min_max(0, 5, AnomalyCRITDMG); AnomalyCRITDMG && logger.debug(`异常暴击伤害:${AnomalyCRITDMG}`); return AnomalyCRITDMG; } @@ -587,26 +617,36 @@ export class Calculator { } get_HP(skill, usefulBuffs) { let HP = this.get('生命值', this.initial_properties.HP, skill, usefulBuffs, true); - HP = Math.max(0, Math.min(HP, 100000)); + HP = min_max(0, 100000, HP); logger.debug(`生命值:${HP}`); return HP; } get_DEF(skill, usefulBuffs) { let DEF = this.get('防御力', this.initial_properties.DEF, skill, usefulBuffs, true); - DEF = Math.max(0, Math.min(DEF, 1000)); + DEF = min_max(0, 1000, DEF); logger.debug(`防御力:${DEF}`); return DEF; } get_Impact(skill, usefulBuffs) { let Impact = this.get('冲击力', this.initial_properties.Impact, skill, usefulBuffs, true); - Impact = Math.max(0, Math.min(Impact, 1000)); + Impact = min_max(0, 1000, Impact); logger.debug(`冲击力:${Impact}`); return Impact; } - get_AnomalyMastery(skill, usefulBuffs) { - let AnomalyMastery = this.get('异常掌控', this.initial_properties.AnomalyMastery, skill, usefulBuffs, true); - AnomalyMastery = Math.max(0, Math.min(AnomalyMastery, 1000)); - logger.debug(`异常掌控:${AnomalyMastery}`); - return AnomalyMastery; + get_SheerForce(skill, usefulBuffs) { + let SheerForce = Math.trunc(this.get_ATK(skill, usefulBuffs) * 0.3); + SheerForce = this.get('贯穿力', SheerForce, skill, usefulBuffs, true); + SheerForce = min_max(0, 10000, SheerForce); + logger.debug(`贯穿力:${SheerForce}`); + return SheerForce; + } + get_SheerBoostArea(skill, usefulBuffs) { + let SheerBoostArea = this.get('贯穿增伤', 1, skill, usefulBuffs); + SheerBoostArea = min_max(0.2, 9, SheerBoostArea); + SheerBoostArea !== 1 && logger.debug(`贯穿增伤区:${SheerBoostArea}`); + return SheerBoostArea; } } +function min_max(min, max, value) { + return Math.min(Math.max(value, min), max); +} diff --git a/model/damage/Calculator.ts b/model/damage/Calculator.ts index f348d0d..b76dd00 100644 --- a/model/damage/Calculator.ts +++ b/model/damage/Calculator.ts @@ -48,6 +48,10 @@ export interface skill { isMain?: boolean /** 角色面板伤害统计中是否隐藏显示 */ isHide?: boolean + /** 是否为异常伤害。自动判断 */ + isAnomalyDMG?: boolean + /** 是否为贯穿伤害。自动判断 */ + isSheerDMG?: boolean /** 禁用伤害计算cache */ banCache?: boolean /** 是否计算该技能 */ @@ -105,12 +109,16 @@ export interface damage { ResistanceArea: number /** 防御区 */ DefenceArea: number + /** 失衡易伤区 */ + StunVulnerabilityArea: number /** 异常精通区 */ AnomalyProficiencyArea: number /** 异常增伤区 */ AnomalyBoostArea: number /** 等级区 */ LevelArea: number + /** 贯穿增伤区 */ + SheerBoostArea: number } /** 伤害结果 */ result: { @@ -204,7 +212,7 @@ export class Calculator { this.enemy = { level: this.avatar.level, basicDEF: 50, - resistance: 0.2 + resistance: -0.2 } } @@ -242,10 +250,17 @@ export class Calculator { const num = skill.check as unknown as number skill.check = oriSkill.check = ({ avatar }) => avatar.rank >= num } + skill.isAnomalyDMG ??= oriSkill.isAnomalyDMG = typeof anomalyEnum[skill.type.slice(0, 2) as anomaly] === 'number' + skill.isSheerDMG ??= oriSkill.isSheerDMG = this.avatar.avatar_profession === 6 && elementType2element(this.avatar.element_type) === skill.element && !skill.isAnomalyDMG this.skills.push(skill) return this.skills } + /** 查找指定已注册技能 */ + find_skill