import { Application, BackendSession, HandlerService, } from "pinus"; import { STATUS, HERO_SYSTEM_TYPE, ITEM_CHANGE_REASON, TASK_TYPE, CONSUME_TYPE } from "../../../consts"; import { ItemInter, RewardInter } from "../../../pubUtils/interface"; import { resResult, parseGoodStr } from "../../../pubUtils/util"; import { addItems, getJewelRandSe, handleCost } from "../../../services/role/rewardService"; import { HeroModel, EPlace } from "../../../db/Hero"; import { gameData, getEquipByJobClassAndEPlace, getNextEquipQuality, getEquipStarIdByEquipId, getNextEquipStar } from "../../../pubUtils/data"; import { BAG, EQUIP } from "../../../pubUtils/dicParam"; import { getRandSeResult, updateEplace, updateEplaces, checkJewelCanPutOnEquip, updateStone, checkStoneCanPutOnEquip, isLocked } from "../../../services/equipService"; import { clone, isNumber, max, min, pick } from 'underscore'; import { JewelModel, RandSe } from "../../../db/Jewel"; import { checkTaskInComposeEquip, checkTaskInEquipLvUp, checkTaskInComposeStone, checkTaskInEquipReset, checkTaskInEquipQuench, checkTaskInEquipQualityUp, checkTaskInEquipStarUp, checkTaskInPutJewel, checkTaskInPutStone } from '../../../services/task/taskService'; import { pushEquipQualityMax, pushEquipStarMax } from "../../../services/sysChatService"; import { addConsumeToHero } from "../../../services/roleService"; import { CheckMeterial, getComposeStoneCostAndAdd, getCurItem } from "../../../services/role/checkMaterial"; import { combineItems } from "../../../services/role/util"; import { calculateCeWithHero } from "../../../services/playerCeService"; import { ItemModel } from "../../../db/Item"; import { index } from "typegoose"; import { all } from "bluebird"; export default function (app: Application) { new HandlerService(app, {}); return new EquipHandler(app); } export class EquipHandler { constructor(private app: Application) { } public async composeEquip(msg: { hid: number, ePlaceId: number }, session: BackendSession) { let roleId: string = session.get('roleId'); let sid: string = session.get('sid'); let serverId: number = session.get('serverId'); let { hid, ePlaceId } = msg; if (!isNumber(ePlaceId) || ePlaceId > 4 || ePlaceId < 1) return resResult(STATUS.WRONG_PARMS); let hero = await HeroModel.findByHidAndRole(hid, roleId); if (!hero) return resResult(STATUS.HERO_NOT_FIND); let oldEplace = hero.ePlace || []; let curEquip = oldEplace.find(equip => equip.id == ePlaceId); if (curEquip) return resResult(STATUS.EQUIP_HAS_COMPOSE); let dicHero = gameData.hero.get(hero.skinId); let dicEquip = getEquipByJobClassAndEPlace(dicHero?.jobClass, ePlaceId); if (!dicEquip) return resResult(STATUS.DIC_DATA_NOT_FOUND); let consumeResult = await handleCost(roleId, sid, dicEquip.composeMaterial, ITEM_CHANGE_REASON.EQUIP_COMPOSE); if (!consumeResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let newEquip = new EPlace(ePlaceId, dicEquip.id); let newEplace = [...oldEplace, newEquip]; let update = { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, dicEquip.composeMaterial), } await calculateCeWithHero(HERO_SYSTEM_TYPE.COMPOSE_EQUIP, roleId, serverId, sid, hid, update, { ePlaceId, skinId: hero.skinId }); await checkTaskInComposeEquip(serverId, roleId, sid, oldEplace, newEplace); let curHero = { hid, ePlace: [newEquip] } return resResult(STATUS.SUCCESS, { curHero }); } // 装备栏强化 public async strengthen(msg: { hid: number, ePlaceId: number, isOneClick: boolean }, session: BackendSession) { let roleId: string = session.get('roleId'); // let roleName: string = session.get('roleName'); const serverId = session.get('serverId'); let sid: string = session.get('sid'); let { hid, ePlaceId, isOneClick } = msg; let hero = await HeroModel.findByHidAndRole(hid, roleId); if (!hero) return resResult(STATUS.HERO_NOT_FIND); let oldEplace = hero.ePlace || []; let curEquip = oldEplace.find(cur => cur.id == ePlaceId); if (!curEquip) return resResult(STATUS.EQUIP_NOT_FIND); if (curEquip.lv >= hero.lv) return resResult(STATUS.ROLE_EQUIP_REACH_MAX); let fromLv = curEquip.lv; let toLv = isOneClick ? hero.lv : fromLv + 1; let newLv = fromLv; let check = new CheckMeterial(roleId); for (let lv = fromLv + 1; lv <= toLv; lv++) { let dicCost = gameData.equipStrengthenCost.get(lv); let isEnough = await check.decrease(dicCost.consume); if (!isEnough) break; // 消耗不足 newLv = lv; } if (newLv == fromLv) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let consumes = check.getConsume(); let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.EQUIP_STRENTHEN); if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { lv: newLv }); let update = { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes) } await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, roleId, serverId, sid, hid, update, { ePlaceIds: [ePlaceId] }); await checkTaskInEquipLvUp(serverId, roleId, sid, oldEplace, newEplace, [ePlaceId]); const curHero = { hid, ePlace: updatedEplace } return resResult(STATUS.SUCCESS, { curHero }); } // 装备栏一键强化至相应等级 public async strengthenAll(msg: { hid: number, lv: number }, session: BackendSession) { let roleId: string = session.get('roleId'); let serverId: number = session.get('serverId'); let sid: string = session.get('sid'); let { hid, lv } = msg; // lv: 升到哪一级 let hero = await HeroModel.findByHidAndRole(hid, roleId); if (!hero) return resResult(STATUS.HERO_NOT_FIND); let { ePlace, lv: playerLv } = hero; // 装备栏 let fromLv = Math.min(...ePlace.map(cur => cur.lv)); // 最小的等级 let toLv = lv < playerLv ? lv : playerLv; let eplaceIds = new Map(); // 更新了的装备栏id let check = new CheckMeterial(roleId); for (let lv = fromLv + 1; lv <= toLv; lv++) { let isBreak = false; for (let equip of ePlace) { if (equip.lv >= lv) continue; let dicCost = gameData.equipStrengthenCost.get(lv); let isEnough = await check.decrease(dicCost.consume); if (!isEnough) { isBreak = true; break; } // 消耗不足 eplaceIds.set(equip.id, { lv }); } if (isBreak) break; } if (eplaceIds.size <= 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let consumes = check.getConsume(); let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.EQUIP_STRENTHEN); if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let { newEplace, updatedEplace } = updateEplaces(ePlace, eplaceIds); let update = { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes), } await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_STRENGTH, roleId, serverId, sid, hid, update, { ePlaceIds: [...eplaceIds.keys()] }); await checkTaskInEquipLvUp(serverId, roleId, sid, ePlace, newEplace, [...eplaceIds.keys()]); const curHero = { hid, ePlace: updatedEplace } return resResult(STATUS.SUCCESS, { curHero }); } // 装备升品 public async qualityUp(msg: { hid: number, ePlaceId: number, isOneClick: boolean }, session: BackendSession) { let roleId: string = session.get('roleId'); let roleName: string = session.get('roleName'); const serverId = session.get('serverId'); let sid: string = session.get('sid'); let { hid, ePlaceId, isOneClick } = msg; let hero = await HeroModel.findByHidAndRole(hid, roleId); if (!hero) return resResult(STATUS.HERO_NOT_FIND); let oldEplace = hero.ePlace || []; let curEquip = oldEplace.find(cur => cur.id == ePlaceId); if (!curEquip) return resResult(STATUS.EQUIP_NOT_FIND); let nextEquipQuality = getNextEquipQuality(curEquip.equipId, curEquip.quality, curEquip.qualityStage); if (!nextEquipQuality) return resResult(STATUS.EQUIP_QUALITY_MAX); let equipUpdate = { quality: curEquip.quality, qualityStage: curEquip.qualityStage, } let check = new CheckMeterial(roleId); let count = 0; if (isOneClick) { // 一键升到该品最高点 if (nextEquipQuality.quality != curEquip.quality) { return resResult(STATUS.EQUIP_QUALITYSTAGE_IS_MAX); } while (nextEquipQuality && nextEquipQuality.quality == curEquip.quality) { let isEnough = await check.decrease(nextEquipQuality.consume); if (!isEnough) break; // 消耗不足 equipUpdate.qualityStage++; nextEquipQuality = getNextEquipQuality(curEquip.equipId, equipUpdate.quality, equipUpdate.qualityStage); count++; } } else { // 往下一阶,包括满点之后的升品 let isEnough = await check.decrease(nextEquipQuality.consume); if (isEnough) { equipUpdate.quality = nextEquipQuality.quality; equipUpdate.qualityStage = nextEquipQuality.point; count++; } } if (equipUpdate.quality == curEquip.quality && equipUpdate.qualityStage == curEquip.qualityStage) { return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); } let consumes = check.getConsume(); let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.EQUIP_QUALITYUP); if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let isUpQuality = equipUpdate.quality != curEquip.quality; let { newEplace, updatedEplace, newEquip } = updateEplace(oldEplace, ePlaceId, equipUpdate); let update = { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes), } await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_QUALITY, roleId, serverId, sid, hid, update, { ePlaceId }); await checkTaskInEquipQualityUp(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, hid, isUpQuality, count); pushEquipQualityMax(roleId, roleName, serverId, hid, newEquip, isUpQuality); const curHero = { hid, isUpQuality, ePlace: updatedEplace } return resResult(STATUS.SUCCESS, { curHero }); } // 装备升星 public async starUp(msg: { hid: number, ePlaceId: number, isOneClick: boolean }, session: BackendSession) { let roleId: string = session.get('roleId'); let roleName: string = session.get('roleName'); const serverId = session.get('serverId'); let sid: string = session.get('sid'); let { hid, ePlaceId, isOneClick } = msg; let hero = await HeroModel.findByHidAndRole(hid, roleId); if (!hero) return resResult(STATUS.HERO_NOT_FIND); let oldEplace = hero.ePlace || []; let curEquip = oldEplace.find(cur => cur.id == ePlaceId); if (!curEquip) return resResult(STATUS.EQUIP_NOT_FIND); let incEquipStarSum = 0; let equipUpdate = { star: curEquip.star, starStage: curEquip.starStage, } let check = new CheckMeterial(roleId); let dicEquipStar = getEquipStarIdByEquipId(curEquip.equipId, curEquip.star); if (!dicEquipStar) return resResult(STATUS.DIC_DATA_NOT_FOUND); let isUpStar = curEquip.starStage == dicEquipStar.count; let count = 0; if (isUpStar) { // 升星 if (isOneClick) { return resResult(STATUS.EQUIP_STARSTAGE_IS_MAX); } else { let nextEquipStar = getNextEquipStar(curEquip.equipId, curEquip.star); if (!nextEquipStar) return resResult(STATUS.EQUIP_STAR_MAX); let dicEquipQualityExtra = gameData.equipQualityExtra.get(curEquip.quality); if (!dicEquipQualityExtra || dicEquipQualityExtra.star < nextEquipStar.star) { return resResult(STATUS.EQUIP_QUALITY_NOT_ENOUGH); } let isEnough = await check.decrease(dicEquipStar.subConsume); if (isEnough) { equipUpdate.star = nextEquipStar.star; equipUpdate.starStage = 0; incEquipStarSum += equipUpdate.star - curEquip.star; count++; } } } else { // 升小点,包括一键升到满小点和升一个小点 let toStage = isOneClick ? dicEquipStar.count : curEquip.starStage + 1; for (let stage = curEquip.starStage + 1; stage <= toStage; stage++) { let isEnough = await check.decrease(dicEquipStar.mainConsume); if (!isEnough) break; // 消耗不足 equipUpdate.starStage = stage; count++; } } if (equipUpdate.star == curEquip.star && equipUpdate.starStage == curEquip.starStage) { return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); } let consumes = check.getConsume(); let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.EQUIP_STARUP); if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let { newEplace, updatedEplace, newEquip } = updateEplace(oldEplace, ePlaceId, equipUpdate); let update = { ePlace: newEplace, consumes: addConsumeToHero(hero.consumes, consumes) } // console.log('### incEquipStarSum', incEquipStarSum) let { curRole } = await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_STAR, roleId, serverId, sid, hid, update, { ePlaceId, skinId: hero.skinId, roleIncUpdate: { equipStarSum: incEquipStarSum } }); checkTaskInEquipStarUp(serverId, roleId, sid, oldEplace, newEplace, ePlaceId, hid, isUpStar, count, hero.skinId); pushEquipStarMax(roleId, roleName, serverId, hid, newEquip, isUpStar); const curHero = { hid, isUpStar, ePlace: updatedEplace } return resResult(STATUS.SUCCESS, { curHero }); } //镶嵌天晶石 public async putOnJewel(msg: { hid: number, ePlaceId: number, jewel: number }, session: BackendSession) { let { hid, ePlaceId, jewel: seqId } = msg; let roleId: string = session.get('roleId'); let sid: string = session.get('sid'); let serverId: number = session.get('serverId'); let hero = await HeroModel.findByHidAndRole(hid, roleId); if (!hero) return resResult(STATUS.HERO_NOT_FIND); let oldEplace = hero.ePlace || []; let curEquip = oldEplace.find(cur => cur.id == ePlaceId); if (!curEquip) return resResult(STATUS.EQUIP_NOT_FIND); let jewel = await JewelModel.findbySeqId(seqId); if (!jewel) return resResult(STATUS.JEWEL_IS_NOT_FIND); if (curEquip.jewel == seqId) return resResult(STATUS.JEWEL_HAS_SUIT); if (!checkJewelCanPutOnEquip(curEquip, jewel)) { return resResult(STATUS.EQUIP_NOT_MATCH_JEWEL) } let originHeroResult: { hid: number, ePlace: Partial[] }; let originJewel = curEquip.jewel ? await JewelModel.findbySeqId(curEquip.jewel) : null; // 原本自己的天晶石 let canSentMineToOrigin = false; // 自己的能不能塞到对方身上 if (jewel.hid != 0) { // 如果天晶石原本镶嵌在其他武将身上,把自己的给他 let originHero = await HeroModel.findByHidAndRole(jewel.hid, roleId); let originEplace = originHero?.ePlace || []; let originEquip = originEplace.find(cur => cur.jewel == seqId); if (originEquip) { let canChange = originJewel && checkJewelCanPutOnEquip(originEquip, originJewel); if (canChange) canSentMineToOrigin = true; let { newEplace, updatedEplace } = updateEplace(originEplace, ePlaceId, { jewel: canChange ? originJewel.seqId : 0 }); await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, jewel.hid, { ePlace: newEplace }, { ePlaceId, jewel: canChange ? originJewel : null, skinId: originHero.skinId }); await checkTaskInPutJewel(serverId, roleId, sid, jewel.hid, originEplace, newEplace, ePlaceId, jewel, canChange ? originJewel : null); originHeroResult = { hid: originHero.hid, ePlace: updatedEplace }; } } if (originJewel) { // 更新自己的天晶石 originJewel = await JewelModel.putOnOrOff(originJewel.seqId, canSentMineToOrigin ? jewel.hid : 0, canSentMineToOrigin ? ePlaceId : 0); } // 目标镶嵌上 let curJewel = await JewelModel.putOnOrOff(seqId, hid, ePlaceId); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { jewel: seqId }); await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceId, jewel: curJewel, skinId: hero.skinId }); await checkTaskInPutJewel(serverId, roleId, sid, hid, oldEplace, newEplace, ePlaceId, originJewel, curJewel); let curHero = { hid, ePlace: updatedEplace } return resResult(STATUS.SUCCESS, { curHero, originHero: originHeroResult, curJewel, originJewel }); } // 卸下天晶石 public async putOffJewel(msg: { hid: number, ePlaceId: number }, session: BackendSession) { let { hid, ePlaceId } = msg; let roleId: string = session.get('roleId'); let sid: string = session.get('sid'); let serverId: number = session.get('serverId'); let hero = await HeroModel.findByHidAndRole(hid, roleId); if (!hero) return resResult(STATUS.HERO_NOT_FIND); let oldEplace = hero.ePlace || []; let curEquip = oldEplace.find(cur => cur.id == ePlaceId); if (!curEquip) return resResult(STATUS.EQUIP_NOT_FIND); if (curEquip.jewel == 0) return resResult(STATUS.JEWEL_NOT_SUIT); let curJewel = await JewelModel.putOnOrOff(curEquip.jewel, 0, 0); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { jewel: 0 }); await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_JEWEL, roleId, serverId, sid, hid, { ePlace: newEplace }, { ePlaceId, jewel: null, skinId: hero.skinId }); await checkTaskInPutJewel(serverId, roleId, sid, hid, oldEplace, newEplace, ePlaceId, null, curJewel); let curHero = { hid, ePlace: updatedEplace } return resResult(STATUS.SUCCESS, { curHero, curJewel }); } // 装备或卸载地玉石 public async putOnOrOffStone(msg: { hid: number, ePlaceId: number, stonesId: number, gid: number }, session: BackendSession) { let { hid, ePlaceId, stonesId, gid } = msg; let roleId: string = session.get('roleId'); let roleName: string = session.get('roleName'); let sid: string = session.get('sid'); let serverId: number = session.get('serverId'); let hero = await HeroModel.findByHidAndRole(hid, roleId); if (!hero) return resResult(STATUS.HERO_NOT_FIND); let oldEplace = hero.ePlace || []; let curEquip = oldEplace.find(cur => cur.id == ePlaceId); if (!curEquip) return resResult(STATUS.EQUIP_NOT_FIND); let curStone = curEquip.stones?.find(cur => cur.id == stonesId) || { id: stonesId, stone: 0 }; if (curStone.stone == gid) { return resResult(gid == 0 ? STATUS.STONE_NOT_SUIT : STATUS.STONE_HAS_SUIT); } if (!checkStoneCanPutOnEquip(curEquip, stonesId, gid)) { // 是否可以镶嵌 return resResult(STATUS.STONE_CANNOT_SUIT); } let updateConsumes = hero.consumes; if (gid > 0) { updateConsumes = addConsumeToHero(updateConsumes, [{ id: gid, count: 1 }]); let consumeResult = await handleCost(roleId, sid, [{ id: gid, count: 1 }], ITEM_CHANGE_REASON.EQUIP_FILL_HOLE); if (!consumeResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); } if (curStone.stone > 0) { // 返回石头 updateConsumes = addConsumeToHero(updateConsumes, [{ id: curStone.stone, count: -1 }]); await addItems(roleId, roleName, sid, [{ id: curStone.stone, count: 1 }], ITEM_CHANGE_REASON.EQUIP_FILL_HOLE); } let newStone = updateStone(curEquip.stones, stonesId, gid); let { newEplace, updatedEplace } = updateEplace(oldEplace, ePlaceId, { stones: newStone }); let jewel = await JewelModel.findbySeqId(curEquip.jewel); let update = { ePlace: newEplace, consumes: updateConsumes, } await calculateCeWithHero(HERO_SYSTEM_TYPE.EQUIP_STONE, roleId, serverId, sid, hid, update, { ePlaceId, jewel, skinId: hero.skinId, stonesId }); await checkTaskInPutStone(serverId, roleId, sid, hid, oldEplace, newEplace, ePlaceId, jewel); let curHero = { hid, ePlace: updatedEplace } return resResult(STATUS.SUCCESS, { curHero }); } // 随机属性锁定 public async lockRandSe(msg: { seqId: number, randSeId: number, type: number }, session: BackendSession) { let { seqId, randSeId, type } = msg; let roleId: string = session.get('roleId'); let roleName: string = session.get('roleName'); let sid: string = session.get('sid'); let jewel = await JewelModel.findbySeqId(seqId); if (!jewel) return resResult(STATUS.JEWEL_NOT_FOUND); let { randSe } = jewel; if (!randSe || randSe.length <= 0) { return resResult(STATUS.JEWEL_HAVE_NO_RANDSE); } let curSe = randSe.find(cur => cur.id == randSeId); if (!curSe || (type == 1 && curSe.locked)) { return resResult(STATUS.JEWEL_DUPLICATE_LOCK); } if (type == 1) { // 仅在上锁时消耗,根据已有的锁的数量判断消耗 let lockNum = randSe.filter(cur => cur.locked).length; let consumes: Array<{ id: number, count: number }> = []; if (lockNum == 0) { consumes = parseGoodStr(EQUIP.EQUIP_ONE_LOCKED); } else if (lockNum == 1) { consumes = parseGoodStr(EQUIP.EQUIP_TWO_LOCKED); } else if (lockNum == 2) { consumes = parseGoodStr(EQUIP.EQUIP_THREE_LOCKED); } else { return resResult(STATUS.ROLE_ALL_SE_LOCK); } let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.EQUIP_LOCK_RANDSE); if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); } let result = await JewelModel.lock(seqId, randSeId, type == 1); if (!result) { return resResult(STATUS.JEWEL_HAVE_NO_RANDSE); } return resResult(STATUS.SUCCESS, { curJewel: pick(result, ['seqId', 'id', 'hid', 'ePlaceId', 'randSe']) }); } // 装备洗炼预览 public async previewRandSe(msg: { seqId: number }, session: BackendSession) { let roleId: string = session.get('roleId'); // let roleName: string = session.get('roleName'); let sid: string = session.get('sid'); let { seqId } = msg; let jewel = await JewelModel.findbySeqId(seqId); if (!jewel) return resResult(STATUS.JEWEL_NOT_FOUND); let { id, randSe, previewRandSe } = jewel; if (previewRandSe.length <= 0) { let previewRandSe = getRandSeResult(id, randSe); if (!previewRandSe) return resResult(STATUS.DIC_DATA_NOT_FOUND); let lockNum = randSe.reduce((pre, cur) => { return cur.locked ? pre + 1 : pre; }, 0); if (lockNum >= randSe.length) { return resResult(STATUS.ROLE_EQUIP_CANNOT_RESTRENGTHEN); } // 消耗 let consumes: Array<{ id: number, count: number }> = []; if (lockNum == 0) { consumes = parseGoodStr(EQUIP.EQUIP_ONE_REFORGED); } else if (lockNum == 1) { consumes = parseGoodStr(EQUIP.EQUIP_TWO_REFORGED); } else if (lockNum == 2) { consumes = parseGoodStr(EQUIP.EQUIP_THREE_REFORGED); } else { consumes = parseGoodStr(EQUIP.EQUIP_FOUR_REFORGED); } let result = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.EQUIP_RESTRENGTHEN); if (!result) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); jewel = await JewelModel.updateInfo(seqId, { previewRandSe }); } return resResult(STATUS.SUCCESS, { curJewel: pick(jewel, ['seqId', 'id', 'hid', 'ePlaceId', 'randSe', 'previewRandSe']) }); } // 装备洗炼 public async resetRandSe(msg: { seqId: number }, session: BackendSession) { let roleId: string = session.get('roleId'); let serverId: number = session.get('serverId'); let sid: string = session.get('sid'); let { seqId } = msg; let jewel = await JewelModel.findbySeqId(seqId); if (!jewel) return resResult(STATUS.JEWEL_NOT_FOUND); let { randSe, hid, ePlaceId, previewRandSe } = jewel; if (!previewRandSe || previewRandSe.length <= 0) { // 没预览过 return resResult(STATUS.EQUIP_RESTRENGTHEN_NOT_PREVIEW); } let newJewel = await JewelModel.updateInfo(seqId, { previewRandSe: [], randSe: previewRandSe }); // 更新战力 if (hid > 0) { const hero = await HeroModel.findByHidAndRole(hid, roleId); await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, hid, { ePlace: hero.ePlace }, { ePlaceId, jewel: newJewel, skinId: hero.skinId }); } await checkTaskInEquipReset(serverId, roleId, sid); return resResult(STATUS.SUCCESS, { curJewel: pick(newJewel, ['seqId', 'id', 'hid', 'ePlaceId', 'randSe', 'previewRandSe']) }); } // 放弃这条洗练 public async giveupPreview(msg: { seqId: number }, session: BackendSession) { let { seqId } = msg; let jewel = await JewelModel.findbySeqId(seqId); if (!jewel) return resResult(STATUS.JEWEL_NOT_FOUND); let { randSe, previewRandSe } = jewel; if (!randSe || randSe.length <= 0) { return resResult(STATUS.JEWEL_HAVE_NO_RANDSE); } if (!previewRandSe) { // 没预览过 return resResult(STATUS.JEWEL_NOT_PREVIEW); } let jewelResult = await JewelModel.updateInfo(seqId, { previewRandSe: [] }) return resResult(STATUS.SUCCESS, { curJewel: pick(jewelResult, ['seqId', 'id', 'hid', 'ePlaceId', 'randSe', 'previewRandSe']) }); } // 选择淬炼的那一条 public async chooseQuench(msg: { seqId: number, randSeId: number }, session: BackendSession) { let { seqId, randSeId } = msg; let jewel = await JewelModel.findbySeqId(seqId); if (!jewel) return resResult(STATUS.JEWEL_NOT_FOUND); let { randSe } = jewel; if (!randSe || randSe.length <= 0) { return resResult(STATUS.JEWEL_HAVE_NO_RANDSE); } let quenchedSe = randSe.find(cur => cur.quenched); if (!!quenchedSe) return resResult(STATUS.JEWEL_HAS_CHOOSEN_QUENCH); let curRandSe = randSe.find(cur => cur.id == randSeId); if (!curRandSe) return resResult(STATUS.JEWEL_HAVE_NO_CUR_RANDSE); let jewelResult = await JewelModel.chooseQuench(seqId, randSeId); return resResult(STATUS.SUCCESS, { curJewel: pick(jewelResult, ['seqId', 'id', 'hid', 'ePlaceId', 'randSe', 'previewRandSe']) }); } // 淬火 public async quench(msg: { seqId: number }, session: BackendSession) { let roleId: string = session.get('roleId'); let serverId: number = session.get('serverId'); let sid: string = session.get('sid'); let { seqId } = msg; let jewel = await JewelModel.findbySeqId(seqId); if (!jewel) return resResult(STATUS.JEWEL_NOT_FOUND); let { randSe, hid, ePlaceId } = jewel; if (!randSe || randSe.length <= 0) { return resResult(STATUS.JEWEL_HAVE_NO_RANDSE); } let quenchedSe = randSe.find(cur => cur.quenched); if (!quenchedSe) return resResult(STATUS.JEWEL_NOT_CHOOSEN_QUENCH); let dicJewel = gameData.jewel.get(jewel.id); if (!dicJewel) return resResult(STATUS.DIC_DATA_NOT_FOUND); let consumeResult = await handleCost(roleId, sid, dicJewel.quenchConsume, ITEM_CHANGE_REASON.EQUIP_QUENCH); if (!consumeResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let newRandSe = getJewelRandSe(quenchedSe.id, quenchedSe.seid); let isSuccess = newRandSe.rand >= quenchedSe.rand; let newJewel = await JewelModel.quench(seqId, isSuccess, newRandSe.rand); // 更新战力 if (isSuccess && hid > 0) { const hero = await HeroModel.findByHidAndRole(hid, roleId); await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_QUENCH, roleId, serverId, sid, hid, { ePlace: hero.ePlace }, { ePlaceId, jewel: newJewel, skinId: hero.skinId }); } await checkTaskInEquipQuench(serverId, roleId, sid, isSuccess); return resResult(STATUS.SUCCESS, { isSuccess, curJewel: pick(newJewel, ['seqId', 'id', 'hid', 'ePlaceId', 'randSe', 'previewRandSe']) }); } // 地玉石和图纸分解 public async decomposeItem(msg: { origin: { id: number, count: number }[] }, session: BackendSession) { let { origin } = msg; let roleId: string = session.get('roleId'); let roleName: string = session.get('roleName'); let sid: string = session.get('sid'); let goods: ItemInter[] = []; for (let { id, count } of origin) { let dicGoods = gameData.goods.get(id); if (!dicGoods) return resResult(STATUS.DIC_DATA_NOT_FOUND); if (!dicGoods.decomposeItem || dicGoods.decomposeItem.length <= 0) return resResult(STATUS.CONSUME_TYPE_ERR); if (count < 0) return resResult(STATUS.WRONG_PARMS); for (let result of dicGoods.decomposeItem) { goods.push({ id: result.id, count: result.count * count }); } } let costResult = await handleCost(roleId, sid, origin, ITEM_CHANGE_REASON.EQUIP_PIECE_DECOMPOSE); if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let result = await addItems(roleId, roleName, sid, goods, ITEM_CHANGE_REASON.EQUIP_PIECE_DECOMPOSE); return resResult(STATUS.SUCCESS, { goods: combineItems(result) }); } //分解装备 public async decomposeJewel(msg: { origin: number[] }, session: BackendSession) { let { origin } = msg; let roleId: string = session.get('roleId'); let roleName: string = session.get('roleName'); let sid: string = session.get('sid'); if (origin.length > BAG.BAG_RESOLVE_UPLIMITED) { return resResult(STATUS.EQUIP_DECOMPOSE_IS_UPLIMIT); } let jewels = await JewelModel.findbySeqIds(origin); if (jewels.length < origin.length) return resResult(STATUS.JEWEL_IS_NOT_FIND); let goods: RewardInter[] = []; let cost: ItemInter[] = []; for (let jewel of jewels) { if (jewel.hid > 0) { return resResult(STATUS.JEWEL_IS_EQUIPED); } let dicGoods = gameData.goods.get(jewel.id); cost.push({ seqId: jewel.seqId, id: jewel.id, count: 1 }); goods.push(...dicGoods.decomposeItem); } let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.EQUIP_DECOMPOSE); // 删掉装备 if (!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); let result = await addItems(roleId, roleName, sid, goods, ITEM_CHANGE_REASON.EQUIP_DECOMPOSE); return resResult(STATUS.SUCCESS, { goods: combineItems(result) }); } //宝石合成 public async composeStone(msg: { id: number, count: number }, session: BackendSession) { let { id, count } = msg; let roleId: string = session.get('roleId'); let roleName: string = session.get('roleName'); let sid: string = session.get('sid'); let serverId: number = session.get('serverId'); let check = new CheckMeterial(roleId); let isEnough = await check.composeStone(id, count); if (!isEnough) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let consumes = check.getConsume(); let costResult = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.COMPOSE_STONE); if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let goods = await addItems(roleId, roleName, sid, [{ id, count }], ITEM_CHANGE_REASON.COMPOSE_STONE); await checkTaskInComposeStone(serverId, roleId, sid, count); return resResult(STATUS.SUCCESS, { goods }); } /** * 玉石一键合成 * @param msg * @param session * @returns */ public async composeStoneByItId(msg: { itId: number }, session: BackendSession) { let { itId } = msg; let roleId: string = session.get('roleId'); let roleName: string = session.get('roleName'); let sid: string = session.get('sid'); let serverId: number = session.get('serverId'); let curItem = await getCurItem(roleId, itId); if (curItem.size == 0) { // console.log("---composeStoneByItId-- curItem=%s", curItem); return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); } let { allCostItem, allAddItem } = await getComposeStoneCostAndAdd(curItem, itId) if (!allCostItem || allCostItem.size == 0 || !allAddItem || allAddItem.size == 0) { // console.log("---composeStoneByItId-- allCostItem=%s, allAddItem=%s", allCostItem, allAddItem); return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); } let costResult = await handleCost(roleId, sid, [...allCostItem].map(([id, count]) => ({ id, count })), ITEM_CHANGE_REASON.COMPOSE_STONE); if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let arrAddItem = []; let total = 0; for (const [id, count] of allAddItem) { if (count == 0) continue; arrAddItem.push({ id, count }); total += count; } let goods = await addItems(roleId, roleName, sid, arrAddItem, ITEM_CHANGE_REASON.COMPOSE_STONE); await checkTaskInComposeStone(serverId, roleId, sid, total); return resResult(STATUS.SUCCESS, { goods }); } public async inheritJewel(msg: { originJewel: number, targetJewel: number }, session: BackendSession) { let { originJewel: originJewelId, targetJewel: targetJewelId } = msg; let roleId: string = session.get('roleId'); let sid: string = session.get('sid'); let serverId: number = session.get('serverId'); let originJewel = await JewelModel.findbySeqId(originJewelId); if (!originJewel || originJewel.roleId != roleId) return resResult(STATUS.JEWEL_IS_NOT_FIND); if (originJewel.hid > 0) return resResult(STATUS.JEWEL_HAS_EQUPED); let targetJewel = await JewelModel.findbySeqId(targetJewelId); if (!targetJewel || targetJewel.roleId != roleId) return resResult(STATUS.JEWEL_IS_NOT_FIND); if (isLocked(targetJewel.randSe)) return resResult(STATUS.JEWEL_LOCKED_CANNOT_INHERIT); let dicOldJewel = gameData.jewel.get(originJewel.id); if (!dicOldJewel) return resResult(STATUS.DIC_DATA_NOT_FOUND); let dicJewel = gameData.jewel.get(targetJewel.id); if (!dicJewel) return resResult(STATUS.DIC_DATA_NOT_FOUND); if (dicJewel.eplaceId != dicOldJewel.eplaceId || dicJewel.lv < dicOldJewel.lv) { return resResult(STATUS.JEWEL_CANNOT_INHERIT); } // 消耗 let consumeResult = await handleCost(roleId, sid, [ { id: originJewel.id, seqId: originJewel.seqId }, ...dicJewel.inheritConsume ], ITEM_CHANGE_REASON.JEWEL_INHERIT); if (!consumeResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let newRandSe = getRandSeResult(targetJewel.id, targetJewel.randSe, originJewel.randSe, originJewel.id); let newJewel = await JewelModel.updateInfo(targetJewel.seqId, { previewRandSe: [], randSe: newRandSe }); // 更新战力 if (targetJewel.hid > 0) { const hero = await HeroModel.findByHidAndRole(targetJewel.hid, roleId); await calculateCeWithHero(HERO_SYSTEM_TYPE.JEWEL_RESET_RANDSE, roleId, serverId, sid, targetJewel.hid, { ePlace: hero.ePlace }, { ePlaceId: targetJewel.ePlaceId, jewel: newJewel, skinId: hero.skinId }); } await checkTaskInEquipReset(serverId, roleId, sid); return resResult(STATUS.SUCCESS, { curJewel: pick(newJewel, ['seqId', 'id', 'hid', 'ePlaceId', 'randSe', 'previewRandSe']) }); } }