import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE, ABI_TYPE_MAIN, HERO_CE_RATIO, HERO_SYSTEM_TYPE, SEID_TYPE } from "../../consts"; import { HeroModel, HeroUpdate, CeAttrData } from "../../db/Hero"; import { CeAttrDataRole, RoleUpdate } from "../../db/Role"; import { gameData, getHeroStarByQuality, getHeroWakeByQuality } from "../../pubUtils/data"; import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool"; import { DicSe } from "../../pubUtils/dictionary/DicSe"; import { deepCopy } from "../../pubUtils/util"; import { AttributeCal } from "./attribute"; export class CalRoleCe { private roleInfo: RoleUpdate; private roleCeWithAttr: Map = new Map(); constructor(roleInfo?: RoleUpdate) { this.roleInfo = roleInfo; } public cal(type: HERO_SYSTEM_TYPE) { switch (type) { case HERO_SYSTEM_TYPE.INIT: this.calTitleAbility(); this.calTeraphMainAttr(); break; } return this.getRoleAttr(); } private calTitleAbility() { let { title } = this.roleInfo; let dicTitle = gameData.title.get(title)||{ mainAttrValue: new Map(), assiAttrValue: new Map() }; for (let i = ABI_TYPE.ABI_HP; i < ABI_TYPE.ABI_MAX; i++) { if (dicTitle.mainAttrValue.has(i)) { let fixUp = dicTitle.mainAttrValue.get(i) || 0; this.getSingleAttrObj(i).updateAttr({ inc: { fixUp } }); } if (dicTitle.assiAttrValue.has(i)) { let fixUp = dicTitle.assiAttrValue.get(i) || 0; this.getSingleAttrObj(i).updateAttr({ inc: { fixUp } }); } } } private calTeraphMainAttr(id?: number) { let { teraphs = [] } = this.roleInfo; for(let teraph of teraphs) { if(id == undefined || teraph.id == id) { for(let [attrId, val] of teraph.attr) { this.getSingleAttrObj(attrId).updateAttr({ inc: { fixUp: val } }); } } } } // 获取一个CeAttrData对象,没有就新建 public getSingleAttrObj(attrId: ABI_TYPE) { if(!this.roleCeWithAttr.has(attrId)) { let calSingleAttr = new CeAttrDataRole(attrId); this.roleCeWithAttr.set(attrId, calSingleAttr); } return this.roleCeWithAttr.get(attrId); } private getRoleAttr() { let attr: CeAttrDataRole[] = []; this.roleCeWithAttr.forEach(value => { if(value.ratioUp > 0 || value.fixUp > 0) { attr.push(value); } }); return attr; } } export class CalHeroCe { private hid: number; private heroInfo: HeroUpdate; private heroCeWithAttr: Map = new Map(); constructor(hid: number, heroInfo?: HeroUpdate) { this.hid = hid; if(heroInfo) this.heroInfo = heroInfo; } public async setHeroInfoByHid(roleId: string) { let hero = await HeroModel.findByHidAndRole(this.hid, roleId); this.heroInfo = hero; } // 主要接口 public cal(type: HERO_SYSTEM_TYPE) { switch (type) { case HERO_SYSTEM_TYPE.INIT: this.calBaseAbility(); this.calSkinSeid(); this.calJobAbility(); break; } return this.getHeroAttr() } // 计算基础属性 private calBaseAbility() { let { star, starStage, quality, colorStar, colorStarStage, lv, skinId } = this.heroInfo; const dicHero = gameData.hero.get(skinId); if(!dicHero) { console.error(`not found hero: ${skinId}`); return; } for (let stage = ABI_STAGE.START + 1; stage <= ABI_STAGE.END; stage++) { let attrId = ABI_STAGE_TO_TYPE.get(stage); const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1 // console.log('*isUpstar', isUpStar, originStar, star, originColorStar, colorStar) const dicStar = isWake ? getHeroWakeByQuality(dicHero.jobClass, dicHero.quality, colorStarStage < stage? colorStar - 1: colorStar) : getHeroStarByQuality(dicHero.jobClass, quality, starStage < stage? star - 1: star); // 星级表 let heroAttr = dicHero.baseAbilityArr.get(attrId); // 武将表hp等 let heroUpAttr = dicHero.baseAbilityUpArr.get(attrId); // 武将表hp_up等 let starUp = 0; // 星级成长 if (!!dicStar && !!dicStar.ceAttr) { starUp = dicStar.ceAttr.get(stage); } let base = heroAttr + lv * (heroUpAttr + starUp); this.getSingleAttrObj(attrId).updateAttr({ set: { base } }); }; } // 计算职业属性 private calJobAbility() { let { job, jobStage } = this.heroInfo; const dicJob = gameData.job.get(job); for(let i = 1; i <= dicJob.maxStage; i++) { if(jobStage >= i) { let { id, attr } = dicJob.ceAttr.get(i); this.getSingleAttrObj(id).updateAttr({ inc: { fixUp: attr } }); } } addSeidEffect.bind(this, dicJob.seid); } // 计算皮肤属性 private calSkinSeid() { let { skinId, star: _star, colorStar: _colorStar } = this.heroInfo; let seidList = new Map(); // type => seid let dicHero = gameData.hero.get(skinId); let { starSeidArr, colorStarSeidArr } = gameData.heroSkill.get(dicHero.skill); for (let { star, value, type } of starSeidArr) { if (_star >= star) { seidList.set(type, value); } } for (let { star, value, type } of colorStarSeidArr) { if (_colorStar >= star) { seidList.set(type, value); } } let list: number[] = []; for(let [_type, value] of seidList) list.push(value); addSeidEffect.bind(this, list); } public getHeroAttr() { let attr: CeAttrData[] = []; this.heroCeWithAttr.forEach(value => { if(value.base > 0 || value.equipUp > 0 || value.fixUp > 0 || value.ratioUp > 0) { attr.push(value); } }); return attr; } // 获取一个CeAttrData对象,没有就新建 public getSingleAttrObj(attrId: ABI_TYPE) { if(!this.heroCeWithAttr.has(attrId)) { let calSingleAttr = new CeAttrData(attrId); this.heroCeWithAttr.set(attrId, calSingleAttr); } return this.heroCeWithAttr.get(attrId); } public getCalculatedCe(roleAttr: CeAttrDataRole[]) { let attrCal = new AttributeCal(); attrCal.setLv(this.heroInfo.lv); attrCal.setByDbData(roleAttr, this.getHeroAttr()); return attrCal.calCe(); } } // 添加技能增加的被动属性 function addSeidEffect(this: CalRoleCe|CalHeroCe, seidList: number[]) { // console.log('******addSeidEffect',this, seidList) // console.log('addSeidList', addSeidList.join()) // console.log('removeSeidList', removeSeidList.join()) let effectList: DicSe[] = []; // any: dic_zyz_se表内容 for (let ii = 0; ii < seidList.length; ii += 2) { let seid = seidList[ii]; let rand = seidList[ii + 1] || 0; let dicSeid: DicSe | DicRandomEffectPool = gameData.se.get(seid); if (!dicSeid) dicSeid = gameData.randomEffectPool.get(seid); if (dicSeid && dicSeid.id > 0) { addSeid(effectList, dicSeid.id, rand, dicSeid.gainValueArr) } } // console.log('effectList', JSON.stringify(effectList)); for (let { type, gainValueArr: [ability, value] } of effectList) { if (type == SEID_TYPE.TYPE101) { // 加值 this.getSingleAttrObj(ability).updateAttr({ inc: { fixUp: value } }); } else if (type == SEID_TYPE.TYPE103) { // 主属性加百分比 if(ABI_TYPE_MAIN.includes(ability)) { this.getSingleAttrObj(ability).updateAttr({ inc: {ratioUp: value / 1000} }); } } else if (type == SEID_TYPE.TYPE104) { // 次级属性加百分比 if(!ABI_TYPE_MAIN.includes(ability)) { this.getSingleAttrObj(ability).updateAttr({ inc: { fixUp: value * 100 * HERO_CE_RATIO } }); } } } } // 获取dic_zyz_se内容 function addSeid(effectList: (DicSe | DicRandomEffectPool)[], seidId: number, rand: number, seidValue: number[] = []) { let curSeid: DicSe | DicRandomEffectPool = gameData.se.get(seidId); if (!curSeid) curSeid = gameData.randomEffectPool.get(seidId); if (!curSeid) { console.log("seidId not found:" + seidId); return; } if (!seidValue) seidValue = curSeid.gainValueArr; if (curSeid.type === SEID_TYPE.TYPE999) { for (let i = 0; i < seidValue.length; i++) { addSeid(effectList, seidValue[i], rand); } return; } let seid: DicSe | DicRandomEffectPool = deepCopy(curSeid); if (curSeid.index > 0) { seid.gainValueArr[curSeid.index - 1] = rand; } effectList.push(seid); }