// /** // * 体力系统 // */ import { HERO_SYSTEM_TYPE, ABI_TYPE, HERO_CE_RATIO, LINEUP_NUM, TALENT_RELATION_TYPE } from '../consts'; import { HeroModel, HeroType, HeroUpdate, CeAttrData, EPlace, Stone, Talent } from '../db/Hero'; import { RoleModel, RoleType, RoleUpdate, CeAttrDataRole } from '../db/Role'; import { AttributeCal } from '../domain/roleField/attribute'; import { ABI_STAGE, SEID_TYPE } from '../consts'; import { gameData, getJobByGradeAndClass, getHeroWakeByQuality, getHeroStarByQuality, getFriendShipById, getSchoolRateByStar, getScollByStar, getTeraph, getEquipQualityIdByEquipIdAndPoint, getEquipSuitByHero, getEquipStarAttrByStage, getJewelConditionByLvAndSeId } from './data'; import { DicSe } from './dictionary/DicSe'; import { DicRandomEffectPool } from './dictionary/DicRandomEffectPool'; import { SchoolModel } from '../db/School'; import { ABI_TYPE_MAIN, ABI_JOB_STAGE, ABI_STAGE_TO_TYPE } from '../consts/constModules/abilityConst' import { PvpDefenseModel } from '../db/PvpDefense'; import { findIndex } from 'underscore'; import { GuildModel } from '../db/Guild'; import { DicJob } from './dictionary/DicJob'; import { saveCeChangeLog } from './logUtil'; import { JewelType } from '../db/Jewel'; // import { type } from 'os'; // // 修改并下发战力 // export async function calPlayerCeAndSave(type: number, roleId: string, originHero: HeroType, update: HeroUpdate, args?: Array, params?: any) { // let role = await RoleModel.findByRoleId(roleId); // let { attr: roleAttrs = [], serverId } = role; // let heroAttrs = await calPlayerCe(originHero, update, type, args, params); // 根据操作计算attr的增加 // let newAttr = new AttributeCal(); // newAttr.setLv(update.lv||originHero.lv); // newAttr.setByDbData(roleAttrs, heroAttrs); // let heroCe = newAttr.calCe(); // 计算最终战力 // let incCe = heroCe - originHero.ce; // // 更新到武将 // update.attr = heroAttrs; // update.ce = heroCe; // if (originHero.historyCe < heroCe) update.historyCe = heroCe; // let hero = await HeroModel.updateHeroInfo(roleId, originHero.hid, update, null, true); // 更新武将 返回是战力缩过的 // // 更新到角色 // let { topLineup, topLineupCe } = await calculatetopLineup(role, originHero.hid, heroCe, originHero._id); // 计算更新最强五人战力 // role = await RoleModel.updateRoleInfo(roleId, { ce: role.ce + incCe, topLineup, topLineupCe }); // await PvpDefenseModel.updateCe(roleId, originHero.hid, reduceCe(incCe)); // 更新pvp防守阵战力 // let guild = await GuildModel.updateCe(roleId, incCe); // 公会更新战力 // let pushHeros = new Array<{ hid: number, ce: number, incHeroCe: number }>(); // pushHeros.push({ // hid: originHero.hid, // ce: reduceCe(heroCe), // incHeroCe: reduceCe(incCe), // }); // saveCeChangeLog(role, incCe, role.ce, type, [originHero.hid]); // return { pushHeros, role, topLineupCe, hero, guild, serverId } // } // //全局属性加成 // export async function reCalAllHeroCe(type: number, roleId: string, update: RoleUpdate, args?: Array, params?: any) { // let role = await RoleModel.findByRoleId(roleId); // let heros = await HeroModel.findByRole(roleId); // let roleAttrs = await reCalRoleAttr(type, heros, role, update, args, params); // if(!roleAttrs) return {role, pushHeros: [], ce: role.ce, topLineupCe: role.topLineupCe, serverId: role.serverId, heros }; // 无加成 // let pushHeros = new Array<{ hid: number, ce: number, incHeroCe: number }>(); // let allIncCe = 0; // let resultHeroes = []; // for (let hero of heros) { // let { attr: heroAttrs, lv } = hero; // let newAttr = new AttributeCal(); // newAttr.setLv(lv); // newAttr.setByDbData(roleAttrs, heroAttrs); // let heroCe = newAttr.calCe(); // 计算最终战力 // if(heroCe != hero.ce) { // let incHeroCe = heroCe - hero.ce; // allIncCe += incHeroCe; // pushHeros.push({ hid: hero.hid, ce: reduceCe(heroCe), incHeroCe: reduceCe(incHeroCe) }); // let resultHero = await HeroModel.updateHeroInfo(roleId, hero.hid, { ce: heroCe }); // resultHeroes.push(resultHero); // await PvpDefenseModel.updateCe(roleId, hero.hid, reduceCe(incHeroCe)); // 更新pvp防守阵战力 // } else { // resultHeroes.push(hero); // } // } // let { topLineup, topLineupCe } = await calculatetopLineup(role); // 计算更新最强五人战力 // if(allIncCe != 0) { // update.attr = roleAttrs; // update.topLineup = topLineup; // update.topLineupCe = topLineupCe; // } // // console.log('************ roleAttr', update.attr) // role = await RoleModel.incRoleInfo(roleId, { ce: allIncCe },update); // let guild = await GuildModel.updateCe(roleId, allIncCe); // 公会更新战力 // saveCeChangeLog(role, allIncCe, role.ce, type, args); // return { role, pushHeros, ce: role.ce, topLineupCe: role.topLineupCe, guild, serverId: role.serverId, heros: resultHeroes } // } // // 计算武将全局战力 // async function reCalRoleAttr(type: number, heros: Array, role: RoleType, update: RoleUpdate, args: Array, params: any) { // let { attr: roleAttrs } = role; // switch (type) { // case HERO_SYSTEM_TYPE.ADD_SKIN: // roleAttrs = calHeroAddSkin(role, args); // break; // case HERO_SYSTEM_TYPE.SCHOOL: // roleAttrs = calSchoolAddAttr(role, heros, args[0], args[1], args[2]); // break; // case HERO_SYSTEM_TYPE.SCROLL: // roleAttrs = calScrollAddAttr(role, heros, args[0]); // break; // case HERO_SYSTEM_TYPE.STAR: // case HERO_SYSTEM_TYPE.COLORSTAR: // case HERO_SYSTEM_TYPE.QUALITY: // roleAttrs = await calSchoolStarIncAttr(role, heros, type, args[0], args[1]); // break; // case HERO_SYSTEM_TYPE.TITLE: // roleAttrs = calTitle(role, update); // break; // case HERO_SYSTEM_TYPE.TERAPH: // roleAttrs = calTeraphMainAttr(role, update, args[0]); // break; // case HERO_SYSTEM_TYPE.TERAPH_UP: // roleAttrs = calTeraphAssistAttr(role, update, args[0]); // break; // case HERO_SYSTEM_TYPE.REBIRTH: // roleAttrs = await calHeroRebirth(role, params.originHero, params.heroUpdate); // break; // } // return roleAttrs; // } // // 计算单个武将战力 // export async function calPlayerCe(hero: HeroType, update: HeroUpdate, type: number, args: Array = [], params) { // let heroAttrs: CeAttrData[] = []; // {"hp": {"base": number, "fixUp": number, "ratioUp": number}} // let addSeidList = new Array(); // let removeSeidList = new Array(); // switch (type) { // case HERO_SYSTEM_TYPE.STAR: // case HERO_SYSTEM_TYPE.LVUP: // case HERO_SYSTEM_TYPE.COLORSTAR: // case HERO_SYSTEM_TYPE.QUALITY: // heroAttrs = calHeroStarIncAttr(hero, update, type, addSeidList, removeSeidList); // args: 升的星盘 // break; // case HERO_SYSTEM_TYPE.TRAIN: // heroAttrs = calHeroTrainIncAttr(hero, update); // break; // case HERO_SYSTEM_TYPE.STAGEUP: // // heroAttrs = calHeroJobStageUpIncAttr(hero, update, addSeidList, removeSeidList); // break; // case HERO_SYSTEM_TYPE.SKIN: // heroAttrs = calHeroWearSkinIncAttr(hero, update, addSeidList, removeSeidList); // break; // case HERO_SYSTEM_TYPE.FAVOUR: // heroAttrs = calHeroFavourUpIncAttr(hero, update); // break; // case HERO_SYSTEM_TYPE.CONNECT: // heroAttrs = calHeroConectIncAttr(hero, update, args[0]); // break; // case HERO_SYSTEM_TYPE.COMPOSE_EQUIP: // heroAttrs = calComposeEquipIncAttr(hero, update, args[0]); // break; // case HERO_SYSTEM_TYPE.EQUIP_STRENGTH: // heroAttrs = calEquipStrengthIncAttr(hero, update, args); // break; // case HERO_SYSTEM_TYPE.EQUIP_QUALITY: // heroAttrs = calEquipQualityIncAttr(hero, update, args); // break; // case HERO_SYSTEM_TYPE.EQUIP_STAR: // heroAttrs = calEquipStarIncAttr(hero, update, args, addSeidList, removeSeidList); // break; // case HERO_SYSTEM_TYPE.EQUIP_JEWEL: // heroAttrs = calEquipPutOnOrOffJewelIncAttr(hero, update, args, params, addSeidList, removeSeidList); // break; // case HERO_SYSTEM_TYPE.EQUIP_STONE: // heroAttrs = calEquipPutOnOrOffStoneIncAttr(hero, update, args, params, addSeidList, removeSeidList); // break; // case HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE: // case HERO_SYSTEM_TYPE.JEWEL_QUENCH: // heroAttrs = calJewelResetRandSeIncAttr(hero, args, params, addSeidList, removeSeidList); // break; // case HERO_SYSTEM_TYPE.SCROLL: // heroAttrs = calHeroCeScrollIncAttr(hero, update); // break; // case HERO_SYSTEM_TYPE.TALENT: // heroAttrs = calHeroTalent(hero, update, addSeidList, removeSeidList); // break; // default: // break; // } // addSeidEffect(heroAttrs, addSeidList, removeSeidList); // 处理加值 // return heroAttrs; // } // /** // * 添加皮肤全局加成 // * @param args // * @param ceAttr // */ // function calHeroAddSkin(role: RoleType, skinIds: Array) { // let { attr: roleAttrs } = role; // for (let id of skinIds) { // let addSkin = gameData.fashion.get(id); // for (let attr of addSkin.globalAttr) { // let fixUp = attr.number * HERO_CE_RATIO; // updateRoleAttr(roleAttrs, attr.id, { inc: { fixUp } }); // } // } // role.attr = roleAttrs; // return roleAttrs; // } // /** // * 升星觉醒升品等 // * @param {HeroType} hero 武将更新前的值 // * @param {HeroUpdate} update 更新的值 // * @param {number} type 养成类型 // * @param {number[]} addSeidList 用于更新被动 // * @param {number[]} removeSeidList 用于更新被动 // */ // export function calHeroStarIncAttr(originHero: HeroType, update: HeroUpdate, type: number, addSeidList: Array, removeSeidList: Array) { // let { star: originStar, starStage: originStarStage, quality: originQuality, colorStar: originColorStar, colorStarStage: originColorStarStage, attr: heroAttrs, skinId: originSkinId, lv: oldLv } = originHero; // let { star = originStar, starStage = originStarStage, quality = originQuality, colorStar = originColorStar, colorStarStage = originColorStarStage, skinId = originSkinId, lv = oldLv } = update; // const dicHero = gameData.hero.get(skinId); // const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1 // const isFirstWake = colorStar > 0 && originColorStar <= 0; // 是否是初次觉醒 // const isUpStar = originStar != star || originColorStar != colorStar; // 是否有升星 // // console.log('*isUpstar', isUpStar, originStar, star, originColorStar, colorStar) // if(starStage == ABI_STAGE.START) star--; // if(colorStarStage == ABI_STAGE.START) colorStar--; // const dicStar = isWake ? getHeroWakeByQuality(dicHero.jobClass, dicHero.quality, colorStar) : getHeroStarByQuality(dicHero.jobClass, quality, star); // 星级表 // let stages = new Array(); // 需要升级的阶 // if (type == HERO_SYSTEM_TYPE.LVUP) { // stages = getAllAttrStage(); // } else if (type == HERO_SYSTEM_TYPE.STAR) { // let end = isUpStar? ABI_STAGE.END: starStage; // if(end < originStarStage) { // stages = getAllAttrStage(); // } else { // for(let i = originStarStage; i < end; i++) { // stages.push(i + 1); // } // } // } else if (type == HERO_SYSTEM_TYPE.QUALITY) { // stages = getAllAttrStage(); // } else if (type = HERO_SYSTEM_TYPE.COLORSTAR) { // if (isFirstWake) { // 首次觉醒 // stages = getAllAttrStage(); // } else { // let end = isUpStar? ABI_STAGE.END: colorStarStage; // if(end < originColorStarStage) { // stages = getAllAttrStage(); // } else { // for(let i = originColorStarStage; i < end; i++) { // stages.push(i + 1); // } // } // } // } else if (type == HERO_SYSTEM_TYPE.SKIN) { // stages = getAllAttrStage(); // } // for (let stage of stages) { // let targetAttrId = ABI_STAGE_TO_TYPE.get(stage); // 转换为18维的属性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 + lv * (heroUpAttr + starUp)) * HERO_CE_RATIO; // updateHeroAttr(heroAttrs, targetAttrId, { set: { base: newBase } }); // } // let curSeidList = getSeidListOfFashion(skinId, star, colorStar); // let preSeidList = getSeidListOfFashion(originSkinId, originStar, originColorStar); // curSeidList.forEach((seid, type) => { // if (!preSeidList.has(type)) { // addSeidList.push(seid, 0); // } // }); // preSeidList.forEach((seid, type) => { // if (!curSeidList.has(type)) { // removeSeidList.push(seid, 0); // } // }); // originHero.attr = heroAttrs; // return heroAttrs;//属性增量可以是多个 // } // type updateCeAttr = Partial; // function updateHeroAttr(heroAttrs: CeAttrData[], id: number, update: { inc?: updateCeAttr, set?: updateCeAttr }) { // let index = heroAttrs.findIndex(cur => cur.id == id); // let curAttr = heroAttrs[index]; // if(!curAttr) { // curAttr = new CeAttrData(id); // heroAttrs.push(curAttr); // index = heroAttrs.length - 1; // } // if(update.inc) { // let { base, equipUp, fixUp, ratioUp } = update.inc; // if(base != undefined) curAttr.base += base; // if(equipUp != undefined) curAttr.equipUp += equipUp; // if(fixUp != undefined) curAttr.fixUp += fixUp; // if(ratioUp != undefined) curAttr.ratioUp += ratioUp; // } // if(update.set) { // let { base, equipUp, fixUp, ratioUp } = update.set; // if(base != undefined) curAttr.base = base; // if(equipUp != undefined) curAttr.equipUp = equipUp; // if(fixUp != undefined) curAttr.fixUp = fixUp; // if(ratioUp != undefined) curAttr.ratioUp = ratioUp; // } // if(curAttr.base <= 0 && curAttr.equipUp <=0 && curAttr.fixUp <=0 && curAttr.ratioUp <= 0) { // heroAttrs.splice(index, 1); // } // } // type updateCeAttrRole = Partial; // function updateRoleAttr(roleAttrs: CeAttrDataRole[], id: number, update: { inc?: updateCeAttrRole, set?: updateCeAttrRole }) { // let curAttr = roleAttrs.find(cur => cur.id == id); // if(!curAttr) { // curAttr = new CeAttrDataRole(id); // roleAttrs.push(curAttr); // } // if(update.inc) { // let { fixUp, ratioUp } = update.inc; // if(fixUp) curAttr.fixUp = cal.add(curAttr.fixUp, fixUp); // if(ratioUp) curAttr.ratioUp = cal.add(curAttr.ratioUp, ratioUp); // } // if(update.set) { // let { fixUp, ratioUp } = update.set; // if(fixUp) curAttr.fixUp = fixUp; // if(ratioUp) curAttr.ratioUp = ratioUp; // } // } // /** // * 获取皮肤上的seid // * @param skinId // * @param originStar // * @param originColorStar // */ // function getSeidListOfFashion(skinId: number, originStar: number, originColorStar: number) { // 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 (originStar >= star) { // seidList.set(type, value); // } // } // for (let { star, value, type } of colorStarSeidArr) { // if (originColorStar >= star) { // seidList.set(type, value); // } // } // return seidList // } // /** // * 兵种训练 // * @param {HeroType} originHero 原始武将 // * @param {HeroUpdate} update 更新的数据 // */ // export function calHeroTrainIncAttr(originHero: HeroType, update: HeroUpdate) { // let { attr: heroAttrs, job: oldJob, jobStage: oldJobStage } = originHero; // let { job = oldJob, jobStage = oldJobStage } = update; // let dicJob = gameData.job.get(job); // let lastJob = getJobByGradeAndClass(dicJob.job_class, dicJob.grade - 1); // let dicLastJob = lastJob? gameData.job.get(lastJob.jobid): null; // for(let i = 1; i <= dicJob.maxStage; i++) { // if(oldJobStage < i && jobStage >= i) { // let lastAttr = dicLastJob? dicLastJob.ceAttr.get(i).attr: 0; // let targetAttrId = dicJob.ceAttr.get(i).id; // let targetAttrValue = dicJob.ceAttr.get(i).attr; // let inc = (targetAttrValue - lastAttr) * HERO_CE_RATIO; // // console.log('*******', targetAttrId, targetAttrValue, lastAttr, inc ) // updateHeroAttr(heroAttrs, targetAttrId, { inc: { fixUp: inc } }); // } // } // return heroAttrs; // } // /** // * 兵种进阶 // * @param {HeroType} originHero 原始武将 // * @param {HeroUpdate} update 更新内容 // * @param {number[]} addSeidList 用于更新被动 // * @param {number[]} removeSeidList 用于更新被动 // */ // // export function calHeroJobStageUpIncAttr(originHero: HeroType, update: HeroUpdate, addSeidList: Array, removeSeidList: Array) { // // let { job: oldJob, attr: heroAttrs } = originHero; // // let { job = oldJob } = update; // // let lastJob = gameData.job.get(oldJob); // // let currentJob = gameData.job.get(job); // // let lastSeids = lastJob?.seid||new Array(); // // let curSeids = currentJob?.seid||new Array(); // // for (let seid of curSeids) { // // let index = findIndex(lastSeids, seid); // // if (index < 0) { // // addSeidList.push(seid, 0); // // } // // } // // for (let seid of lastSeids) { // // let index = findIndex(curSeids, seid); // // if (index < 0) { // // removeSeidList.push(seid, 0); // // } // // } // // return heroAttrs; // // } // /** // * 初始计算兵种属性 // * @param {HeroType} originHero 原始武将 // * @param {HeroUpdate} hero 更新后的武将 // * @param {number[]} addSeidList 用于更新被动 // * @param {number[]} removeSeidList 用于更新被动 // */ // export function calHeroJobAttr(originHero: HeroType, hero: HeroUpdate, addSeidList: Array, removeSeidList: Array) { // let { attr: heroAttrs } = originHero; // let currentJob = gameData.job.get(hero.job); // let jobGradeAndClass = getJobByGradeAndClass(currentJob.job_class, currentJob.grade - 1); // let lastJob: DicJob; // if (!!jobGradeAndClass) { // lastJob = gameData.job.get(jobGradeAndClass.jobid); // } // for (let stage = ABI_JOB_STAGE.START; stage <= ABI_JOB_STAGE.END; stage++) { // if(hero.jobStage >= stage) { // let targetAttrId = currentJob.ceAttr.get(stage).id; // let fixUp = currentJob.ceAttr.get(stage).attr * HERO_CE_RATIO; // updateHeroAttr(heroAttrs, targetAttrId, { inc: { fixUp }}) // } else { // if(lastJob) { // let targetAttrId = lastJob.ceAttr.get(stage).id; // let fixUp = lastJob.ceAttr.get(stage).attr * HERO_CE_RATIO; // updateHeroAttr(heroAttrs, targetAttrId, { inc: { fixUp } }); // } // } // }; // originHero.attr = heroAttrs; // // heroAttrs = calHeroJobStageUpIncAttr(originHero, hero, addSeidList, removeSeidList); // return heroAttrs; // } // /** // * 穿戴时装的单武将加成 // * @param {HeroType} originHero 原始武将 // * @param {number} wearSkinId 穿戴的皮肤 // * @param {number} pullSkinId 脱下的皮肤 // * @param {number[]} addSeidList 用于更新被动 // * @param {number[]} removeSeidList 用于更新被动 // * @param {boolean} isInit 是否是计算初始战力 // */ // export function calHeroWearSkinIncAttr(originHero: HeroType, update: HeroUpdate, addSeidList: number[], removeSeidList: number[]) { // let { attr: heroAttrs, skinId: originSkinId } = originHero; // let { skinId = originSkinId, ePlace: newEplace } = update; // calHeroStarIncAttr(originHero, update, HERO_SYSTEM_TYPE.SKIN, addSeidList, removeSeidList); // let addSkin = gameData.fashionBySkinId.get(skinId); // let delSkin = gameData.fashionBySkinId.get(originSkinId); // if (delSkin) { // for (let attr of delSkin.actorAttr) { // let fixUp = -1 * attr.number * HERO_CE_RATIO; // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp } }); // } // } // for (let attr of addSkin.actorAttr) { // let fixUp = attr.number * HERO_CE_RATIO; // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp } }); // } // originHero.attr = heroAttrs; // let eplaceIds = newEplace.map(cur => cur.id); // calEquipStrengthIncAttr(originHero, update, eplaceIds); // calEquipQualityIncAttr(originHero, update, eplaceIds); // calEquipStarIncAttr(originHero, update, eplaceIds, addSeidList, removeSeidList); // // 天赋点 // calHeroTalent(originHero, update, addSeidList, removeSeidList); // return heroAttrs; // } // /** // * 羁绊解锁 // * @param {HeroType} originHero 原始武将 // * @param {HeroUpdate} update 更新数据 // * @param {number} shipId 解锁的那个id // */ // export function calHeroConectIncAttr(originHero: HeroType, update: HeroUpdate, shipId: number) { // let { connections: oldConnections = [], favourLv, attr: heroAttrs } = originHero; // let { connections = oldConnections } = update; // let oldConnect = oldConnections.find(cur => cur.shipId == shipId); // let connect = connections.find(cur => cur.shipId == shipId); // let oldLevel = oldConnect?.level||0; // let level = connect?.level||0; // let fiendShipLevel = gameData.friendShipLevelMap.get(favourLv); // let currentShip = getFriendShipById(shipId, level); // if (currentShip) { // for (let attr of currentShip.attributes) { // let fixUp = attr.number * (HERO_CE_RATIO + fiendShipLevel.add); // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp } }); // } // } // if (level > 1) { // let lastShip = getFriendShipById(shipId, oldLevel); // if (lastShip) { // for (let attr of lastShip.attributes) { // let fixUp = -1 * attr.number * (HERO_CE_RATIO + fiendShipLevel.add); // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp } }) // } // } // } // originHero.attr = heroAttrs; // return heroAttrs; // } // /** // * 好感度升级,影响羁绊加成 // * // * @param {HeroType} originHero 原始武将数据 // * @param {HeroUpdate} update 更新的数据 // */ // export function calHeroFavourUpIncAttr(originHero: HeroType, update: HeroUpdate) { // let { favourLv: oldFavourLv, attr: heroAttrs } = originHero; // let { favourLv = oldFavourLv } = update; // let currentFiendShipLevel = gameData.friendShipLevelMap.get(favourLv); // let difAdd = currentFiendShipLevel.add; // if (oldFavourLv && oldFavourLv > 0) { // 减上一级好感 // let lastFiendShipLevel = gameData.friendShipLevelMap.get(oldFavourLv); // difAdd -= lastFiendShipLevel.add; // } // for (let {shipId, level} of originHero.connections) { // let dicHeroFriendShip = getFriendShipById(shipId, level); // for (let attr of dicHeroFriendShip.attributes) { // let fixUp = (attr.number + difAdd ) * HERO_CE_RATIO; // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp } }); // } // } // originHero.attr = heroAttrs; // return heroAttrs; // } // export function calComposeEquipIncAttr(hero: HeroType, update: HeroUpdate, eplaceId: number) { // let { attr: heroAttrs } = hero; // let newEquip = update.ePlace.find(cur => cur.id == eplaceId); // if(newEquip) { // let dicEquip = gameData.equipById.get(newEquip.equipId); // for(let attr of dicEquip.attribute) { // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: attr.num * HERO_CE_RATIO } }); // } // } // return heroAttrs; // } // export function calEquipStrengthIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[]) { // let { attr: heroAttrs, ePlace: oldEplace } = hero; // let { ePlace: newEplace } = update; // for(let eplaceId of eplaceIds) { // let oldEquip = oldEplace.find(cur => cur.id == eplaceId); // let newEquip = newEplace.find(cur => cur.id == eplaceId); // if(newEquip && oldEquip) { // let dicOldEquip = gameData.equipById.get(oldEquip.equipId); // let dicNewEquip = gameData.equipById.get(newEquip.equipId); // for(let attr of dicOldEquip.attributeUp) { // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: -1 * attr.num * oldEquip.lv * HERO_CE_RATIO } }); // } // for(let attr of dicNewEquip.attributeUp) { // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: attr.num * newEquip.lv * HERO_CE_RATIO } }); // } // } // } // hero.attr = heroAttrs; // return heroAttrs // } // export function calEquipQualityIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[]) { // let { attr: heroAttrs, ePlace: oldEplace } = hero; // let { ePlace: newEplace } = update; // for(let eplaceId of eplaceIds) { // let oldEquip = oldEplace.find(cur => cur.id == eplaceId); // let newEquip = newEplace.find(cur => cur.id == eplaceId); // if(newEquip && oldEquip) { // let dicOldEquipQuality = getEquipQualityIdByEquipIdAndPoint(oldEquip.equipId, oldEquip.quality, oldEquip.qualityStage); // let dicNewEquipQuality = getEquipQualityIdByEquipIdAndPoint(newEquip.equipId, newEquip.quality, newEquip.qualityStage); // for(let attr of dicOldEquipQuality.attribute) { // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: -1 * attr.num * HERO_CE_RATIO } }); // } // for(let attr of dicNewEquipQuality.attribute) { // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: attr.num * HERO_CE_RATIO } }); // } // } // } // hero.attr = heroAttrs; // return heroAttrs // } // export function calEquipStarIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[], addSeidList: number[], removeSeidList: number[]) { // // 升星本身的属性加成 // let { hid, attr: heroAttrs, ePlace: oldEplace } = hero; // let { ePlace: newEplace } = update; // for(let eplaceId of eplaceIds) { // let oldEquip = oldEplace.find(cur => cur.id == eplaceId); // let newEquip = newEplace.find(cur => cur.id == eplaceId); // if(newEquip && oldEquip) { // let { mainAttr: oldMainAttr, subAttr: oldSubAttr } = getEquipStarAttrByStage(oldEquip.equipId, oldEquip.star, oldEquip.starStage); // let { mainAttr: newMainAttr, subAttr: newSubAttr } = getEquipStarAttrByStage(newEquip.equipId, newEquip.star, newEquip.starStage); // // 主属性 // for(let attr of oldMainAttr) { // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: -1 * attr.num * HERO_CE_RATIO } }); // } // for(let attr of newMainAttr) { // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: attr.num * HERO_CE_RATIO } }); // } // for(let attr of oldSubAttr) { // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: -1 * attr.num * HERO_CE_RATIO } }); // } // for(let attr of newSubAttr) { // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: attr.num * HERO_CE_RATIO } }); // } // } // } // // 套装属性 // calEquipSuitIncAttr(hid, oldEplace, newEplace, addSeidList, removeSeidList); // hero.attr = heroAttrs; // return heroAttrs; // } // function calEquipSuitIncAttr(hid: number, oldEplace: EPlace[], newEplace: EPlace[], addSeidList: number[], removeSeidList: number[]) { // let dicEquipSuit = getEquipSuitByHero(hid); // let oldSuitStars: number[] = [], newSuitStars: number[] = []; // for(let equipId of dicEquipSuit.equips) { // let oldEquip = oldEplace.find(cur => cur.equipId == equipId); // oldSuitStars.push(oldEquip? oldEquip.star: 0); // let newEquip = newEplace.find(cur => cur.equipId == equipId); // newSuitStars.push(newEquip? newEquip.star: 0); // } // let oldStar = Math.min(...oldSuitStars); // let newStar = Math.min(...newSuitStars); // for(let { star, seid } of dicEquipSuit.effect) { // if(oldStar >= star) removeSeidList.push(seid); // if(newStar >= star) addSeidList.push(seid, 0); // } // } // export function calEquipPutOnOrOffJewelIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[], params: { oldJewel: JewelType, newJewel: JewelType }, addSeidList: number[], removeSeidList: number[]) { // let { attr: heroAttrs, ePlace: oldEplace } = hero; // let { ePlace: newEplace } = update; // for(let eplaceId of eplaceIds) { // let oldEquip = oldEplace.find(cur => cur.id == eplaceId); // setRandSeToSeidList(params.oldJewel, oldEquip, removeSeidList); // let newEquip = newEplace.find(cur => cur.id == eplaceId); // setRandSeToSeidList(params.newJewel, newEquip, addSeidList); // } // return heroAttrs; // } // function setRandSeToSeidList(jewel: JewelType, equip: EPlace, list: number[]) { // if(equip && jewel) { // for(let { id, seid, rand } of jewel.randSe) { // if(isRandSeUnLock(jewel.id, id, equip.stones)) { // list.push(seid, rand); // } // } // } // } export function isRandSeUnLock(jewelId: number, randSeId: number, stones: Stone[]) { let dicJewel = gameData.jewel.get(jewelId); let dicJewelCondition = getJewelConditionByLvAndSeId(dicJewel.lv, randSeId); let stoneCnt = 0, stoneLv = 0; for(let { stone } of stones) { let dicStone = gameData.stone.get(stone); if(dicStone) { stoneCnt++; stoneLv += dicStone.lv; } } return stoneCnt >= dicJewelCondition.stoneCnt && stoneLv >= dicJewelCondition.stoneLv; } // export function calEquipPutOnOrOffStoneIncAttr(hero: HeroType, update: HeroUpdate, eplaceIds: number[], params: { jewel: JewelType }, addSeidList: number[], removeSeidList: number[]) { // let { attr: heroAttrs, ePlace: oldEplace } = hero; // let { ePlace: newEplace } = update; // for(let eplaceId of eplaceIds) { // let oldEquip = oldEplace.find(cur => cur.id == eplaceId); // updateHeroAttrOfStone(heroAttrs, oldEquip, -1); // setRandSeToSeidList(params.jewel, oldEquip, removeSeidList); // let newEquip = newEplace.find(cur => cur.id == eplaceId); // updateHeroAttrOfStone(heroAttrs, newEquip, 1); // setRandSeToSeidList(params.jewel, newEquip, addSeidList); // 地玉石阶数变化可能导致属性词条解锁变化 // } // return heroAttrs; // } // function updateHeroAttrOfStone(heroAttrs: CeAttrData[], equip: EPlace, ratio: number) { // for(let { stone } of equip.stones) { // let dicStone = gameData.stone.get(stone); // if(dicStone) { // for(let attr of dicStone.attribute) { // updateHeroAttr(heroAttrs, attr.id, { inc: { fixUp: ratio * attr.num * HERO_CE_RATIO } }); // } // } // } // } // export function calJewelResetRandSeIncAttr(hero: HeroType, eplaceIds: number[], params: { oldJewel: JewelType, newJewel: JewelType }, addSeidList: number[], removeSeidList: number[]) { // let { attr: heroAttrs, ePlace } = hero; // for(let eplaceId of eplaceIds) { // let equip = ePlace.find(cur => cur.id == eplaceId); // setRandSeToSeidList(params.oldJewel, equip, removeSeidList); // setRandSeToSeidList(params.newJewel, equip, addSeidList); // } // return heroAttrs; // } // // 添加技能增加的被动属性 // function addSeidEffect(heroAttrs: CeAttrData[], addSeidList: Array, removeSeidList: Array) { // // console.log('addSeidList', addSeidList.join()) // // console.log('removeSeidList', removeSeidList.join()) // 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) // } // } // // console.log('effectList', JSON.stringify(effectList)); // for (let { type, gainValueArr: [ability, value] } of effectList) { // if (type == SEID_TYPE.TYPE101) { // 加值 // updateHeroAttr(heroAttrs, ability, { inc: {fixUp: value * multi * HERO_CE_RATIO} }); // } else if (type == SEID_TYPE.TYPE103) { // 主属性加百分比 // if(ABI_TYPE_MAIN.includes(ability)) { // updateHeroAttr(heroAttrs, ability, { inc: {ratioUp: value / 1000 * multi} }); // } // } else if (type == SEID_TYPE.TYPE104) { // 次级属性加百分比 // if(!ABI_TYPE_MAIN.includes(ability)) { // updateHeroAttr(heroAttrs, ability, { inc: {fixUp: value * 100 * multi * HERO_CE_RATIO } }); // } // } // } // } // } // // 获取dic_zyz_se内容 // function addSeid(effectList: Array, seidId: number, rand: number, seidValue = new Array()) { // 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); // } // /** // * 全局加成,百家学宫 // * @param role 角色 // * @param heros 所有武将 // * @param schoolId 学宫学派 // * @param hid 换上的武将 // * @param preHid 撤下的武将 // */ // function calSchoolAddAttr(role: RoleType, heros: HeroType[], schoolId: number, hid: number, preHid: number) { // let { attr: roleAttrs } = role; // let school = gameData.school.get(schoolId); // if (!school) return null; // let preHero = heros.find(cur => cur.hid == preHid); // let curHero = heros.find(cur => cur.hid == hid); // let defaultPercent = { mainAttrAPerent: 0, assiAttrAddValue: 0 }; // let preRate = preHero ? getSchoolRateByStar(preHero.star, preHero.colorStar, preHero.quality) : defaultPercent; // let curRate = curHero ? getSchoolRateByStar(curHero.star, curHero.colorStar, curHero.quality) : defaultPercent; // for (let attrId of school.upAttribute) { // if(ABI_TYPE_MAIN.includes(attrId)) { // 主属性 // let ratioUp = curRate.mainAttrAPerent - preRate.mainAttrAPerent; // updateRoleAttr(roleAttrs, attrId, { inc: { ratioUp } }); // } else { // let fixUp = (curRate.assiAttrAddValue - preRate.assiAttrAddValue) * HERO_CE_RATIO; // updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } }); // } // } // return roleAttrs; // } // /** // * 升星,觉醒,升品时,百家学宫配置武将会相应修改全局战力 // * @param {HeroType[]} heros 全部武将 // * @param {number} type 类型 HERO_SYSTEM_TYPE // * @param {number} hid 更新的那个武将 // * @param {number} isStarUp 是否升星 // */ // async function calSchoolStarIncAttr(role: RoleType, heros: HeroType[], type: number, hid: number, isStarUp: number) { // let { roleId, attr: roleAttrs } = role; // if ((type == HERO_SYSTEM_TYPE.STAR || type == HERO_SYSTEM_TYPE.COLORSTAR) && !isStarUp) { // return null; // } // let hero = heros.find(cur => cur.hid == hid); // if(!hero) return null; // let curHeroInSchool = await SchoolModel.findByHid(roleId, hid); // if (!curHeroInSchool) return null; // let preStar = hero.star, preColorStar = hero.colorStar, preQuality = hero.quality; // if (type == HERO_SYSTEM_TYPE.STAR && isStarUp) { // preStar--; // } else if (type == HERO_SYSTEM_TYPE.QUALITY) { // preQuality--; // } else if (type == HERO_SYSTEM_TYPE.COLORSTAR) { // preColorStar--; // if(preColorStar <= 0) preQuality--; // } else { // return null; // } // let school = gameData.school.get(curHeroInSchool.schoolId); // let preRate = getSchoolRateByStar(preStar, preColorStar, preQuality); // let curRate = getSchoolRateByStar(hero.star, hero.colorStar, hero.quality); // for (let attrId of school.upAttribute) { // if(ABI_TYPE_MAIN.includes(attrId)) { // 主属性 // let ratioUp = curRate.mainAttrAPerent - preRate.mainAttrAPerent; // updateRoleAttr(roleAttrs, attrId, { inc: { ratioUp } }); // } else { // let fixUp = (curRate.assiAttrAddValue - preRate.assiAttrAddValue) * HERO_CE_RATIO; // updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } }); // } // } // return roleAttrs; // } // /** // * 全局加成, 名将谱 // * @param heros 所有武将 // * @param hid 激活的武将 // * @param ceAttr // */ // function calScrollAddAttr(role: RoleType,heros: HeroType[], hid: number) { // let { attr: roleAttrs } = role; // // console.log('********** calScrollAddAttr', hid) // let curHero = heros.find(cur => cur.hid == hid); // let dicHero = gameData.hero.get(hid); // if (!curHero || !dicHero) return roleAttrs; // let { quality } = dicHero; // let { star, quality: curQuality, colorStar } = curHero; // // console.log('********** calScrollAddAttr curHero', star, curQuality, colorStar); // let heroScroll = getScollByStar(quality, star, curQuality, colorStar); // if (!heroScroll) return roleAttrs; // // console.log('********** heroScroll', heroScroll); // let isInit = star == dicHero.initialStars && curQuality == dicHero.quality && colorStar == 0; // let preScroll = isInit? null: gameData.preHeroScroll.get(heroScroll.id); // // console.log('********** preScroll', preScroll); // heroScroll.ceAttr.forEach((add, attrId) => { // let preAdd = preScroll ? preScroll.ceAttr.get(attrId) : 0; // let fixUp = (add - preAdd) * HERO_CE_RATIO; // // console.log('********** preAdd', attrId, preAdd, fixUp); // updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } }); // }); // return roleAttrs; // } // /** // * 名将谱激活增加单个武将好感 // * @param originHero 原始武将 // * @param update 更新数据 // */ // function calHeroCeScrollIncAttr(originHero: HeroType, update: HeroUpdate) { // let { attr: heroAttrs, favourLv: oldFavourLv } = originHero; // let { favourLv = oldFavourLv } = update; // if (favourLv != oldFavourLv) { // heroAttrs = calHeroFavourUpIncAttr(originHero, update); // } // return heroAttrs; // } // function calHeroTalent(originHero: HeroType, update: HeroUpdate, addSeidList: number[], removeSeidList: number[]) { // let { attr: heroAttrs, skins: oldSkins } = originHero; // let { skins } = update; // let oldSkin = oldSkins.find(cur => cur.enable); // let newSkin = skins.find(cur => cur.enable); // let oldSeids = getTalentSeid(oldSkin.talent); // let newSeids = getTalentSeid(newSkin.talent); // for(let seid of newSeids) addSeidList.push(seid); // for(let seid of oldSeids) removeSeidList.push(seid); // return heroAttrs // } // function getTalentSeid(talent: Talent[]) { // let seids = new Map(); // id, seids // for(let { id, level } of talent) { // let dicHeroTalent = gameData.heroTalent.get(id); // for(let { type, ids} of dicHeroTalent.relation) { // if(type == TALENT_RELATION_TYPE.REPLACE) { // for(let id of ids) { // seids.delete(id); // } // } // } // for(let { lv, seid } of dicHeroTalent.level) { // if(level >= lv) { // if(!seids.has(id)) seids.set(id, []); // seids.get(id).push(seid); // } // } // } // let result: number[] = []; // for(let [_, ids] of seids) { // result.push(...ids); // } // return result; // } // /** // * 升爵位 // * @param role 角色数据 // * @param titleId 升到哪个爵位 // */ // function calTitle(role: RoleType, update: RoleUpdate) { // let { title: oldTitle, attr: roleAttrs } = role; // let { title: newTitle = oldTitle } = update; // let dicOldTitle = gameData.title.get(oldTitle)||{ mainAttrValue: new Map(), assiAttrValue: new Map() }; // let dicNewTitle = gameData.title.get(newTitle); // for (let i = ABI_TYPE.ABI_HP; i < ABI_TYPE.ABI_MAX; i++) { // if (dicNewTitle.mainAttrValue.has(i) || dicOldTitle.mainAttrValue.has(i)) { // let fixUp = ((dicNewTitle.mainAttrValue.get(i) || 0) - (dicOldTitle.mainAttrValue.get(i) || 0)) * HERO_CE_RATIO; // updateRoleAttr(roleAttrs, i, { inc: { fixUp } }); // } // if (dicNewTitle.assiAttrValue.has(i) || dicOldTitle.mainAttrValue.has(i)) { // let fixUp = ((dicNewTitle.assiAttrValue.get(i) || 0) - (dicOldTitle.assiAttrValue.get(i) || 0)) * HERO_CE_RATIO; // updateRoleAttr(roleAttrs, i, { inc: { fixUp } }); // } // } // return roleAttrs; // } // /** // * 神像强化,更新主属性加成 // * @param role 角色数据 // * @param update 更新数据 // * @param id 更新哪座神像 // */ // function calTeraphMainAttr(role: RoleType, update: RoleUpdate, id: number) { // let { attr: roleAttrs, teraphs: oldTeraphs = [] } = role; // let { teraphs = oldTeraphs } = update; // let oldTeraph = oldTeraphs.find(cur => cur.id == id); // let teraph = teraphs.find(cur => cur.id == id); // if(teraph && teraph.attr) { // for(let [attrId, val] of teraph.attr) { // let oldVal = 0; // if(oldTeraph && oldTeraph.attr && oldTeraph.attr.has(attrId)) { // oldVal = oldTeraph.attr.get(attrId); // } // let fixUp = (val - oldVal) * HERO_CE_RATIO; // updateRoleAttr(roleAttrs, attrId, { inc: {fixUp} }) // } // } // return roleAttrs; // } // /** // * 神像进阶,更新次级属性加成 // * @param role 角色数据 // * @param update 更新数据 // * @param id 更新哪座神像 // */ // function calTeraphAssistAttr(role: RoleType, update: RoleUpdate, id: number) { // let { attr: roleAttrs, teraphs: oldTeraphs = [] } = role; // let { teraphs = oldTeraphs } = update; // let oldTeraph = oldTeraphs.find(cur => cur.id == id); // let teraph = teraphs.find(cur => cur.id == id); // let dicOldTeraph = getTeraph(id, oldTeraph?.grade); // let dicTeraph = getTeraph(id, teraph?.grade); // if(!dicTeraph) return null; // dicTeraph.assiAttrValue.forEach((val, attrId) => { // let oldVal = 0; // if(dicOldTeraph && dicOldTeraph.assiAttrValue && dicOldTeraph.assiAttrValue.has(attrId)) { // oldVal = dicOldTeraph.assiAttrValue.get(attrId); // } // let fixUp = (val - oldVal) * HERO_CE_RATIO; // updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } }); // }); // return roleAttrs; // } // async function calHeroRebirth(role: RoleType, originHero: HeroType, updateHero: HeroUpdate) { // let { roleId, attr: roleAttrs } = role; // // 1. 名将谱 // let dicHero = gameData.hero.get(originHero.hid); // let dicHeroScroll = getScollByStar(dicHero.quality, updateHero.star, updateHero.quality, updateHero.colorStar); // let dicPreScroll = getScollByStar(dicHero.quality, originHero.star, originHero.quality, originHero.colorStar); // if(dicHeroScroll) { // for(let [attrId, value] of dicHeroScroll.ceAttr) { // updateRoleAttr(roleAttrs, attrId, { inc: { fixUp: value * HERO_CE_RATIO } }); // } // } // if(dicPreScroll) { // for(let [attrId, value] of dicPreScroll.ceAttr) { // updateRoleAttr(roleAttrs, attrId, { inc: { fixUp: -value * HERO_CE_RATIO } }); // } // } // // 2. 百家学宫 // let school = await SchoolModel.findByHid(roleId, originHero.hid); // if(school) { // let dicSchool = gameData.school.get(school.schoolId); // let preRate = getSchoolRateByStar(originHero.star, originHero.colorStar, originHero.quality); // let curRate = getSchoolRateByStar(updateHero.star, updateHero.colorStar, updateHero.quality); // console.log('####', updateHero.star, updateHero.colorStar, updateHero.quality) // for (let attrId of dicSchool.upAttribute) { // if(ABI_TYPE_MAIN.includes(attrId)) { // 主属性 // let ratioUp = (curRate?.mainAttrAPerent||0) - (preRate?.mainAttrAPerent||0); // updateRoleAttr(roleAttrs, attrId, { inc: { ratioUp } }); // } else { // let fixUp = ((curRate?.assiAttrAddValue||0) - (preRate?.assiAttrAddValue||0)) * HERO_CE_RATIO; // updateRoleAttr(roleAttrs, attrId, { inc: { fixUp } }); // } // } // } // return roleAttrs; // }