390 lines
15 KiB
TypeScript
390 lines
15 KiB
TypeScript
import { ResGetList } from '../protocols/hero/PtlGetList';
|
|
import { player } from '../protocols/user/type';
|
|
import { EquipShared } from './equip';
|
|
import { PeijianShared } from './peijian';
|
|
import { PlayerShared } from './player';
|
|
import { PublicShared } from './public';
|
|
import { ShiwuShared } from './shiwu';
|
|
|
|
export type otherBuff = Partial<player & {
|
|
allBuff: k_v<number>;
|
|
}>;
|
|
type heroDataType = Partial<Omit<ResGetList['list'][''], 'getTime'>>;
|
|
|
|
export class HeroShared {
|
|
static getAllBuff(hero: heroDataType[]) {
|
|
let allBuff: k_v<number> = {};
|
|
|
|
hero.forEach(h => {
|
|
let heroConf = G.gc.hero[h.heroId];
|
|
let heroGrow = G.gc.herogrow[heroConf.jjup]?.[h.jieji];
|
|
heroGrow && PublicShared.mergeProperty(allBuff, heroGrow.jj_allattr || {});
|
|
});
|
|
|
|
return allBuff;
|
|
}
|
|
|
|
/**
|
|
* 获取英雄基本属性
|
|
* @param hero 英雄数据
|
|
* @param otherBuff 有些功能会对英雄有属性加成
|
|
*/
|
|
static getHeroBasicAttr(hero: heroDataType, otherBuff: otherBuff = G.otherBuff, pos = 0) {
|
|
let jiban = 0;
|
|
let buff: k_v<any> = { skillArr: [] };
|
|
let heroConf = G.gc.hero[hero.heroId];
|
|
let heroLv = G.gc.herolv[heroConf.lvup];
|
|
let heroGrow = G.gc.herogrow[heroConf.jjup]?.[hero.jieji];
|
|
|
|
//计算等级属性
|
|
for (let k in heroLv.buff) {
|
|
let val = heroLv.buff[k];
|
|
if (typeof val == 'number') buff[k] = val;
|
|
else buff[k] = PublicShared.eval(val, { lv: hero.lv });
|
|
// else buff[k] = Math.floor(new Function(`let lv=${hero.lv}; return ${val}`)());
|
|
}
|
|
|
|
//计算阶级属性
|
|
if (heroGrow) {
|
|
PublicShared.mergeProperty(buff, heroGrow.buff);
|
|
PublicShared.mergeProperty(buff, heroGrow.jj_attr);
|
|
}
|
|
|
|
if (pos > 0 && otherBuff.allBuff) {
|
|
PublicShared.mergeProperty(buff, otherBuff.allBuff);
|
|
}
|
|
|
|
if (pos > 0) {
|
|
if (otherBuff.headFrames) {
|
|
for (let [id, time] of Object.entries(otherBuff.headFrames)) {
|
|
if (time == -1 || time > G.time) {
|
|
PublicShared.mergeProperty(buff, G.gc.playerHeadFrame[id].buff);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (otherBuff.chatFrames) {
|
|
for (let [id, time] of Object.entries(otherBuff.chatFrames)) {
|
|
if (time == -1 || time > G.time) {
|
|
PublicShared.mergeProperty(buff, G.gc.playerChatFrame[id].buff);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (otherBuff.model) {
|
|
for (let [id, item] of Object.entries(otherBuff.model)) {
|
|
if (item.time == -1 || item.time > G.time) {
|
|
PublicShared.mergeProperty(buff, G.gc.playerModel[id].buff);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//计算装备属性
|
|
if (hero.equip) {
|
|
for (let pos in hero.equip) {
|
|
hero.equip[pos] && PublicShared.mergeProperty(buff, EquipShared.getEquipBuff(hero.equip[pos]));
|
|
}
|
|
|
|
let equips = Object.values(hero.equip).filter(e => e != '').map(e => EquipShared.fmtEquip(e));
|
|
|
|
//计算装备大师属性
|
|
if (equips.length >= 4) {
|
|
let minLv = Math.min(...equips.map(e => e.lv));
|
|
let minStar = Math.min(...equips.map(e => e.star));
|
|
let minAdjustment = Math.min(...equips.map(e => e.adjustment));
|
|
let lvMasterConf = G.gc.equipMaster.peiyang.filter(c => c.aLv <= minLv).sort((a, b) => b.lv - a.lv)[0];
|
|
let starMasterConf = G.gc.equipMaster.shengxing.filter(c => c.aLv <= minStar).sort((a, b) => b.lv - a.lv)[0];
|
|
let adjustmentMasterConf = G.gc.equipMaster.tiaojiao.filter(c => c.aLv <= minAdjustment).sort((a, b) => b.lv - a.lv)[0];
|
|
|
|
lvMasterConf && PublicShared.mergeProperty(buff, lvMasterConf.buff);
|
|
starMasterConf && PublicShared.mergeProperty(buff, starMasterConf.buff);
|
|
adjustmentMasterConf && PublicShared.mergeProperty(buff, adjustmentMasterConf.buff);
|
|
}
|
|
|
|
//计算装备套装属性
|
|
let ids = equips.map(e => G.gc.equip[e.equipId].tzid).filter(i => !!i).map(i => Object.fromEntries([[i, 1]]));
|
|
let objs: k_v<number> = {};
|
|
ids.forEach(v => PublicShared.mergeProperty(objs, v));
|
|
|
|
for (let [id, num] of Object.entries(objs)) {
|
|
let conf = G.gc.equipSuit[id];
|
|
let nums = Object.keys(conf.buff).map(n => Number(n)).sort((a, b) => a - b);
|
|
if (num < nums[0]) continue;
|
|
nums.forEach(n => num >= n && PublicShared.mergeProperty(buff, conf.buff[n]));
|
|
}
|
|
|
|
//计算装备羁绊
|
|
let confs = G.gc.group.equip.filter(c => c.page == hero.heroId);
|
|
let equipIds = equips.map(e => e.equipId);
|
|
confs.forEach(conf => {
|
|
if (equipIds.includes(conf.member.toString())) {
|
|
jiban++;
|
|
PublicShared.mergeProperty(buff, conf.skill);
|
|
}
|
|
});
|
|
}
|
|
|
|
//计算配件属性
|
|
if (hero.peijian) {
|
|
let suitObj: k_v<{ num: number, minLv: number; }> = {};
|
|
let pjs = Object.values(hero.peijian).filter(s => !!s).map(s => PeijianShared.fmt(s));
|
|
|
|
|
|
pjs.forEach(p => {
|
|
PublicShared.mergeProperty(buff, PeijianShared.getAttr(p));
|
|
let conf = G.gc.peijian[p.peijianId];
|
|
if (conf.suit) {
|
|
if (!suitObj[conf.suit]) suitObj[conf.suit] = { num: 0, minLv: 0 };
|
|
suitObj[conf.suit].num++;
|
|
if (!suitObj[conf.suit].minLv || p.lv < suitObj[conf.suit].minLv) suitObj[conf.suit].minLv = p.lv;
|
|
}
|
|
});
|
|
|
|
let sumLv = R.sum(pjs.map(i => i.lv))
|
|
|
|
for (let [suitId, data] of Object.entries(suitObj)) {
|
|
|
|
// //计算配件套装属性
|
|
// let suitConf = G.gc.peijian_suit[suitId];
|
|
// let suitBuff = Object.entries(suitConf.buff).filter(v => Number(v) <= data.num);
|
|
// suitBuff.forEach(b => PublicShared.mergeProperty(buff, b[1]));
|
|
|
|
//计算配件大师属性
|
|
let masterConf = Object.values(G.gc.peijian_master[suitId]).filter(c => c.needLv <= sumLv).sort((a, b) => b.lv - a.lv)[0];
|
|
if (masterConf) {
|
|
let masterbuff = Object.entries(masterConf.buff).filter(v => Number(v[0]) <= data.num);
|
|
masterbuff.forEach(b => PublicShared.mergeProperty(buff, b[1]));
|
|
}
|
|
}
|
|
}
|
|
|
|
//计算专属武器属性
|
|
if (hero.weapon?.jieji) {
|
|
PublicShared.mergeProperty(buff, G.gc.zhuanshu[heroConf.zhuanshu][hero.weapon.jieji][hero.weapon.star].buff);
|
|
}
|
|
|
|
//计算天赋属性
|
|
if (hero.talent) {
|
|
for (let [type, lv] of Object.entries(hero.talent)) {
|
|
let conf = G.gc.hero_tf[type]?.[lv];
|
|
conf && conf.effect && PublicShared.mergeProperty(buff, conf.effect);
|
|
}
|
|
}
|
|
|
|
//计算饰物属性
|
|
if (hero.shiwu) {
|
|
for (let pos in hero.shiwu) {
|
|
hero.shiwu[pos] && ShiwuShared.getShiwuBuff(hero.shiwu[pos], buff, hero.heroId);
|
|
}
|
|
}
|
|
|
|
//计算潜能属性
|
|
if (hero.qiannneg) {
|
|
for (let type in hero.qiannneg) {
|
|
// console.log(PublicShared.mergeProperty(buff, G.gc.hero_qianneng[type]?.[hero.qiannneg[type]].buff))
|
|
for (let i = 1; i <= hero.qiannneg[type]; i++) {
|
|
G.gc.hero_qianneng[type]?.[i] && PublicShared.mergeProperty(buff, G.gc.hero_qianneng[type]?.[i].buff);
|
|
}
|
|
}
|
|
}
|
|
|
|
//计算名望加成属性
|
|
// if (otherBuff?.renown) {
|
|
// for (let lv = 1; lv < otherBuff.renown; lv++) {
|
|
// G.gc.mw_dj[lv].buff && PublicShared.mergeProperty(buff, G.gc.mw_dj[lv].buff);
|
|
// }
|
|
// }
|
|
|
|
//计算维修厂buff
|
|
// if (otherBuff?.wxcLv) {
|
|
// let curWxcLv = otherBuff.wxcLv.lv + 1;
|
|
// for (let lv = 1; lv < curWxcLv; lv++) {
|
|
// PublicShared.mergeProperty(buff, Object.values(G.gc.weixiuchang_zz[lv].buff));
|
|
// G.gc.weixiuchang_zz[lv].buff2 && PublicShared.mergeProperty(buff, G.gc.weixiuchang_zz[lv].buff2);
|
|
// }
|
|
// if (otherBuff.wxcLv.ids.length > 0) {
|
|
// otherBuff.wxcLv.ids.forEach(id => {
|
|
// G.gc.weixiuchang_zz[curWxcLv].buff[id + 1] && PublicShared.mergeProperty(buff, G.gc.weixiuchang_zz[curWxcLv].buff[id + 1]);;
|
|
// });
|
|
// }
|
|
// }
|
|
|
|
//计算收藏品buff;
|
|
if (pos > 0 && otherBuff?.shoucangping) {
|
|
PublicShared.mergeProperty(buff, PlayerShared.getMingDaoBuff(otherBuff as any, 'hero_buff') || {});
|
|
|
|
for (let [id, lv] of Object.entries(otherBuff.shoucangping)) {
|
|
if (lv >= 1) {
|
|
PublicShared.mergeProperty(buff, G.gc.mingdao[id].buff);
|
|
PublicShared.mergeProperty(buff, Object.fromEntries(Object.keys(G.gc.mingdao[id].upBuff).map(k => [k, G.gc.mingdao[id].upBuff[k] * (lv - 1)])));
|
|
}
|
|
}
|
|
}
|
|
|
|
//计算公会物资buff
|
|
if (otherBuff?.ghwz) {
|
|
for (let id in otherBuff.ghwz) {
|
|
let conf = G.gc.shili_wz[id][otherBuff.ghwz[id]];
|
|
conf && PublicShared.mergeProperty(buff, conf.buff);
|
|
}
|
|
}
|
|
|
|
//计算阵型加成
|
|
if (pos > 0 && otherBuff?.selectMatrix) {
|
|
let lv = otherBuff.matrix[otherBuff.selectMatrix];
|
|
let select = otherBuff.selectMatrix;
|
|
let posObj = otherBuff.matrixPos?.[select] || {};
|
|
let find = Object.entries(posObj).find(v => v[1] == hero._id);
|
|
|
|
if (find) {
|
|
let maxLv = R.values(G.gc.fightPlan[select]).length - 1
|
|
let fixLv = lv > maxLv ? maxLv : lv
|
|
let __buff = G.gc.fightPlan[select][fixLv].buff[Number(find[0]) - 1];
|
|
__buff && PublicShared.mergeProperty(buff, __buff);
|
|
}
|
|
}
|
|
|
|
//计算助战属性
|
|
if (pos > 0 && otherBuff?.helpHeros) {
|
|
let arr = otherBuff.helpHeros.map(v => v.jieji);
|
|
let allJieJi = arr.length > 0 ? arr.reduce((a, b) => a + b) : 0;
|
|
let helpBuff = G.gc.herocom.zhuzhanBuff.filter(v => v.need <= allJieJi).sort((a, b) => b.need - a.need)[0];
|
|
helpBuff && PublicShared.mergeProperty(buff, helpBuff.value);
|
|
}
|
|
|
|
//计算英雄羁绊
|
|
if (otherBuff?.fightHeros) {
|
|
if (!otherBuff.heroPos || Object.values(otherBuff.heroPos).includes(hero._id)) {
|
|
let confs = G.gc.group.hero.filter(c => c.page == hero.heroId);
|
|
confs.forEach(conf => {
|
|
let arr = conf.member.split(',').removeOne(id => id == hero.heroId).sort();
|
|
let inArr = arr.intersection([].concat(otherBuff.fightHeros, otherBuff.helpHeros?.map(h => h.heroId || ''))).sort();
|
|
|
|
if (arr.join('_') == inArr.join('_')) {
|
|
jiban++;
|
|
PublicShared.mergeProperty(buff, conf.skill);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
//计算训练计划
|
|
if (otherBuff?.skills) {
|
|
for (let [id, lv] of Object.entries(otherBuff.skills)) {
|
|
if (lv && G.gc.xunlianjihua[id].use == 0) {
|
|
PublicShared.mergeProperty(buff, Object.fromEntries([G.gc.xunlianjihua[id].skill].map(k => [k, PublicShared.eval(G.gc.xunlianjihua[id].v[0], { slv: lv })])));
|
|
}
|
|
}
|
|
}
|
|
|
|
// 威望加成计算
|
|
if (otherBuff?.weiwangbuff) {
|
|
PublicShared.mergeProperty(buff, otherBuff?.weiwangbuff || {});
|
|
}
|
|
|
|
//最后进行加成属性计算
|
|
for (let k in buff) {
|
|
if (k.indexOf('pro') == -1) continue;
|
|
let buffKey = k.replace('pro', '');
|
|
if (buff[buffKey]) {
|
|
buff[buffKey] += buff[buffKey] * buff[k];
|
|
if (buffKey == 'baoshang' && buff[buffKey] > 10) buff[buffKey] = 10
|
|
// buff[k] = 0;
|
|
}
|
|
}
|
|
|
|
buff.mindps += buff.atk;
|
|
buff.maxdps += buff.atk;
|
|
|
|
//属性取整
|
|
this.amendAttr(buff);
|
|
|
|
buff.jiban = jiban;
|
|
buff.maxHp = buff.hp;
|
|
|
|
return buff;
|
|
};
|
|
|
|
/**修正属性 数值取整*/
|
|
static amendAttr(buff: k_v<number>) {
|
|
for (let k in buff) {
|
|
if (typeof buff[k] != 'number') continue;
|
|
if (k.indexOf('pro') != -1 || k.indexOf('drop') != -1) continue;
|
|
buff[k] = Math.floor(buff[k]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取英雄战力
|
|
* @param hero 英雄数据
|
|
* @param otherBuff 有些功能会对英雄有属性加成
|
|
*/
|
|
static getHeroZhanLi(hero: heroDataType, otherBuff: otherBuff = G.otherBuff, pos = 0) {
|
|
let buff = this.getHeroBasicAttr(hero, otherBuff, pos);
|
|
return this.computeHeroZhanLi(buff);
|
|
}
|
|
|
|
/**
|
|
* 计算英雄战力
|
|
*/
|
|
static computeHeroZhanLi(buff: k_v<any> = {}) {
|
|
let atk = buff.atk || 0;
|
|
let mindps = buff.mindps || 0;
|
|
let maxdps = buff.maxdps || 0;
|
|
let def = buff.def || 0;
|
|
let hp = buff.hp || 0;
|
|
let speed = buff.speed || 0;
|
|
let speedpro = buff.speedpro || 0;
|
|
let hppro = buff.hppro || 0;
|
|
let dpspro = buff.dpspro || 0;
|
|
let undpspro = buff.undpspro || 0;
|
|
let xixuepro = buff.xixuepro || 0;
|
|
let baoshangpro = buff.baoshangpro || 0;
|
|
let shanbipro = buff.shanbipro || 0;
|
|
let mingzhongpro = buff.mingzhongpro || 0;
|
|
let pvpdpspro = buff.pvpdpspro || 0;
|
|
let pvpdpsdrop = buff.pvpdpsdrop || 0;
|
|
|
|
return Math.floor(
|
|
(atk * .85) +
|
|
(mindps * .85) +
|
|
(maxdps * .75) +
|
|
(def * 1.03) +
|
|
(hp * 1) +
|
|
(hp * hppro * .5) +
|
|
(speed * (speedpro + 1) * 21.28) +
|
|
((mindps + maxdps) / 2 * dpspro * .75) +
|
|
(hp * undpspro * .6) +
|
|
((mindps + maxdps) / 2 * xixuepro) +
|
|
((mindps + maxdps) / 2 * baoshangpro * .75) +
|
|
((mindps + maxdps) / 2 * shanbipro * .5) +
|
|
((mindps + maxdps) / 2 * mingzhongpro * .5) +
|
|
((mindps + maxdps) / 2 * pvpdpspro * .5) +
|
|
(hp * pvpdpsdrop * .5)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 获取英雄升级消耗
|
|
* @param id 英雄id
|
|
* @param lv 英雄等级
|
|
*/
|
|
static getHeroLvUpNeed(id: string | number, lv = 1): atn[] {
|
|
|
|
return [
|
|
{ a: 'item', t: '1', n: G.gc.herolvup[lv].expneed },
|
|
{ a: 'attr', t: 'jinbi', n: G.gc.herolvup[lv].jinbineed }
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 获取英雄进阶消耗
|
|
* @param id 英雄id
|
|
* @param lv 英雄当前阶级
|
|
*/
|
|
static getHeroJinJieNeed(id: string | number, jieji = 0): atn[] {
|
|
let heroJinJie = G.gc.herogrow[G.gc.hero[id].jjup];
|
|
return heroJinJie?.[jieji + 1]?.need || [];
|
|
}
|
|
} |