import { Application, BackendSession, HandlerService, } from "pinus"; import { STATUS, HERO_SYSTEM_TYPE, ITEM_CHANGE_REASON } from "../../../consts"; import { gameData, getDicAuthorBookSub } from "../../../pubUtils/data"; import { RewardInter } from "../../../pubUtils/interface"; import { resResult } from "../../../pubUtils/util"; import { calculateCeWithRole } from "../../../services/playerCeService"; import { CheckMeterial } from "../../../services/role/checkMaterial"; import { addItems, handleCost } from "../../../services/role/rewardService"; import { combineItems } from "../../../services/role/util"; import { AuthorBookModel } from "../../../db/AuthorBook"; import { checkAuthorBookLimit, replaceAuthorBooks } from "../../../services/roleService"; export default function (app: Application) { new HandlerService(app, {}); return new AuthorsBookHandler(app); } export class AuthorsBookHandler { constructor(private app: Application) { } public async starUp(msg: { bookId: number, subId: number, star: number, useItem: boolean }, session: BackendSession) { const roleId: string = session.get('roleId'); const sid: string = session.get('sid'); const roleName: string = session.get('roleName'); const serverId: number = session.get('serverId'); const { bookId, subId, star, useItem } = msg; let allAuthorBooks = await AuthorBookModel.findByRoleId(roleId); let authorBookData = allAuthorBooks.find(authorBook => authorBook.bookId == bookId); let starInData = authorBookData?.authors?.find(cur => cur.subId == subId)?.star??0; if(star != starInData) return resResult(STATUS.ACCESS_BUSY); let dicAuthorsBookSub = getDicAuthorBookSub(bookId, subId, star + 1); if(!dicAuthorsBookSub) return resResult(STATUS.AUTHOR_BOOK_SUB_MAX); // 是否解锁(进度解锁) if(!checkAuthorBookLimit(allAuthorBooks, bookId)) return resResult(STATUS.AUTHOR_BOOK_LOCK); // 英灵是否够 let check = new CheckMeterial(roleId); let isEnough = await check.decreaseItemsContinue(dicAuthorsBookSub.spirits); let useItemCnt = 0; if(useItem) { // 使用英灵石代替 if(!isEnough) { let notEnoughItems = check.getNotEnoughItems(); let replaceItems: RewardInter[] = []; for(let [ id, count ] of notEnoughItems) { let dicSpirit = gameData.spirit.get(id); if(!dicSpirit) return resResult(STATUS.DIC_DATA_NOT_FOUND); // 应该是表填错,正常情况不可能出现 for(let item of dicSpirit.composeItem) { replaceItems.push({ id: item.id, count: item.count * count }); useItemCnt += item.count * count; } } isEnough = await check.decreaseItemsContinue(replaceItems); } } if(!isEnough) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let consumes = check.getConsume(); let costResult = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.AUTHOR_BOOK_STAR_UP); if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); // 升星 authorBookData = await AuthorBookModel.upStar(roleId, bookId, subId, star, dicAuthorsBookSub.value, gameData.authorBookSubs.get(bookId)||[]); if(!authorBookData) { // 防并发问题 await addItems(roleId, roleName, sid, consumes, ITEM_CHANGE_REASON.AUTHOR_BOOK_STAR_RETURN); return resResult(STATUS.ACCESS_BUSY); } // 计算战力更新 await calculateCeWithRole(HERO_SYSTEM_TYPE.AUTHOR_BOOK_STAR, roleId, serverId, sid, {}, { authorBooks: replaceAuthorBooks(allAuthorBooks, authorBookData), bookId, subId }); let curAuthorBook = authorBookData.authors?.find(cur => cur.subId == subId); let maxProgress = gameData.authorBookMaxProgress.get(bookId)??0; return resResult(STATUS.SUCCESS, { bookId, subId, star: curAuthorBook?.star??0, progress: authorBookData.progress, maxProgress, useItemCnt }); } // 重置条目 public async resetAuthor(msg: { bookId: number, subId: number, star: number }, session: BackendSession) { const roleId: string = session.get('roleId'); const sid: string = session.get('sid'); const roleName: string = session.get('roleName'); const serverId: number = session.get('serverId'); const { bookId, subId, star } = msg; let allAuthorBooks = await AuthorBookModel.findByRoleId(roleId); let authorBookData = allAuthorBooks.find(authorBook => authorBook.bookId == bookId); if(!authorBookData) return resResult(STATUS.ACCESS_BUSY) let starInData = authorBookData?.authors?.find(cur => cur.subId == subId)?.star??0; if(star != starInData) return resResult(STATUS.ACCESS_BUSY); let progress = 0, spirits: RewardInter[] = []; for(let i = 1; i <= star; i++) { let dicAuthorsBookSub = getDicAuthorBookSub(bookId, subId, i); if(!dicAuthorsBookSub) return resResult(STATUS.DIC_DATA_NOT_FOUND); progress += dicAuthorsBookSub.value; spirits.push(...dicAuthorsBookSub.spirits); } // 重置诸子列传 authorBookData = await AuthorBookModel.resetSub(roleId, bookId, subId, star, -progress); if(!authorBookData) return resResult(STATUS.ACCESS_BUSY); let goods = await addItems(roleId, roleName, sid, combineItems(spirits), ITEM_CHANGE_REASON.AUTHOR_BOOK_SUB_RESET); // 计算战力更新 await calculateCeWithRole(HERO_SYSTEM_TYPE.AUTHOR_BOOK_SUB_RESET, roleId, serverId, sid, {}, { authorBooks: replaceAuthorBooks(allAuthorBooks, authorBookData), bookId, subId }); let curAuthorBook = authorBookData.authors?.find(cur => cur.subId == subId); let maxProgress = gameData.authorBookMaxProgress.get(bookId)??0; return resResult(STATUS.SUCCESS, { bookId, subId, star: curAuthorBook?.star??0, progress: authorBookData.progress, maxProgress, goods }); } // 买英灵 public async buySpirit(msg: { id: number, count: number }, session: BackendSession) { let roleId: string = session.get('roleId'); let sid: string = session.get('sid'); let roleName: string = session.get('roleName'); const { id, count } = msg; let dicSpirit = gameData.spirit.get(id); if(!dicSpirit) return resResult(STATUS.DIC_DATA_NOT_FOUND); let consumes = dicSpirit.composeItem.map(cur => ({ id: cur.id, count: cur.count * count })); let costResult = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.BUY_SPIRIT); if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let reward = [{ id, count }]; let goods = await addItems(roleId, roleName, sid, reward, ITEM_CHANGE_REASON.BUY_SPIRIT); return resResult(STATUS.SUCCESS, { goods }); } public async decomposeSpirit(msg: { spirits: { id: number, count: number }[] }, session: BackendSession) { let roleId: string = session.get('roleId'); let sid: string = session.get('sid'); let roleName: string = session.get('roleName'); const { spirits = [] } = msg; let rewards: RewardInter[] = []; for(let { id, count } of spirits) { let dicSpirit = gameData.spirit.get(id); if(!dicSpirit) return resResult(STATUS.DIC_DATA_NOT_FOUND); for(let item of dicSpirit.decomposeItem) { rewards.push({ id: item.id, count: item.count * count }); } } let consumes = spirits; let costResult = await handleCost(roleId, sid, consumes, ITEM_CHANGE_REASON.DECOMPOSE_SPIRIT); if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let goods = await addItems(roleId, roleName, sid, combineItems(rewards), ITEM_CHANGE_REASON.DECOMPOSE_SPIRIT); return resResult(STATUS.SUCCESS, { goods }); } }