854 lines
38 KiB
TypeScript
854 lines
38 KiB
TypeScript
import { Application, BackendSession, HandlerService, } from "pinus";
|
|
import { STATUS, HERO_SYSTEM_TYPE, ITEM_CHANGE_REASON, TASK_TYPE, CONSUME_TYPE, RESONANCE } 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";
|
|
import { getResonanceDataMap } from "../../../services/role/resonanceService";
|
|
|
|
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 { dbResonanceMap } = await getResonanceDataMap(roleId);
|
|
if(dbResonanceMap.has(hid)) return resResult(STATUS.RESONANCE__HID_NOT_CAN);
|
|
|
|
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 { dbResonanceMap } = await getResonanceDataMap(roleId);
|
|
if(dbResonanceMap.has(hid)) return resResult(STATUS.RESONANCE__HID_NOT_CAN);
|
|
|
|
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<number, { lv: number }>(); // 更新了的装备栏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 { dbResonanceMap } = await getResonanceDataMap(roleId);
|
|
if(dbResonanceMap.has(hid)) return resResult(STATUS.RESONANCE__HID_NOT_CAN);
|
|
|
|
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 { dbResonanceMap } = await getResonanceDataMap(roleId);
|
|
if(dbResonanceMap.has(hid)) return resResult(STATUS.RESONANCE__HID_NOT_CAN);
|
|
|
|
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 { dbResonanceMap } = await getResonanceDataMap(roleId);
|
|
if(dbResonanceMap.has(hid) && RESONANCE.JEWEL) return resResult(STATUS.RESONANCE__HID_NOT_CAN);
|
|
|
|
|
|
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<EPlace>[] };
|
|
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 { dbResonanceMap } = await getResonanceDataMap(roleId);
|
|
if(dbResonanceMap.has(hid) && RESONANCE.JEWEL) return resResult(STATUS.RESONANCE__HID_NOT_CAN);
|
|
|
|
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 { dbResonanceMap } = await getResonanceDataMap(roleId);
|
|
if(dbResonanceMap.has(hid) && RESONANCE.STONE) return resResult(STATUS.RESONANCE__HID_NOT_CAN);
|
|
|
|
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']) });
|
|
}
|
|
|
|
} |