/** * 体力系统 */ import { HERO_SYSTEM_TYPE } from '../consts'; import { deepCopy } from './util'; import { HeroModel, HeroType } from '../db/Hero'; import { RoleModel } from '../db/Role'; import { CeAttrData, CeAttr } from '../db/generalField'; import { getAttrNameByJobStage, getAttrCeRatio, getAtrrNameById, ABI_TYPE_TO_STAGE, ABI_STAGE, SEID_TYPE, HERO_ATTR} from '../consts'; import { gameData, getJobByGradeAndClass, getHeroWakeByQuality, getHeroStarByQuality, getFriendShipById } from './data'; import { Attributes } from './interface'; import { DicSe } from './dictionary/DicSe'; const HERO_CE_RATIO = 100; const _ = require('underscore'); //战力计算TODO export function calPlayerCe(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.STAR) { reIncAttr = calHeroStarIncAttr(hero, args, addSeidList); // 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 = calWaerHeroSkinIncAttr(hero, args); } else if (type == HERO_SYSTEM_TYPE.FAVOUR) { reIncAttr = calHeroFavourUpIncAttr(hero, args); } else if (type == HERO_SYSTEM_TYPE.CONNECT) { reIncAttr = calHeroConectIncAttr(hero, args); } addSeidEffect(reIncAttr, addSeidList, removeSeidList); // 处理加值 if(!hero.ceAttr) hero.ceAttr = new CeAttr(); for (let attrName in reIncAttr) { let originalAttrData: CeAttrData = hero.ceAttr[attrName]||new CeAttrData(); let oldCe = originalAttrData.fixUp * HERO_CE_RATIO + originalAttrData.base *(HERO_CE_RATIO + originalAttrData.ratioUp) if(!hero.ceAttr[attrName]) hero.ceAttr[attrName] = new CeAttrData(); for (let attrKey in reIncAttr[attrName]) { hero.ceAttr[attrName][attrKey] = parseInt(reIncAttr[attrName][attrKey]); } incArr[attrName] = reIncAttr[attrName].fixUp * HERO_CE_RATIO + reIncAttr[attrName].base *(HERO_CE_RATIO + reIncAttr[attrName].ratioUp) - oldCe; //计算属性 incCe += incArr[attrName] * getAttrCeRatio(attrName); } hero.ce += incCe; return incCe; } //修改并下发战力 export async function calPlayerCeAndSave(roleId: string, heros: Array, type?: number, args?: Array) { let incPlayerCe = 0; let pushHeros = new Array<{hid: number, ce: number, incHeroCe: number}>(); for (let hero of heros) { let incHeroCe = calPlayerCe(hero, type, args); incPlayerCe += incHeroCe; await HeroModel.updateHeroInfo(roleId, hero.hid, hero ); pushHeros.push({ hid: hero.hid, ce: hero.ce, incHeroCe : incHeroCe, }); } let role = await RoleModel.findByRoleId(roleId); role.ce += incPlayerCe; await RoleModel.updateRoleInfo(roleId, role); return {pushHeros, role} } export function calHeroStarIncAttr (hero: HeroType, args: Array, addSeidList: Array) { let {star, starStage, quality, colorStar, colorStarStage, ceAttr} = hero; let res: CeAttr = {}; const dicHero = gameData.hero.get(hero.hid); const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1 if(isWake) { if(colorStarStage == ABI_STAGE.START) colorStar = colorStar -1; } else { if(starStage == ABI_STAGE.START) star = star -1; } const dicStar = isWake? getHeroWakeByQuality(quality, colorStar): getHeroStarByQuality(quality, star); // 星级表 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 = 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 } // 解锁技能 if(dicHero.skill){ let {starSeidArr, colorStarSeidArr} = gameData.heroSkill.get(dicHero.skill); if(isWake) { for(let {star, value} of starSeidArr){ if(hero.star == star){ addSeidList.push(value); } } } else { for(let {star, value} of colorStarSeidArr){ if(hero.colorStar == star){ addSeidList.push(value); } } } } return res;//属性增量可以是多个 } 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]); let currentJob = gameData.job.get(hero.job); addSeidList.concat(deepCopy(currentJob.seid)); for (let seid of lastJob.seid) { let index = _.indexOf(currentJob.seid, seid); if (index > 0) { addSeidList.splice(index, 1); } else { removeSeidList.push(seid); } } return res; } //穿戴时装 export function calWaerHeroSkinIncAttr(hero: HeroType, args: Array) { let res: CeAttr = {}; let addSkin = gameData.fashion.get(args[0]); let delSkin = gameData.fashion.get(args[1]); let attrName: string; 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; } 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; } // 根据存在升星表等的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, addSeidList: Array, removeSeidList: Array) { 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 seid of list) { let dicSeid = gameData.se.get(seid); if(dicSeid && dicSeid.id > 0){ addSeid(effectList, dicSeid.id, dicSeid.gainValueArr) } } for(let {type, gainValueArr: [ability, value]} of effectList) { if(type == SEID_TYPE.TYPE101) { // 加值 if(!reIncAttr[HERO_ATTR[ability]]) { reIncAttr[HERO_ATTR[ability]] = new CeAttrData(); } reIncAttr[HERO_ATTR[ability]].fixUp += value * multi * HERO_CE_RATIO; } else if (type == SEID_TYPE.TYPE102) { // 加百分比 if(!reIncAttr[HERO_ATTR[ability]]) { reIncAttr[HERO_ATTR[ability]] = new CeAttrData(); } reIncAttr[HERO_ATTR[ability]].ratioUp += value * multi; } } } } // 获取dic_zyz_se内容 function addSeid(effectList: Array, seidId:number, seidValue = new Array()){ // console.log('addSeidEffect', seidId, seidValue) let curSeid = gameData.se.get(seidId); if(!curSeid) {console.log("seidId not found:"+seidId);return;} if(!seidValue) seidValue = curSeid.gainValueArr; if(curSeid.type === 999){ for(let i = 0;i < seidValue.length;i++){ addSeid(effectList, seidValue[i]); } return; } effectList.push(curSeid); }