/** * 体力系统 */ import { HERO_SYSTEM_TYPE, ABI_TYPE, JEWEL_ATTR } from '../consts'; import { deepCopy } from './util'; import { HeroModel, HeroType } from '../db/Hero'; import { RoleModel } from '../db/Role'; import { CeAttrData, CeAttr, CeAttrNumber } from '../db/generalField'; import { getAttrNameByJobStage, getAttrCeRatio, getAtrrNameById, ABI_TYPE_TO_STAGE, ABI_STAGE, SEID_TYPE} from '../consts'; import { gameData, getJobByGradeAndClass, getHeroWakeByQuality, getHeroStarByQuality, getFriendShipById } from './data'; import { Attributes } from './interface'; import { DicSe } from './dictionary/DicSe'; import { EquipType } from '../db/Equip'; import { DicRandomEffectPool } from './dictionary/DicRandomEffectPool'; import { getGoodById } from './gamedata'; const HERO_CE_RATIO = 100; const _ = require('underscore'); //战力计算TODO export function calPlayerCe(globalCeAttr: CeAttr, hero: HeroType, type: number, args: Array) { let incCe = 0; let incArr: Attributes = {}; let reIncAttr: CeAttr = {}; // {"hp": {"base": number, "fixUp": number, "ratioUp": number}} let addSeidList = new Array(); let removeSeidList = new Array(); if (type == HERO_SYSTEM_TYPE.INIT) { reIncAttr = calHeroInitIncAttr(hero, addSeidList, removeSeidList); // args: 升的星盘 } else if (type == HERO_SYSTEM_TYPE.STAR) { reIncAttr = calHeroStarIncAttr(hero, args, addSeidList, removeSeidList); // args: 升的星盘 } else if (type == HERO_SYSTEM_TYPE.TRAIN) { reIncAttr = calHeroTrainIncAttr(hero); } else if (type == HERO_SYSTEM_TYPE.STAGEUP) { reIncAttr = calHeroJobStageUpIncAttr(hero, args, addSeidList, removeSeidList ); } else if (type == HERO_SYSTEM_TYPE.SKIN) { reIncAttr = calHeroWearSkinIncAttr(hero, args, addSeidList, removeSeidList ); } else if (type == HERO_SYSTEM_TYPE.FAVOUR) { reIncAttr = calHeroFavourUpIncAttr(hero, args); } else if (type == HERO_SYSTEM_TYPE.CONNECT) { reIncAttr = calHeroConectIncAttr(hero, args); } else if (type == HERO_SYSTEM_TYPE.EQUIP) { reIncAttr = calEquipPutOnOffIncAttr(hero, args, addSeidList, removeSeidList); } else if (type == HERO_SYSTEM_TYPE.EQUIP_BASE) { reIncAttr = calHeroEquipIncAttr(hero); } else if (type == HERO_SYSTEM_TYPE.RESTRENGTHEN) { reIncAttr = calRestrengthenIncAttr(hero, args.shift(), args, addSeidList, removeSeidList); } else if (type == HERO_SYSTEM_TYPE.JEWEL_ON) {//宝石穿戴 reIncAttr = calHeroCeWhenJewelOn(hero, args); } else if (type == HERO_SYSTEM_TYPE.JEWEL_OFF) {//宝石卸下 reIncAttr = calHeroCeWhenJewelOff(hero, args); } else { reIncAttr = hero.ceAttr; } addSeidEffect(reIncAttr, hero.ceAttr, addSeidList, removeSeidList); // 处理加值 if(!hero.ceAttr) hero.ceAttr = new CeAttr(); for (let attrName in reIncAttr) { if(!reIncAttr[attrName]) continue; let originalAttrData: CeAttrData = hero.ceAttr[attrName]||new CeAttrData(); let originalGlobalAttrData: CeAttrData = globalCeAttr[attrName]||new CeAttrData(); let oldCe = (originalAttrData.fixUp + (originalAttrData.equipUp||0)) * HERO_CE_RATIO + originalAttrData.base *(HERO_CE_RATIO + originalAttrData.ratioUp + originalGlobalAttrData.ratioUp); if(!hero.ceAttr[attrName]) hero.ceAttr[attrName] = new CeAttrData(); for (let attrKey in reIncAttr[attrName]) { hero.ceAttr[attrName][attrKey] = parseInt(reIncAttr[attrName][attrKey]||0); } incArr[attrName] = (reIncAttr[attrName].fixUp + (reIncAttr[attrName].equipUp||0)) * HERO_CE_RATIO + reIncAttr[attrName].base *(HERO_CE_RATIO + reIncAttr[attrName].ratioUp + originalGlobalAttrData.ratioUp) - oldCe; //计算属性 incCe += incArr[attrName] * getAttrCeRatio(attrName); } hero.ce += incCe; if(hero.historyCe < hero.ce) hero.historyCe = hero.ce; return incCe; } //修改并下发战力 export async function calPlayerCeAndSave(roleId: string, heros: Array, type?: number, args?: Array) { if(!heros.length) heros = await HeroModel.findByRole(roleId); let incPlayerCe = 0; let pushHeros = new Array<{hid: number, ce: number, incHeroCe: number}>(); let role = await RoleModel.findByRoleId(roleId); if(!role.globalCeAttr) role.globalCeAttr = new CeAttr(); let reIncAttr: CeAttr = {}; // role表属性增量 if (type == HERO_SYSTEM_TYPE.INIT) { reIncAttr = calRoleInitIncAttr(heros, role.globalCeAttr); // 全局变量增 } else if (type == HERO_SYSTEM_TYPE.ADD_SKIN) { reIncAttr = calHeroAddSkin(args, role.globalCeAttr); } for (let attrName in reIncAttr) { role.globalCeAttr[attrName].fixUp = reIncAttr[attrName].fixUp; role.globalCeAttr[attrName].ratioUp = reIncAttr[attrName].ratioUp; } for (let hero of heros) { let incHeroCe = calPlayerCe(role.globalCeAttr, hero, type, args); incPlayerCe += incHeroCe; await HeroModel.updateHeroInfo(roleId, hero.hid, hero); pushHeros.push({ hid: hero.hid, ce: hero.ce, incHeroCe : incHeroCe, }); } role.ce += incPlayerCe; await RoleModel.updateRoleInfo(roleId, {globalCeAttr: role.globalCeAttr, ce: role.ce}); return {pushHeros, role} } // 初始战力 export function calHeroInitIncAttr(hero: HeroType, addSeidList: Array, removeSeidList: Array) { let res1 = calHeroStarIncAttr(hero, getAllAttrStage(), addSeidList, removeSeidList, true); let hero1 = combineHeroCeAttr(hero, res1); let curSkin = hero.skins.find(cur => cur.enable); let res2 = calHeroWearSkinIncAttr(hero1, [curSkin?curSkin.id:0, 0], addSeidList, removeSeidList, true); let hero2 = combineHeroCeAttr(hero, res2); calHeroJobStageUpIncAttr(hero2, [0], addSeidList, removeSeidList); let result: CeAttr = {}; combineAttrResult(result, res1); combineAttrResult(result, res2); return res1 } function combineAttrResult(target: CeAttr, origin: CeAttr) { for(let attrName in origin) { for(let attrKey in origin[attrName]) { if(!target.hasOwnProperty(attrName)) { target[attrName] = {}; } if(!target[attrName].hasOwnProperty(attrKey)) { target[attrName][attrKey] = 0; } if(origin[attrName][attrKey] > target[attrName][attrKey]) { target[attrName][attrKey] = origin[attrName][attrKey]; } } } } export function calRoleInitIncAttr(heros: HeroType[], globalCeAttr: CeAttr) { let args = new Array(); for(let hero of heros) { for(let skin of hero.skins) { args.push(skin.id); } } let res = calHeroAddSkin(args, globalCeAttr); return res; } // 将hero的ceAttr暂时更新,不更新在originalHero本体上 function combineHeroCeAttr(originalHero: HeroType, result: CeAttr) { let hero = deepCopy(originalHero); if(!hero.ceAttr) hero.ceAttr = new CeAttr(); for (let attrName in result) { if(!result[attrName]) continue; if(!hero.ceAttr[attrName]) hero.ceAttr[attrName] = new CeAttrData(); for (let attrKey in result[attrName]) { hero.ceAttr[attrName][attrKey] = parseInt(result[attrName][attrKey]||0); } } delete hero._id; return hero; } /** * * @param hero HeroType 武将更新后的值 * @param args number[] 参数,表示需要更新多少个维 * @param addSeidList number[] 用于更新被动 * @param removeSeidList number[] 用于更新被动 * @param isInit boolean 是否是初次创建武将 */ export function calHeroStarIncAttr (hero: HeroType, args: Array, addSeidList: Array, removeSeidList: Array, isInit = false) { let {star, starStage, quality, colorStar, colorStarStage, ceAttr, skins} = hero; let originStar = star, originColorStar = colorStar; let res: CeAttr = {}; const dicHero = gameData.hero.get(hero.hid); const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1 if(isWake) { if(colorStarStage == ABI_STAGE.START) originColorStar = colorStar - 1; } else { if(starStage == ABI_STAGE.START) originStar = star - 1; } const dicStar = isWake? getHeroWakeByQuality(quality, originColorStar): getHeroStarByQuality(quality, originStar); // 星级表 for(let stage of args) { let targetAttrId = getFieldByStage(stage, hero.job); // 转换为17维的属性id let heroAttr = dicHero.baseAbilityArr.get(targetAttrId); // 武将表hp等 let heroUpAttr = dicHero.baseAbilityUpArr.get(targetAttrId); // 武将表hp_up等 let starUp = 0; if (!!dicStar && !!dicStar.ceAttr) { starUp = dicStar.ceAttr.get(stage); } let newBase = (heroAttr + hero.lv * (heroUpAttr + starUp)) * HERO_CE_RATIO; let field = getAtrrNameById(targetAttrId); let ceAttrData: CeAttrData = ceAttr[field]||new CeAttrData(); // 存表中的属性下的base,fixup,ratioup let {ratioUp = 0, fixUp = 0} = ceAttrData; res[field] = { base: newBase, ratioUp, fixUp}; // base变动,增量为△base * ratio + 0 } // 解锁技能 let curSkin = skins.find(cur => cur.enable); let curSeidList = getSeidListOfFashion(curSkin.id, star, colorStar); let preSeidList = getSeidListOfFashion(curSkin.id, isInit?0:originStar, isInit?0:originColorStar); for(let [type, seid] of curSeidList) { if(!preSeidList.has(type)) { addSeidList.push(seid, 0); } } for(let [type, seid] of preSeidList) { console.log(type, seid) if(!curSeidList.has(type)) { removeSeidList.push(seid, 0); } } return res;//属性增量可以是多个 } function getSeidListOfFashion(fashionid: number, originStar: number, originColorStar: number) { let seidList = new Map(); // type => seid if(!gameData.fashion.has(fashionid)) return seidList; let { skillId } = gameData.fashion.get(fashionid); let { starSeidArr, colorStarSeidArr } = gameData.heroSkill.get(skillId); for(let {star, value, type} of starSeidArr) { if(originStar >= star) { seidList.set(type, value); } } for(let {star, value, type} of colorStarSeidArr) { if(originColorStar >= star) { seidList.set(type, value); } } return seidList } export function getAllAttrStage () { let attrs = new Array(); // 有升级的属性 1-hp 2-atk 3-def 4-mdef 5-agi 6-luk for(let stage = ABI_STAGE.START + 1; stage <= ABI_STAGE.END; stage++) { attrs.push(stage) }; return attrs; } //训练 export function calHeroTrainIncAttr(hero: HeroType) { let res: CeAttr = {}; let attrName: string = getAttrNameByJobStage(hero.jobStage); res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp}; let currentJob = gameData.job.get(hero.job); if (currentJob.grade > 1) { let jobGradeAndClass = getJobByGradeAndClass(currentJob.job_class, currentJob.grade - 1); let lastJob = gameData.job.get(jobGradeAndClass.jobid); res[attrName].fixUp += (currentJob[attrName] - lastJob[attrName]) * HERO_CE_RATIO; } else { res[attrName].fixUp += currentJob[attrName] * HERO_CE_RATIO; } return res; } //进阶 export function calHeroJobStageUpIncAttr(hero: HeroType, args: Array, addSeidList: Array, removeSeidList: Array) { let res: CeAttr = {}; let lastJob = gameData.job.get(args[0])||{seid:[]}; let currentJob = gameData.job.get(hero.job); for (let seid of currentJob.seid) { let index = _.findIndex(lastJob.seid, seid); if (index < 0) { addSeidList.push(seid, 0); } } for (let seid of lastJob.seid) { let index = _.findIndex(currentJob.seid, seid); if (index < 0) { removeSeidList.push(seid, 0); } } return res; } //穿戴时装 export function calHeroWearSkinIncAttr(hero: HeroType, args: Array, addSeidList: Array, removeSeidList: Array, isInit = false) { let res: CeAttr = {}; let addSkin = gameData.fashion.get(args[0]); let delSkin = gameData.fashion.get(args[1]); let attrName: string; if(delSkin) { for (let attr of delSkin.actorAttr) { attrName = getAtrrNameById(attr.id); res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp}; res[attrName].fixUp -= attr.number * HERO_CE_RATIO; } } for (let attr of addSkin.actorAttr) { attrName = getAtrrNameById(attr.id); res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp}; res[attrName].fixUp += attr.number * HERO_CE_RATIO; } if(!isInit) { // 初始的时候,这一段技能在calHeroStarIncAttr里计算了,不用重复算 let { star, colorStar } = hero; let curSeidList = getSeidListOfFashion(args[0], star, colorStar); let preSeidList = getSeidListOfFashion(args[1], star, colorStar); for(let [type, seid] of curSeidList) { if(!preSeidList.has(type)) { removeSeidList.push(seid, 0); } } for(let [type, seid] of preSeidList) { if(!curSeidList.has(type)) { addSeidList.push(seid, 0); } } } return res; } //羁绊解锁 export function calHeroConectIncAttr(hero: HeroType, args: Array) { let res: CeAttr = {}; let fiendShipLevel = gameData.friendShipLevelMap.get(hero.favourLv); let shipId = args[0];//当前升级的羁绊序号 let level = args[1];//当前升级的羁绊等级 let attrName: string; let currentShip = getFriendShipById(shipId, level); for (let attr of currentShip.attributes) { attrName = getAtrrNameById(attr.id); res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp}; res[attrName].fixUp += attr.number * (HERO_CE_RATIO + fiendShipLevel.add); } if (level > 1) { let lastShip = getFriendShipById(shipId, level - 1); for (let attr of lastShip.attributes) { attrName = getAtrrNameById(attr.id); res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp}; res[attrName].fixUp -= attr.number * (HERO_CE_RATIO + fiendShipLevel.add); } } return res; } //好感升级 export function calHeroFavourUpIncAttr(hero: HeroType, args: Array) { let res: CeAttr = {}; let currentFiendShipLevel = gameData.friendShipLevelMap.get(hero.favourLv); let difAdd = currentFiendShipLevel.add; if (!!args[0]) { let lastFiendShipLevel = gameData.friendShipLevelMap.get(args[0]); difAdd -= lastFiendShipLevel.add; } let attrName: string; for (let connect of hero.connections) { let heroShip = getFriendShipById(connect.shipId, connect.level); for (let attr of heroShip.attributes) { attrName = getAtrrNameById(attr.id); res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp}; res[attrName].fixUp += attr.number * (HERO_CE_RATIO + difAdd); } } return res; } // 穿脱, removeSeidList原来身上穿着的所有装备的seid,包括套装的 export function calEquipPutOnOffIncAttr(hero: HeroType, args: Array, addSeidList: Array, removeSeidList: Array) { // 计算身上所有装备的战力值(特技相关以外) let res = calHeroEquipIncAttr(hero); // 计算被动技能 let { ePlace } = hero; let suits = new Map(); for(let { equip } of ePlace) { if(equip) { let e = equip; for(let { seid, rand } of e.randSe) { addSeidList.push(seid, rand); } if(e.suitId > 0) { if(suits.has(e.suitId)) { suits.set(e.suitId, 1); } else { suits.set(e.suitId, suits.get(e.suitId) + 1); } } } } suits.forEach((suitId, count) => { let { effect } = gameData.suit.get(suitId); for(let e of effect) { if(count >= e.count) { addSeidList.push(e.seid, 0); } } }); for(let arg of args) { removeSeidList.push(arg) } return res } // 装备,装备栏升级,装备精炼等涉及到值的 export function calHeroEquipIncAttr(hero: HeroType) { let res: CeAttr = {}; let { ePlace } = hero; let attrResult = new CeAttrNumber(); for(let {equip, lv, refineLv} of ePlace) { if(equip) { let e = equip; let dicGoods = gameData.goods.get(e.id); let {goodsAbility, goodsAbilityUp} = dicGoods; let dicRefine = gameData.refine.get(refineLv); let jewel = new Map(); for(let {jewel: jewelId} of e.holes) { if(jewelId > 0) { let g = gameData.goods.get(jewelId); if(g) { let jGoods = g.goodsAbility; jGoods.forEach((value, key) => { if(jewel.has(key)) { jewel.set(key, value); } else { jewel.set(key, jewel.get(key) + value); } }) } } } for(let i = ABI_TYPE.ABI_HP; i < ABI_TYPE.ABI_MAX; i++) { if(i == ABI_TYPE.ABI_SPEED || i == ABI_TYPE.ABI_AP) continue; let attrName = getAtrrNameById(i); // console.log('***', i, attrName); let value1 = goodsAbility.get(i)||0 * (HERO_CE_RATIO + e.randRange); // console.log('基础值', value1); let valueup = goodsAbilityUp.get(i)||0; // console.log('成长', lv, valueup); let valueRefine = dicRefine?dicRefine.upPercent:0; // console.log('refine', dicRefine?dicRefine.upPercent:0 ); let valueJewel = jewel.get(i)||0; // console.log('jewel', valueJewel); let attr = (value1 + lv * valueup) * ( HERO_CE_RATIO + valueRefine) + valueJewel * HERO_CE_RATIO; attrResult[attrName] += attr; } } } for(let attrName in attrResult) { let originalCe = hero.ceAttr[attrName].equipUp||0; console.log('装备战力:', attrName, attrResult[attrName] * HERO_CE_RATIO, originalCe); res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp, equipUp: originalCe}; res[attrName].equipUp += attrResult[attrName] * HERO_CE_RATIO - originalCe; } return res; } // 洗炼 export function calRestrengthenIncAttr (hero: HeroType, ePaceId: number, args: Array, addSeidList: Array, removeSeidList: Array) { let res: CeAttr = {}; let {ePlace} = hero; let curPlace = ePlace.find(cur => cur.id == ePaceId); if(curPlace && curPlace.equip) { let e = curPlace.equip; for(let { seid, rand } of e.randSe) { addSeidList.push(seid, rand); } } for(let arg of args) { removeSeidList.push(arg) } return res } // 根据存在升星表等的stage字段的id对应17维id function getFieldByStage(stage: number, jobid: number) { let targetAttrId = ABI_TYPE_TO_STAGE.get(stage); if(typeof targetAttrId === 'number') { return targetAttrId } else { const dicJob = gameData.job.get(jobid); return targetAttrId(dicJob.type); } } // 添加技能增加的被动属性 function addSeidEffect(reIncAttr: CeAttr, heroCeAttr: CeAttr,addSeidList: Array, removeSeidList: Array) { console.log('addSeidList', addSeidList) console.log('removeSeidList', removeSeidList) let otiginalSeidList = [ {list: addSeidList, multi: 1}, {list: removeSeidList, multi: -1} ]; for(let {list, multi} of otiginalSeidList) { let effectList = new Array(); // any: dic_zyz_se表内容 for(let ii = 0; ii < list.length; ii += 2 ) { let seid = list[ii]; let rand = list[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) } } for(let {type, gainValueArr: [ability, value]} of effectList) { let attrName = getAtrrNameById(ability); if(!attrName) continue; if(type == SEID_TYPE.TYPE101) { // 加值 if(!reIncAttr[attrName]) { reIncAttr[attrName] = deepCopy(heroCeAttr[attrName]); } if(!reIncAttr[attrName]) { delete reIncAttr[attrName]; continue; } reIncAttr[attrName].fixUp += value * multi * HERO_CE_RATIO; delete reIncAttr[attrName]._id; } else if (type == SEID_TYPE.TYPE102) { // 加百分比 if(!reIncAttr[attrName]) { reIncAttr[attrName] = deepCopy(heroCeAttr[attrName]); } if(!reIncAttr[attrName]) { delete reIncAttr[attrName]; continue; } reIncAttr[attrName].ratioUp += value * multi; delete reIncAttr[attrName]._id; } } } } // 获取dic_zyz_se内容 function addSeid(effectList: Array, seidId:number, rand: number, seidValue = new Array()){ // console.log('addSeidEffect', seidId, seidValue) 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; } effectList.push(curSeid); let seid: DicSe|DicRandomEffectPool = deepCopy(curSeid); if(curSeid.index > 0) { seid.gainValueArr[curSeid.index - 1] = rand; } effectList.push(seid); } function calHeroCeWhenJewelOn(hero: HeroType, args: Array) { let res: CeAttr = {}; let id = args[0]; let oldId = args[1]; let goodInfo = getGoodById(id); let oldGoodInfo; if (!!oldId) oldGoodInfo = getGoodById(oldId); for (let attrName in JEWEL_ATTR) { if (!!goodInfo[attrName]) { res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp}; res[attrName].fixUp += goodInfo[attrName]; if (oldGoodInfo) res[attrName].fixUp -= oldGoodInfo[attrName]; } } return res; } function calHeroCeWhenJewelOff(hero: HeroType, args: Array) { let res: CeAttr = {}; for (let id of args) { let goodInfo = getGoodById(id); for (let attrName in JEWEL_ATTR) { if (!!goodInfo[attrName]) { res[attrName] = {fixUp: hero.ceAttr[attrName].fixUp, base: hero.ceAttr[attrName].base, ratioUp: hero.ceAttr[attrName].ratioUp}; res[attrName].fixUp -= goodInfo[attrName]; } } } return res; } //全局属性加成 export async function reCalAllHeroCe(roleId: string, type: number, args:Array) { let reIncAttr: CeAttr = {}; let role = await RoleModel.findByRoleId(roleId); if(!role.globalCeAttr) role.globalCeAttr = new CeAttr(); let originalAttr = role.globalCeAttr; let pushHeros:Array<{hid:number, ce:number, incHeroCe:number}> = [] if (type == 1) {//获得皮肤 reIncAttr = calHeroAddSkin(args, role.globalCeAttr); } for (let attrName in reIncAttr) { role.globalCeAttr[attrName].fixUp = reIncAttr[attrName].fixUp; role.globalCeAttr[attrName].ratioUp = reIncAttr[attrName].ratioUp; } let heros = await HeroModel.findByRole(roleId); for (let hero of heros) { let incHeroCe = 0; for (let attrName in reIncAttr) { let oldcCe = originalAttr[attrName].fixUp * HERO_CE_RATIO + hero.ceAttr[attrName].base * (HERO_CE_RATIO + originalAttr[attrName].ratioUp); let incArr = role.globalCeAttr[attrName].fixUp * HERO_CE_RATIO + hero.ceAttr[attrName].base * (HERO_CE_RATIO + role.globalCeAttr[attrName].ratioUp) - oldcCe; incHeroCe += incArr * getAttrCeRatio(attrName); } incHeroCe += incHeroCe; hero.ce += incHeroCe; pushHeros.push({ hid: hero.hid, ce: hero.ce, incHeroCe }); await HeroModel.updateHeroInfo(roleId, hero.hid, {ce: hero.ce}); } await RoleModel.updateRoleInfo(roleId, {globalCeAttr: role.globalCeAttr, ce: role.ce}); return {pushHeros, ce: role.ce} } function calHeroAddSkin(args:Array, ceAttr: CeAttr){ let res: CeAttr = {}; for (let arg of args) { let addSkin = gameData.fashion.get(arg); let attrName: string; for (let attr of addSkin.globalAttr) { attrName = getAtrrNameById(attr.id); res[attrName] = {fixUp: ceAttr[attrName].fixUp, ratioUp: ceAttr[attrName].ratioUp}; res[attrName].fixUp += attr.number * HERO_CE_RATIO; } } return res; }