import { RougelikeRecordDetailType } from '../../db/RougelikeRecordDetail'; import { COLLECTION_TYPE, PUSH_ROUTE, ROUGE_LIKE_CARD_TYPE, TASK_ROUGE_CARD_TYPE, TASK_TYPE } from '../../consts'; import { genCode } from '../../pubUtils/util'; import { Card, RougelikeCharaModel, RougelikeCharaPara, RougelikeCharaType } from '../../db/RougelikeChara'; import { RougelikeCardPara, RougelikeCardModel } from '../../db/RougelikeCard'; import { CommonCard, CommonChara } from '../../pubUtils/interface'; import { RougelikeCollectionModel } from '../../db/RougelikeCollection'; import { sendMessageToUserWithSuc } from '../pushService'; import { gameData } from '../../pubUtils/data'; import { clone } from 'underscore'; import { RougeEffect, getSlotUnlockPoint } from './rougeEffectService'; import { BackendSession } from 'pinus'; import { checkTask } from '../task/taskService'; import { RougelikeRecordModel } from '../../db/RougelikeRecord'; import { updateMaxHp } from './rougeService'; export class HandleAddCard { roleId: string; sid: string; serverId: number; gameCode: string; getLayer: number = 0; getWay: number = 0; addCharas: RougelikeCharaPara[] = []; // 需要更新的角色 addPassiveCards: RougelikeCardPara[] = []; // 需要更新的特性卡 addHolyCards: RougelikeCardPara[] = []; // 需要更新的圣物 addCoin: number = 0; // 需要增加的试炼币 constructor(session: BackendSession, gameCode: string, recordDetail?: RougelikeRecordDetailType) { this.roleId = session.get('roleId'); this.sid = session.get('sid'); this.serverId = session.get('serverId'); this.gameCode = gameCode; if (recordDetail) { this.getLayer = recordDetail.layer; this.getWay = recordDetail.nodeType; } } private getCommonParam() { let { roleId, gameCode, getLayer, getWay } = this; return { roleId, gameCode, getLayer, getWay }; } public pushChara(id: number, maxHp: number, passiveCardIds: number[]) { let cards: Card[] = []; for (let index = 0; index < passiveCardIds.length; index++) { let cardId = passiveCardIds[index]; let cardCode = this.pushPassiveCard(cardId, id); cards.push({ index, cardCode, cardId }); } let charaCode = genCode(8); this.addCharas.push({ ...this.getCommonParam(), cards, charaCode, charaId: id, maxHp, hp: maxHp, ap: 0, shield: 0, others: '', roundSkill: 0, apSkill: 0 }); return charaCode; } public pushCard(id: number, rewardType: ROUGE_LIKE_CARD_TYPE, charaId: number = 0) { if (rewardType == ROUGE_LIKE_CARD_TYPE.PASSIVE) { return this.pushPassiveCard(id, charaId); } else if (rewardType == ROUGE_LIKE_CARD_TYPE.HOLY) { return this.pushHolyCard(id); } } public pushPassiveCard(id: number, charaId: number = 0) { let cardCode = genCode(8); this.addPassiveCards.push({ ...this.getCommonParam(), cardCode, cardId: id, type: ROUGE_LIKE_CARD_TYPE.PASSIVE, lv: gameData.rougePassiveCard.get(id)?.lv || 0, charaId }); return cardCode } public pushHolyCards(ids: number[]) { for (let id of ids) this.pushHolyCard(id); } public pushHolyCard(id: number) { let cardCode = genCode(8); this.addHolyCards.push({ ...this.getCommonParam(), cardCode, cardId: id, type: ROUGE_LIKE_CARD_TYPE.HOLY, useCount: 0 }); return cardCode } private getHolyUseCount(holyId: number) { const holyCardData = gameData.rougeHolyCard.get(holyId); return holyCardData?.useCount || 0; } public async save() { let result: { addCharas?: CommonChara[], addCards?: CommonCard[] } = {}; if (this.addCharas.length > 0) { let updateParams = this.addCharas || []; let resultArrs = await RougelikeCharaModel.createCharas(updateParams); this.addCharas = resultArrs; result.addCharas = resultArrs.map(param => new CommonChara(param)); } if (this.addPassiveCards.length > 0 || this.addHolyCards.length > 0) { let updateParams = [...(this.addPassiveCards || []), ...(this.addHolyCards || [])]; // await RougelikeCardModel.bulkWriteUpdate(updateParams); updateParams.map(async param => { const { gameCode, cardCode } = param; await RougelikeCardModel.updateByCode(gameCode, cardCode, { $set: param }) }); result.addCards = updateParams.map(param => new CommonCard(param)); } let collections: { type: number, id: number, addNum?: number }[] = []; for (let { cardId, type } of result.addCards || []) { if (type == ROUGE_LIKE_CARD_TYPE.PASSIVE) { collections.push({ type: COLLECTION_TYPE.PASSIVE_CARD, id: cardId }); } if (type == ROUGE_LIKE_CARD_TYPE.HOLY) collections.push({ type: COLLECTION_TYPE.HOLY_CARD, id: cardId }); } if (collections.length > 0) await addCollection(this.roleId, this.sid, this.gameCode, collections); //任务 if (this.addPassiveCards.length > 0) { let passiveCardMap = new Map(); for (const { cardId } of this.addPassiveCards) { const passiveCardData = gameData.rougePassiveCard.get(cardId); let count = passiveCardMap.get(passiveCardData.authorType) || 0; passiveCardMap.set(passiveCardData.authorType, count + 1); } for (const [authorType, count] of passiveCardMap) { await checkTask(this.serverId, this.roleId, this.sid, TASK_TYPE.ROUGE_AUTHOR_CARD_COLLECT, { authorType, cardType: TASK_ROUGE_CARD_TYPE.PASSIVE, cardIds: this.addPassiveCards.map(cur => cur.cardId) }); } } if (this.addHolyCards.length > 0) { await checkTask(this.serverId, this.roleId, this.sid, TASK_TYPE.ROUGE_HOLY_COLLECT, { cardIds: this.addHolyCards.map(cur => cur.cardId) }); } if (this.addCharas.length > 0) { result.addCharas = await this.getCharasByHolyEffect(); } return result; } // 处理获得角色卡时拥有圣物效果 public async getCharasByHolyEffect() { let result = await getSlotUnlockPoint(this.roleId, this.gameCode, this.addCharas || []); this.addCharas = result.dbCharas; if (result.isUpdate) { await RougelikeCharaModel.bulkWriteUpdate(this.addCharas || []); } return this.addCharas.map(param => new CommonChara(param)); } // 处理圣物效果 public async getHolyEffect() { let result: { addCharas?: CommonChara[], addCards?: CommonCard[] } = {}; let charasMap = (this.addCharas || []).reduce((result, cur) => { result.set(cur.charaCode, cur); return result; }, new Map()); let cardsMap = [...(this.addPassiveCards || []), ...(this.addHolyCards || [])].reduce((result, cur) => { result.set(cur.cardCode, cur); return result; }, new Map()); if ((this.addHolyCards || []).length > 0) { let rougeEffect = new RougeEffect(this.roleId, this.gameCode); let holyIds = clone(this.addHolyCards.map(cur => { return { cardCode: cur.cardCode, cardId: cur.cardId, useCount: cur.useCount } })); let { charas, cards } = await rougeEffect.getEffectImmediate(holyIds); if (charas && charas.size > 0) { await RougelikeCharaModel.bulkWriteUpdate([...charas.values()]); charasMap = new Map([...charasMap, ...charas]) } if (cards && cards.size > 0) { await RougelikeCardModel.bulkWriteUpdate([...cards.values()]) cardsMap = new Map([...cardsMap, ...cards]) } } result.addCharas = [...charasMap.values()].map(param => new CommonChara(param)); result.addCards = [...cardsMap.values()].map(param => new CommonCard(param)); const dbRecord = await RougelikeRecordModel.findByGameCode(this.gameCode); result.addCharas = await updateMaxHp(this.roleId, this.gameCode, (dbRecord?.type || 0), (dbRecord?.grade || 0), charasMap) return result; } } export function formateCharasOrCards(params: RougelikeCharaPara[] | RougelikeCardPara[], type: number) { let result: { charas?: CommonChara[], cards?: CommonCard[] } = {}; if (!params || params.length == 0) return result; const updateParams = params || []; if (type == ROUGE_LIKE_CARD_TYPE.CHARA) result.charas = updateParams.map(param => new CommonChara(param)); else result.cards = updateParams.map(param => new CommonCard(param)); return result; } export async function addCollection(roleId: string, sid: string, gameCode: string, arr: { type: number, id: number, addNum?: number }[]) { let collections: { type: number, id: number, num: number }[] = [], passiveCnt = 0; for (let { type, id, addNum = 1 } of arr) { if (type == COLLECTION_TYPE.PASSIVE_CARD_SUM) continue; let collection = await RougelikeCollectionModel.addRec(roleId, type, id, gameCode, addNum); if (!collection || collection.num > 1) continue; if (collection.num == 1) passiveCnt++; collections.push({ type, id, num: collection.num }); } if (passiveCnt > 0) { let collection = await RougelikeCollectionModel.addRec(roleId, COLLECTION_TYPE.PASSIVE_CARD_SUM, 0, gameCode, passiveCnt); collections.push({ type: COLLECTION_TYPE.PASSIVE_CARD, id: 0, num: collection.num }); } await sendMessageToUserWithSuc(roleId, PUSH_ROUTE.ROUGE_COLLECT_UPDATE, { collections }, sid); return collections; } export async function addSingleCollect(roleId: string, sid: string, gameCode: string, type: number, id: number) { return await addCollection(roleId, sid, gameCode, [{ type, id }]); } export async function addSameTypeCollect(roleId: string, sid: string, gameCode: string, type: number, ids: number[]) { return await addCollection(roleId, sid, gameCode, ids.map(id => ({ type, id }))); }