新增妮露组队“海妮心二妲·丰穰之核”伤害 (#600)

* 添加顶层`MiaoError`处理,可实现任意代码处回复错误信息。

* 解除xx伤害n,n最多只能到7个的限制;修复xx伤害n,显示的buff列表不正确。

* 新增妮露组队“海妮心二妲·丰穰之核”伤害

* 更新buff名称使其更符合规范

* 妮露组队伤害补充双水共鸣效果
This commit is contained in:
zolay 2023-06-12 03:20:56 +08:00 committed by GitHub
parent 12bc9cf5f7
commit 6e3cfc8be3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 136 additions and 29 deletions

View File

@ -24,7 +24,7 @@ app.reg({
profileDetail: {
name: '角色面板',
fn: ProfileDetail.detail,
rule: /^#*([^#]+)\s*(详细|详情|面板|面版|圣遗物|武器[1-7]?|伤害[1-7]?)\s*(\d{9})*(.*[换变改].*)?$/
rule: /^#*([^#]+)\s*(详细|详情|面板|面版|圣遗物|武器[1-7]?|伤害([1-9]+\d*)?)\s*(\d{9})*(.*[换变改].*)?$/
},
profileChange: {

View File

@ -48,8 +48,8 @@ let ProfileDetail = {
let name = msg.replace(/#|老婆|老公|星铁|原神/g, '').trim()
msg = msg.replace('面版', '面板')
let dmgRet = /(?:伤害|武器)(\d?)$/.exec(name)
let dmgIdx = 0
let dmgRet = /(?:伤害|武器)(\d*)$/.exec(name)
let dmgIdx = 0, idxIsInput = false
if (/(最强|最高|最高分|最牛|第一)/.test(msg)) {
mode = /(分|圣遗物|评分|ACE)/.test(msg) ? 'rank-mark' : 'rank-dmg'
name = name.replace(/(最强|最高分|第一|最高|最牛|圣遗物|评分|群)/g, '')
@ -60,9 +60,11 @@ let ProfileDetail = {
} else if (dmgRet) {
// mode = /武器/.test(msg) ? 'weapon' : 'dmg'
mode = 'dmg'
name = name.replace(/(伤害|武器)+[0-7]?/, '').trim()
name = name.replace(/(伤害|武器)+\d*/, '').trim()
if (dmgRet[1]) {
dmgIdx = dmgRet[1] * 1
// 标识是用户指定的序号
idxIsInput = true
}
} else if (/(详情|详细|面板)更新$/.test(msg) || (/更新/.test(msg) && /(详情|详细|面板)$/.test(msg))) {
mode = 'refresh'
@ -104,7 +106,7 @@ let ProfileDetail = {
}
if (mode === 'profile' || mode === 'dmg' || mode === 'weapon') {
return ProfileDetail.render(e, char, mode, { dmgIdx })
return ProfileDetail.render(e, char, mode, { dmgIdx, idxIsInput })
} else if (mode === 'refresh') {
await ProfileList.refresh(e)
return true

View File

@ -1,6 +1,6 @@
import lodash from 'lodash'
import Plugin from './common/Plugin.js'
import { Version } from '#miao'
import { Version, MiaoError } from '#miao'
class App {
constructor (cfg) {
@ -91,7 +91,17 @@ class App {
e.msg = '#poke#'
}
e.original_msg = e.original_msg || e.msg
try {
return await app.fn.call(this, e)
} catch (err) {
if (err?.message && (err instanceof MiaoError)) {
// 处理 MiaoError
return e.reply(err.message)
} else {
// 其他错误抛出
throw err
}
}
}
if (app.yzRule && app.yzCheck) {

17
components/MiaoError.js Normal file
View File

@ -0,0 +1,17 @@
export default class MiaoError extends Error {
constructor(message) {
// 允许返回特殊消息,需传递数组,例如 [segment.image()]
if (Array.isArray(message)) {
super()
this._message = message
} else {
super(message);
}
}
get message() {
return this._message ? this._message : super.message;
}
}

View File

@ -4,5 +4,6 @@ import Common from './Common.js'
import Cfg from './Cfg.js'
import Version from './Version.js'
import App from './App.js'
import MiaoError from './MiaoError.js'
export { Data, Cfg, Format, Common, Version, App }
export { Data, Cfg, Format, Common, Version, App, MiaoError }

View File

@ -94,13 +94,13 @@ export default class ProfileData extends AvatarData {
}
// 计算当前profileData的伤害信息
async calcDmg ({ enemyLv = 91, mode = 'profile', dmgIdx = 0 }) {
async calcDmg ({ enemyLv = 91, mode = 'profile', dmgIdx = 0, idxIsInput = false }) {
if (!this.dmg) {
let ds = this.getData('id,level,attr,cons,artis:artis.sets,trees')
ds.talent = lodash.mapValues(this.talent, 'level')
ds.weapon = Data.getData(this.weapon, 'name,affix')
this.dmg = new ProfileDmg(ds, this.game)
}
return await this.dmg.calcData({ enemyLv, mode, dmgIdx })
return await this.dmg.calcData({ enemyLv, mode, dmgIdx, idxIsInput })
}
}

View File

@ -7,7 +7,7 @@ import { attrMap as attrMapSR } from '../resources/meta-sr/artifact/index.js'
import DmgBuffs from './profile/DmgBuffs.js'
import DmgAttr from './profile/DmgAttr.js'
import DmgCalc from './profile/DmgCalc.js'
import { Common } from '#miao'
import {Common, MiaoError} from '#miao'
export default class ProfileDmg extends Base {
constructor (profile = {}, game = 'gs') {
@ -98,7 +98,7 @@ export default class ProfileDmg extends Base {
return false
}
async calcData ({ enemyLv = 91, mode = 'profile', dmgIdx = 0 }) {
async calcData ({ enemyLv = 91, mode = 'profile', dmgIdx = 0, idxIsInput = false }) {
if (!this.char || !this.profile) {
return false
}
@ -129,12 +129,19 @@ export default class ProfileDmg extends Base {
buffs = this.getBuffs(buffs)
let { msg } = DmgAttr.calcAttr({ originalAttr, buffs, meta, params: defParams || {} })
let msgList = []
let ret = []
let detailMap = []
let dmgRet = []
let dmgDetail = {}
// 用户手动输入伤害序号
if (idxIsInput) {
// 从1开始所以需要 - 1
dmgIdx = --dmgIdx < 0 ? 0 : dmgIdx
}
if (mode === 'single') {
dmgIdx = defDmgIdx > -1 ? defDmgIdx : 0
}
@ -156,7 +163,7 @@ export default class ProfileDmg extends Base {
detail = detail({ ...ds, attr, profile })
}
let params = lodash.merge({}, defParams, detail?.params || {})
let { attr } = DmgAttr.calcAttr({ originalAttr, buffs, meta, params, talent: detail.talent || '' })
let { attr, msg } = DmgAttr.calcAttr({ originalAttr, buffs, meta, params, talent: detail.talent || '' })
if (detail.isStatic) {
return
}
@ -180,12 +187,16 @@ export default class ProfileDmg extends Base {
...basicDmgRet
})
}
msgList.push(msg)
})
if (mode === 'dmg') {
let detail
if (dmgIdx && detailMap[dmgIdx - 1]) {
detail = detailMap[dmgIdx - 1]
if (idxIsInput && detailMap[dmgIdx]) {
detail = detailMap[dmgIdx]
} else if (idxIsInput) {
// 当用户输入的下标错误时,提示错误
throw new MiaoError(`序号输入错误:${this.char.name}最多只支持${detailMap.length}种伤害计算哦`)
} else if (!lodash.isUndefined(defDmgIdx) && details[defDmgIdx]) {
detail = details[defDmgIdx]
} else {
@ -247,7 +258,9 @@ export default class ProfileDmg extends Base {
}
return {
ret,
msg,
// 根据当前计算的伤害显示对应的buff列表
msg: msgList[idxIsInput ? dmgIdx : (defDmgIdx > -1 ? defDmgIdx : dmgIdx)] || msg,
msgList,
dmgRet,
enemyName,
dmgCfg: dmgDetail,

View File

@ -1,3 +1,6 @@
// 纳西妲、妮露、艾尔海森、心海
const team2 = createTeam('海妮心妲', ['纳西妲', '艾尔海森', '心海'])
export const details = [{
title: '水月伤害',
params: { sy: true ,team:false},
@ -29,26 +32,41 @@ export const details = [{
title: 'Q两段蒸发总伤害',
params: { team:false },
dmg: ({ talent, calc, attr }, { basic }) => basic(calc(attr.hp) * (talent.q['技能伤害'] + talent.q['永世流沔伤害']) / 100, 'q', '蒸发')
}, {
title: '夜万妮香Q总蒸发伤害',
params: { team:true },
dmg: ({ talent, calc, attr }, { basic }) => basic(calc(attr.hp) * (talent.q['技能伤害'] + talent.q['永世流沔伤害']) / 100, 'q', '蒸发')
}, {
title: '丰穰之核伤害',
params: { bloom:true ,team:false },
dmg: ({calc, attr}, { reaction }) => {
return reaction('bloom')}
}, {
title: '海妮心二妲·丰穰之核',
params: {team: false, bloom: true, ...team2.params},
dmg: ({}, {reaction}) => {
// 草神二命固定暴击率20%、暴击伤害100%
const cpctNum = 20 / 100, cdmgNum = 100 / 100
// 计算丰穰之核非暴击伤害
const {avg} = reaction('bloom')
return {
// 暴击伤害
dmg: avg * (1 + cdmgNum),
// 平均伤害
avg: avg * (1 + cpctNum * cdmgNum)
}
}
}, {
title: '夜万妮香Q总蒸发伤害',
params: { team:true },
dmg: ({ talent, calc, attr }, { basic }) => basic(calc(attr.hp) * (talent.q['技能伤害'] + talent.q['永世流沔伤害']) / 100, 'q', '蒸发')
}]
export const mainAttr = 'hp,atk,cpct,cdmg,mastery'
export const defDmgIdx = 6
export const defParams = {
team:true,
}
export const buffs = [{check: ({ params }) => params.team === false,
export const buffs = [{
check: ({ params }) => params.team === false || team2.is(params),
title: '妮露天赋:丰穰之核增伤[bloom]%,元素精通提升100点',
data: {
bloom: ({ calc, attr }) => Math.min(400,(calc(attr.hp)-30000)/1000*9),
@ -61,14 +79,14 @@ export const buffs = [{check: ({ params }) => params.team === false,
eDmg: ({ params }) => params.sy ? 65 : 0
}
}, {
check: ({params }) => params.team === false,
check: ({params }) => params.team === false || team2.is(params),
title: '妮露2命金杯的丰馈下降低敌人35%水抗与草抗',
cons: 2,
data: {
kx: 35
}
}, {
check: ({ cons,params }) => cons <= 1 && params.team === true,
check: ({ cons,params }) => cons <= 1 && params.team === true && team2.not(params),
title: '精1苍古0命万叶获得[dmg]%增伤(苍古普攻16增伤),增加[atkPct]%攻击,减抗[kx]%',
data: {
aDmg:16,
@ -79,7 +97,7 @@ export const buffs = [{check: ({ params }) => params.team === false,
kx:40,
}
}, {
check: ({ cons,params }) => ((cons < 6 && cons >1) && params.team === true),
check: ({ cons,params }) => ((cons < 6 && cons >1) && params.team === true && team2.not(params)),
title: '精1苍古2命万叶获得[dmg]%增伤(苍古普攻16增伤),增加[atkPct]%攻击,减抗[kx]%,精通[mastery]',
data: {
aDmg:16,
@ -91,7 +109,7 @@ export const buffs = [{check: ({ params }) => params.team === false,
mastery:200
}
}, {
check: ({ cons,params }) => (cons >= 6 && params.team === true),
check: ({ cons,params }) => (cons >= 6 && params.team === true && team2.not(params)),
title: '精5苍古6命万叶获得[dmg]%增伤(苍古普攻32增伤),增加[atkPct]%攻击,减抗[kx]%,精通[mastery]',
data: {
aDmg:32,
@ -103,14 +121,14 @@ export const buffs = [{check: ({ params }) => params.team === false,
mastery:200
}
}, {
check: ({ cons,params }) => (cons >= 4 && params.team === true),
check: ({ cons,params }) => (cons >= 4 && params.team === true && team2.not(params)),
title: '双水夜兰2层4命双水,夜兰4命[hpPct]%生命值,[dmg]增伤',
data: {
hpPct: 45,
dmg:30
}
}, {
check: ({ cons,params }) => (cons < 4 && params.team === true),
check: ({ cons,params }) => (cons < 4 && params.team === true && team2.not(params)),
title: '双水夜兰:双水[hpPct]%生命值,[dmg]增伤',
data: {
hpPct: 25,
@ -129,4 +147,50 @@ export const buffs = [{check: ({ params }) => params.team === false,
cpct: ({ calc, attr }) => Math.min(30, calc(attr.hp) / 1000 * 0.6),
cdmg: ({ calc, attr }) => Math.min(60, calc(attr.hp) / 1000 * 1.2)
}
}, {
check: ({params}) => team2.is(params),
title: '双水双草共鸣:双水提升[hpPct]%生命值上限双草提升精通50点触发绽放再提升30点共提升[mastery]点',
data: {
hpPct: 25,
mastery: 50 + 30,
}
}, {
check: ({params}) => team2.is(params),
title: '千精草套纳西妲开Q增加[mastery]点精通,减[kx]%草抗',
data: {
mastery: 1000 * 0.25,
kx: 30
}
}, {
check: ({params}) => team2.is(params),
title: '精1千夜浮梦队伍中装备者以外的角色元素精通提升[mastery]点',
data: {
mastery: 40,
}
}, {
check: ({params}) => team2.is(params),
title: '纳西妲2命提供绽放反应固定20%暴击率和100%的暴击伤害',
data: {}
}, 'vaporize']
/**
* 创建队伍
* @param name 队伍名
* @param members 队员
* @return {{name, members, params, go, is, not}}
*/
function createTeam(name, members) {
const team = {name, members}
// 队伍出战
team.go = () => {
const params = {}
team.members.forEach(k => params[name + '_' + k] = true);
return params
}
team.params = team.go()
// 是否是当前配队
team.is = (params) => members.filter(k => params[name + '_' + k] === true).length === members.length
// 是否不是当前配队
team.not = (params) => !team.is(params)
return team
}