HJ_Server/src/shared/public/hero.ts
xichaoyin 2e054daa65 fix:
修复威望系统属性在探险战斗中没有生效
2024-01-04 16:12:55 +08:00

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?.weiwang) {
PublicShared.mergeProperty(buff, otherBuff?.weiwang || {});
}
//最后进行加成属性计算
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 || [];
}
}