From 820bfe170a023968d7ca9a70b6df1e82e5580b44 Mon Sep 17 00:00:00 2001 From: luying Date: Tue, 29 Aug 2023 16:29:19 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(=E6=AD=A6=E5=B0=86):=20?= =?UTF-8?q?=E9=87=8D=E7=94=9F=E4=BD=93=E9=AA=8C=E4=BC=98=E5=8C=96=20ca13e8?= =?UTF-8?q?be3=20=E8=87=B3=204ee246e78?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/servers/role/handler/heroHandler.ts | 80 +++++++++++++++++-- game-server/app/services/checkParam.ts | 7 ++ game-server/app/services/playerCeService.ts | 38 +++++++++ game-server/app/services/roleService.ts | 17 +++- shared/consts/constModules/heroConst.ts | 1 + shared/db/School.ts | 5 ++ shared/db/Skin.ts | 5 ++ shared/pubUtils/util.ts | 11 ++- 8 files changed, 155 insertions(+), 9 deletions(-) diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index 76b4e27a7..a5416bda8 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -1,8 +1,8 @@ import { Application, BackendSession, ChannelService, HandlerService, } from 'pinus'; import { handleCost, addItems, unlockFigure, getCoinObject, getGoldObject } from '../../../services/role/rewardService'; -import { resResult, deepCopy, parseGoodStr } from '../../../pubUtils/util'; +import { resResult, deepCopy, parseGoodStr, swapFields } from '../../../pubUtils/util'; import { STATUS } from '../../../consts/statusCode'; -import { HeroModel, Connect, HeroSkin, HeroUpdate, EPlace, Talent } from '../../../db/Hero'; +import { HeroModel, Connect, HeroSkin, HeroUpdate, EPlace, Talent, HeroType } from '../../../db/Hero'; import { CURRENCY_BY_TYPE, CURRENCY_TYPE, CONSUME_TYPE, HERO_GROW_MAX, HERO_SYSTEM_TYPE, ABI_STAGE, DEBUG_MAGIC_WORD, HERO_INITIAL_QUALITY, REDIS_KEY, TASK_TYPE, ITEM_CHANGE_REASON, CHECK_HERO_CONSUME } from '../../../consts'; import { RoleModel } from '../../../db/Role'; import { ItemModel } from '../../../db/Item'; @@ -14,13 +14,13 @@ import { PvpDefenseModel } from '../../../db/PvpDefense'; import { checkTask, checkTaskInHeroGiveFavor, checkTaskInHeroQUalityUp, checkTaskInHeroStarUp, checkTaskInHeroTrain, checkTaskInHeroWakeUp } from '../../../services/task/taskService'; import { isNumber, pick } from 'underscore'; import { updateEplaces } from '../../../services/equipService'; -import { addConnect, addConsumeToHero, calStarUpConsume, checkUnlockTalentCondition, initSkinTalent, updateSkinTalent } from '../../../services/roleService'; -import { JewelModel, jewelUpdate } from '../../../db/Jewel'; +import { addConnect, addConsumeToHero, calStarUpConsume, checkUnlockTalentCondition, getHeroNewEplace, initSkinTalent, updateSkinTalent } from '../../../services/roleService'; +import { JewelModel, JewelType, jewelUpdate } from '../../../db/Jewel'; import { HERO, REBORN } from '../../../pubUtils/dicParam'; import { createHero, createHeroes } from '../../../services/role/createHero'; import { CheckMeterial } from '../../../services/role/checkMaterial'; import { HeroParam } from '../../../domain/roleField/hero'; -import { calculateCeWithHero } from '../../../services/playerCeService'; +import { calculateCeWithHero, calculateCeWithHeroes, calculateCeWithRole } from '../../../services/playerCeService'; import { SchoolModel } from '../../../db/School'; import { SkinModel } from '../../../db/Skin'; import { RoleCeModel } from '../../../db/RoleCe'; @@ -810,6 +810,74 @@ export class HeroHandler { return resResult(STATUS.SUCCESS, { preHid, curHero: pick(curHero, ['hid', 'subHid', 'subActorId']) }); } + + /** + * 重生 武将等级、装备养成、职业进阶上养成度对换,升星、羁绊不对换,双方的职业天赋树均重置 + * @param msg + * @param session + */ + public async heroReborn(msg: { originHid: number, targetHid: number }, session: BackendSession) { + const roleId: string = session.get('roleId'); + const roleName: string = session.get('roleName'); + const sid: string = session.get('sid'); + const serverId: number = session.get('serverId'); + + const { originHid, targetHid } = msg; + let dbHeros = await HeroModel.findByHidsAndRole(roleId, [originHid, targetHid]); + if (dbHeros.length != 2) return resResult(STATUS.HERO_NOT_FIND); + const heroMap = dbHeros.reduce((map, obj) => { map.set(obj.hid, obj); return map; }, new Map()); + let originHero = heroMap.get(originHid); + let targetHero = heroMap.get(targetHid); + + swapFields(originHero || {}, targetHero || {}, ['lv', 'job', 'jobStage']); + if (originHero.skins || originHero.skins.length > 0) originHero.skins.forEach((cur) => { cur.talent = [], cur.usedTalentPoint = 0; }); + if (targetHero.skins || targetHero.skins.length > 0) targetHero.skins.forEach((cur) => { cur.talent = [], cur.usedTalentPoint = 0; }); + + let tempOriginEPlace = [], tempTargetEPlace = [] + if (originHero.ePlace || targetHero.ePlace.length > 0) tempOriginEPlace = getHeroNewEplace(originHero, targetHero?.ePlace || []); + if (targetHero.ePlace || originHero.ePlace.length > 0) tempTargetEPlace = getHeroNewEplace(targetHero, originHero?.ePlace || []); + originHero.ePlace = tempOriginEPlace; + targetHero.ePlace = tempTargetEPlace; + + let jewels: JewelType[] = []; + let curJewels: jewelUpdate[] = []; + for (let { jewel } of originHero.ePlace) { + if (jewel == 0) continue; + let result = await JewelModel.updateInfo(jewel, { hid: targetHid }); + if (!result) return resResult(STATUS.HERO_NOT_FIND); + jewels.push(result); + curJewels.push({ seqId:result.seqId, hid:result.hid}); + } + for (let { jewel } of targetHero.ePlace) { + if (jewel == 0) continue; + let result = await JewelModel.updateInfo(jewel, { hid: originHid }); + if (!result) return resResult(STATUS.HERO_NOT_FIND); + jewels.push(result); + curJewels.push({ seqId:result.seqId, hid:result.hid}); + } + + let heroesRet: HeroType[] = []; + for (let hero of [originHero, targetHero]) { + let result = await HeroModel.updateHeroInfo(roleId, hero.hid, { ...pick(hero, ['lv', 'job', 'jobStage', 'ePlace', 'skins']) }); + if (!result) return resResult(STATUS.HERO_NOT_FIND); + heroesRet.push(result); + } + + let artifacts = await ArtifactModel.findbyHids(roleId, [originHid, targetHid]); + + // 战力重算 + let { heroes } = await calculateCeWithHeroes(HERO_SYSTEM_TYPE.REBORN_CAL, roleId, serverId, sid, heroesRet, { jewels, heroes: heroesRet, artifacts }); + + let curHeroes = []; + for (let hero of (heroes || [])) { + const heroResult = new HeroParam(hero); + curHeroes.push({ ...pick(heroResult, ['seqId', 'hid', 'ce', 'lv', 'job', 'jobStage', 'ePlace', 'talent', 'usedTalentPoint', 'totalTalentPoint']) }); + } + + return resResult(STATUS.SUCCESS, { curHeroes, curJewels }) + } + + // ! debug接口 一键全武将 public async debugGetAllHeroes(msg: { magicWord: string }, session: BackendSession) { let roleId: string = session.get('roleId'); @@ -919,4 +987,4 @@ export class HeroHandler { } } -} +} \ No newline at end of file diff --git a/game-server/app/services/checkParam.ts b/game-server/app/services/checkParam.ts index 643c1c683..2a15837b7 100644 --- a/game-server/app/services/checkParam.ts +++ b/game-server/app/services/checkParam.ts @@ -1864,6 +1864,13 @@ export function checkRouteParam(route: string, msg: any) { if (!checkNaturalNumbers(msg.hid, msg.id)) return false; break; } + case "role.heroHandler.heroReborn": + { + const { originHid, targetHid } = msg; + if (originHid == targetHid) return false; + if (!checkNaturalNumbers(originHid, targetHid)) return false; + break; + } case "role.itemHandler.useItem": { if (!checkNaturalNumbers(msg.id, msg.count)) return false; diff --git a/game-server/app/services/playerCeService.ts b/game-server/app/services/playerCeService.ts index 0ab42e198..db29e1562 100644 --- a/game-server/app/services/playerCeService.ts +++ b/game-server/app/services/playerCeService.ts @@ -63,6 +63,15 @@ export async function calculateCeWithHero(type: HERO_SYSTEM_TYPE, roleId: string return { heroes, curHero, curRole } } +export async function calculateCeWithHeroes(type: HERO_SYSTEM_TYPE, roleId: string, serverId: number, sid: string, heroUpdate: HeroUpdate[], param: Param = {}) { + let heroUpdates = new Map(); + for(let val of heroUpdate){ + heroUpdates.set(val.hid, val); + } + let { heroes, curRole } = await calculateCes(type, roleId, serverId, sid, heroUpdates, param.roleUpdate||{}, param.roleIncUpdate||{}, param); + return { heroes, curRole } +} + export async function calculateCeWithRole(type: HERO_SYSTEM_TYPE, roleId: string, serverId: number, sid: string, roleUpdate: RoleUpdate, param: Param = {}) { let { heroes, curRole } = await calculateCes(type, roleId, serverId, sid, new Map(), roleUpdate, {}, param); return { heroes, curRole }; @@ -352,6 +361,8 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve calCe.setEquipSuit(hid, skinId, ePlace); calCe.setScroll(hid, scrollStar, scrollQuality, scrollColorStar); } + + calCe.setTitle(role.title); calCe.setTeraph(role.teraphs); @@ -447,6 +458,33 @@ export async function calculateCes(type: HERO_SYSTEM_TYPE, roleId: string, serve break; } + case HERO_SYSTEM_TYPE.REBORN_CAL: // 42. 重生 + { + let hids = []; + let { jewels, heroes, artifacts } = param; + for (let { hid, skinId, lv, quality, star, starStage, colorStar, colorStarStage, job, jobStage, connections, skins, scrollStar, scrollQuality, scrollColorStar, ePlace } of heroes) { + calCe.setHeroBase(hid, skinId); + calCe.setHeroLv(hid, lv); + calCe.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage); + calCe.setJob(hid, job, jobStage); + calCe.setConnection(hid, connections); + calCe.setTalent(hid, skins); + for (let { id, equipId, star, starStage, quality, qualityStage, lv: equipLv, stones, jewel } of ePlace) { + calCe.setEquipQuality(hid, id, equipId, quality, qualityStage); + calCe.setEquipStrength(hid, id, equipId, equipLv); + calCe.setEquipStar(hid, id, equipId, star, starStage); + let curJewel = jewels.find(cur => cur.seqId == jewel); + calCe.setJewel(hid, id, stones, curJewel); + calCe.setStone(hid, id, stones); + } + let artifact = artifacts.find(cur => cur.hid == hid); + if (artifact) calCe.setPutArtifact(hid, skinId, job, artifact); + calCe.setEquipSuit(hid, skinId, ePlace); + hids.push(hid); + } + ceChangeTxt.push(`重生武将重新计算, 重生武将hids:${hids}`); + break; + } } let { heroCe, roleInc } = calCe.getCeInc(); // 计算战力,获得有变化的武将战力 let changeHids: number[] = []; diff --git a/game-server/app/services/roleService.ts b/game-server/app/services/roleService.ts index a006fcc6c..d1abeff26 100644 --- a/game-server/app/services/roleService.ts +++ b/game-server/app/services/roleService.ts @@ -4,10 +4,10 @@ import { DEFAULT_HEROES, LINEUP_NUM, ROLE_SELECT, TALENT_RELATION_TYPE, TERAPH_R import { DicTeraph } from '../pubUtils/dictionary/DicTeraph'; import { Teraph, RoleModel, RoleType, RoleUpdate } from '../db/Role'; import { SCHOOL } from '../pubUtils/dicParam'; -import { gameData, getHeroInitTalent, getHeroStarByQuality } from '../pubUtils/data'; +import { gameData, getEquipByJobClassAndEPlace, getHeroInitTalent, getHeroStarByQuality } from '../pubUtils/data'; import { SchoolModel } from '../db/School'; import { SclResultInter, SclPosInter, RewardInter, ItemInter } from '../pubUtils/interface'; -import { Connect, HeroModel, HeroSkin, HeroType, HeroUpdate, Talent } from '../db/Hero'; +import { Connect, EPlace, HeroModel, HeroSkin, HeroType, HeroUpdate, Talent } from '../db/Hero'; import { SkinUpdate } from '../db/Skin'; import { Figure } from '../domain/dbGeneral'; import { pick } from 'underscore'; @@ -390,4 +390,17 @@ export function replaceAuthorBooks(authorBooks: AuthorBookType[], authorBook: Au authorBooks[index] = authorBook; } return authorBooks; +} + + +export function getHeroNewEplace(hero: HeroType, ePlace: EPlace[]) { + const dicHero = gameData.hero.get(hero.skinId); + let newEplace = []; + for (let eP of ePlace) { + const dicEquip = getEquipByJobClassAndEPlace(dicHero?.jobClass, eP.id); + if (!dicEquip) continue; + // const newEquip = new EPlace(eP.id, dicEquip.id); + newEplace.push({ ...eP, equipId: dicEquip.id }); + } + return newEplace; } \ No newline at end of file diff --git a/shared/consts/constModules/heroConst.ts b/shared/consts/constModules/heroConst.ts index ca2bee047..358d1b4f1 100644 --- a/shared/consts/constModules/heroConst.ts +++ b/shared/consts/constModules/heroConst.ts @@ -42,6 +42,7 @@ export enum HERO_SYSTEM_TYPE { ARTIFACT_REBUILD = 39, // 宝物重铸 AUTHOR_BOOK_STAR = 40, // 诸子列传升星 AUTHOR_BOOK_SUB_RESET = 41, // 诸子列传重置 + REBORN_CAL = 42, //重生计算 }; // 武将上限 diff --git a/shared/db/School.ts b/shared/db/School.ts index 8a87d3780..f83fd1227 100644 --- a/shared/db/School.ts +++ b/shared/db/School.ts @@ -42,6 +42,11 @@ export default class School extends BaseModel { return result; } + public static async findByHids(roleId: string, hids: number[]) { + let result: SchoolType[] = await SchoolModel.find({ roleId, hid: { $in: hids } }).lean(); + return result; + } + public static async updateBySclAndPos(roleId: string, schoolId: number, positionId: number, update: SchoolUpdate) { const doc = new SchoolModel(); diff --git a/shared/db/Skin.ts b/shared/db/Skin.ts index 38448beb7..7d49955df 100644 --- a/shared/db/Skin.ts +++ b/shared/db/Skin.ts @@ -29,6 +29,11 @@ export default class Skin extends BaseModel { return rec; } + public static async findbyRoleAndHids(roleId: string, hids: number[]) { + const rec: SkinType[] = await SkinModel.find({ roleId, hid: { $in: hids } }).lean(); + return rec; + } + public static getInitInfo(hid: number): SkinUpdate { let dicHero = gameData.hero.get(hid); let dicFashion = gameData.fashion.get(dicHero.initialSkin) diff --git a/shared/pubUtils/util.ts b/shared/pubUtils/util.ts index 9f76cb6c8..57cd2986e 100644 --- a/shared/pubUtils/util.ts +++ b/shared/pubUtils/util.ts @@ -881,4 +881,13 @@ export function compareVersion(versionA: string, versionB: string) { } else { return 0; } -}; \ No newline at end of file +}; + +// 交换俩obj中的指定字段 +export function swapFields(originObj: object, targetObj: object, fieldsToSwap: string[]) { + for (const field of fieldsToSwap) { + const temp = originObj[field]; + originObj[field] = targetObj[field]; + targetObj[field] = temp; + } +} \ No newline at end of file