import { STATUS } from '../../../consts/statusCode'; import { RoleModel } from './../../../db/Role'; import { HeroModel } from '../../../db/Hero'; import { resResult, decodeIdCntArrayStr, parseGoodStr } from '../../../pubUtils/util'; import { Application, BackendSession, pinus } from 'pinus'; import { handleCost, addItems, createHeroes } from '../../../services/rewardService'; import { getTitle, getTeraph, gameData, getScollByStar, getFriendLvByExp, getHeroExpByLv } from '../../../pubUtils/data'; import { SCHOOL, SCROLL, EXTERIOR, SCRIPT } from '../../../pubUtils/dicParam'; import { getAtrrNameById } from '../../../consts/constModules/abilityConst' import { findIndex } from 'underscore'; import { SclResultInter, SclPosInter } from '../../../pubUtils/interface'; import { SchoolModel } from '../../../db/School'; import { checkTeraphMaterialEnough, getSchoolList } from '../../../services/roleService' import { calPlayerCeAndSave, calAllHeroCe } from '../../../services/playerCeService'; import { HERO_SYSTEM_TYPE, LINEUP_NUM, ROLE_SELECT, REDIS_KEY, TASK_TYPE, DEFAULT_HEROES, DEFAULT_HERO_LV, DEFAULT_ITEMS, DEFAULT_EQUIPS, DEFAULT_GOLD, DEFAULT_COIN } from '../../../consts'; import { checkBattleHeroesByHid } from '../../../services/normalBattleService'; import { Rank } from '../../../services/rankService'; import { updateUserInfo } from '../../../services/redisService'; import { checkTaskWithHero, checkTask, checkTaskWithArgs, checkActivityTask } from '../../../services/taskService'; import { getGoldObject, getCoinObject } from '../../../pubUtils/itemUtils'; import { RScriptRecordModel } from '../../../db/RScriptRecord'; import { checkPvp } from '../../../services/pvpService'; export default function (app: Application) { return new RoleHandler(app); } export class RoleHandler { constructor(private app: Application) { } async initRole(msg: { roleName: string }, session: BackendSession) { let roleId = session.get('roleId'); let serverId = session.get('serverId'); let sid: string = session.get('sid'); let funcs: number[] = session.get('funcs'); let { roleName } = msg; let role = await RoleModel.findByRoleId(roleId, 'roleName hasInit', true); if (role.hasInit) return resResult(STATUS.ROLE_HAS_INIT); let checkName = await RoleModel.checkName(roleName, serverId); if (checkName) return resResult(STATUS.NAME_HAS_USED); let heroInfos = []; for (let hid of DEFAULT_HEROES) { heroInfos.push({ hid, lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0 }); } let heroes = await createHeroes(roleId, roleName, sid, serverId, funcs, heroInfos); session.set('roleName', roleName); session.push('roleName', () => { }); let items = [].concat(DEFAULT_ITEMS, DEFAULT_EQUIPS, [getGoldObject(DEFAULT_GOLD)], [getCoinObject(DEFAULT_COIN)]); await addItems(roleId, roleName, sid, items); role = await RoleModel.updateRoleInfo(roleId, { hasInit: true, roleName }, true) let battleId = SCRIPT.SCRIPT_BATTLE_ID; let warInfo = gameData.war.get(battleId); await RScriptRecordModel.setScript(roleId, battleId, warInfo.warType, 2, SCRIPT.SCRIPT_NAME); await checkPvp(role); return resResult(STATUS.SUCCESS, { roleId, roleName, heroes }) } async getRoleInfo(msg: { targetRoleId: string }, session: BackendSession) { let { targetRoleId } = msg; let { roleId, roleName, head = EXTERIOR.EXTERIOR_FACE, frame = EXTERIOR.EXTERIOR_FACECASE, spine = EXTERIOR.EXTERIOR_APPEARANCE, ce = 0, topLineup, topLineupCe = 0 } = await RoleModel.findByRoleId(targetRoleId); return resResult(STATUS.SUCCESS, { roleId, roleName, head, frame, spine, ce, topLineup, topLineupCe }); } //爵位 async roleTitleLevelUp(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let sid: string = session.get('sid'); const serverId = session.get('serverId'); let funcs: number[] = session.get('funcs'); let role = await RoleModel.findByRoleId(roleId); let { title } = role; let titleInfo = getTitle(title + 1); if (!titleInfo) return resResult(STATUS.DIC_DATA_NOT_FOUND) if (titleInfo.lvLimited > role.lv) return resResult(STATUS.COM_BATTLE_LV_NOT_ENOUGH) let consumes = titleInfo.material; let result = await handleCost(roleId, sid, consumes); if (!result) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); let update = { title: title + 1 } role = await calAllHeroCe(HERO_SYSTEM_TYPE.TITLE, sid, roleId, update); // 任务 await checkTask(roleId, sid, funcs, TASK_TYPE.ROLE_TITLE, 1, false, { title }); //成长任务 await checkActivityTask(serverId, sid, funcs, roleId, TASK_TYPE.ROLE_TITLE, update.title) return resResult(STATUS.SUCCESS, { roleId, title: role.title }); } //神像强化 async roleTeraphStrengthen(msg: { id: number, count: number }, session: BackendSession) { let { id, count } = msg; let roleId = session.get('roleId'); let sid: string = session.get('sid'); let funcs: number[] = session.get('funcs'); let role = await RoleModel.findByRoleId(roleId); let teraphs = role.teraphs; let index = findIndex(teraphs, { id }); if (index < 0) return resResult(STATUS.WRONG_PARMS); let teraph = teraphs[index]; let dicTeraph = getTeraph(id, teraph.grade); if (!dicTeraph) return resResult(STATUS.DIC_DATA_NOT_FOUND); let attrs = new Array(); // 可以强化的属性 dicTeraph.mainAttrMax.forEach((max, id) => { let attrName = getAtrrNameById(id); if (teraph[attrName] < max) { attrs.push(id); } }); if (!attrs.length) return resResult(STATUS.ROLE_TERAPH_NOT_STRENGTHEN); // 随机神像中的一条属性并检查道具是否足够,以及更新teraph let { consumes } = checkTeraphMaterialEnough(count, attrs, dicTeraph, teraph); let result = await handleCost(roleId, sid, consumes); if (!result) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); role = await calAllHeroCe(HERO_SYSTEM_TYPE.TERAPH, sid, roleId, { teraphs }, [id]); // 任务 await checkTask(roleId, sid, funcs, TASK_TYPE.ROLE_TERAPH_STRENGTHEN, count, true, {}); return resResult(STATUS.SUCCESS, { roleId, teraphs: role.teraphs }); } //神像进阶 async roleTeraphQualityUp(msg: { id: number }, session: BackendSession) { let { id } = msg; let roleId = session.get('roleId'); let sid: string = session.get('sid'); const serverId = session.get('serverId'); let funcs: number[] = session.get('funcs'); let role = await RoleModel.findByRoleId(roleId); let teraphs = role.teraphs; let index = findIndex(teraphs, { id }); if (index < 0) return resResult(STATUS.WRONG_PARMS); let teraph = teraphs[index]; let teraphInfo = getTeraph(id, teraph.grade); if (!teraphInfo) return resResult(STATUS.DIC_DATA_NOT_FOUND) for (let [attrId, val] of teraph.attr) { if (val < teraphInfo.mainAttrMax.get(attrId)) return resResult(STATUS.ROLE_TERAPH_NOT_QUILITY); teraph.attr.set(attrId, 0); } teraph.grade++; let nextTeraphInfo = getTeraph(id, teraph.grade) if (!nextTeraphInfo) return resResult(STATUS.DIC_DATA_NOT_FOUND); let consumes = teraphInfo.upGradeMaterial; let result = await handleCost(roleId, sid, consumes); if (!result) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); role = await calAllHeroCe(HERO_SYSTEM_TYPE.TERAPH_UP, sid, roleId, { teraphs }, [id]); // 神像进阶,进阶一次就触发一次礼包弹框 await checkActivityTask(serverId, sid, funcs, roleId, TASK_TYPE.ROLE_TERAPH_STAGE_UP, 1) return resResult(STATUS.SUCCESS, { roleId, teraphs: role.teraphs }); } // 获得百家学宫 async getSchoolList(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let school = await getSchoolList(roleId); return resResult(STATUS.SUCCESS, { school }); } // 摆放/替换/卸下武将 async changeSchoolHero(msg: { schoolId: number, positionId: number, hid: number }, session: BackendSession) { let roleId = session.get('roleId'); let sid = session.get('sid'); let funcs: number[] = session.get('funcs'); const serverId = session.get('serverId'); let { schoolId, positionId, hid } = msg; if (!gameData.school.has(schoolId)) { return resResult(STATUS.DIC_DATA_NOT_FOUND); } const dicPosition = decodeIdCntArrayStr(SCHOOL.SCHOOL_POSITION, 1); // id(str) => isOpen if (!dicPosition.has(positionId.toString())) { return resResult(STATUS.DIC_DATA_NOT_FOUND); } let isOpen = !!dicPosition.get(positionId.toString()); // 该位置是否解锁 if (hid > 0) { let findHero = await SchoolModel.findByHid(roleId, hid); if (!!findHero) { return resResult(STATUS.ROLE_SCHOOL_HERO_USED); } let curHero = await HeroModel.findByHidAndRole(hid, roleId); if (!curHero) return resResult(STATUS.HERO_NOT_FIND); } let curSchool = await SchoolModel.findBySclAndPos(roleId, schoolId, positionId); let preHid = 0; // 原先在该位置上的武将 if (curSchool) { isOpen = curSchool.isOpen; preHid = curSchool.hid; } if (!isOpen) { return resResult(STATUS.ROLE_SCHOOL_POSITION_LOCKED); } await SchoolModel.updateBySclAndPos(roleId, schoolId, positionId, { hid, isOpen }) await calAllHeroCe(HERO_SYSTEM_TYPE.SCHOOL, sid, roleId, {}, [schoolId, hid, preHid]); // 任务 await checkTaskWithArgs(roleId, sid, funcs, TASK_TYPE.ROLE_SCHOOL_UNLOCK, [hid, preHid]); if (hid > 0) { //成长任务 await checkActivityTask(serverId, sid, funcs, roleId, TASK_TYPE.ROLE_SCHOOL_PUT_HERO, 1) } return resResult(STATUS.SUCCESS, { schoolId, positionId, hid, preHid, isOpen }); } // 解锁位置 async unlockSchoolPosition(msg: { schoolId: number, positionId: number }, session: BackendSession) { let roleId = session.get('roleId'); let sid = session.get('sid'); let funcs: number[] = session.get('funcs'); let { schoolId, positionId } = msg; if (!gameData.school.has(schoolId)) { return resResult(STATUS.DIC_DATA_NOT_FOUND); } const dicPosition = decodeIdCntArrayStr(SCHOOL.SCHOOL_POSITION, 1); // id(str) => isOpen if (!dicPosition.has(positionId.toString())) { return resResult(STATUS.DIC_DATA_NOT_FOUND); } let isOpen = !!dicPosition.get(positionId.toString()); // 该位置是否解锁 if (isOpen) { return resResult(STATUS.ROLE_SCHOOL_POSITION_UNLOCK_NOT_NEED); } let curSchool = await SchoolModel.findBySclAndPos(roleId, schoolId, positionId); if (curSchool && curSchool.isOpen) { return resResult(STATUS.ROLE_SCHOOL_POSITION_UNLOCK_NOT_NEED); } const cost = parseGoodStr(SCHOOL.SCHOOL_UNLOCK_COIN); const costResult = await handleCost(roleId, sid, cost); if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); curSchool = await SchoolModel.updateBySclAndPos(roleId, schoolId, positionId, { isOpen: true }) // 任务 await checkTask(roleId, sid, funcs, TASK_TYPE.ROLE_SCHOOL_UNLOCK, 1, true, {}); return resResult(STATUS.SUCCESS, { schoolId, positionId, hid: curSchool.hid, isOpen: curSchool.isOpen }); } // 激活/升级名将谱 async activeHeroScroll(msg: { hid: number }, session: BackendSession) { let roleId = session.get('roleId'); let sid = session.get('sid'); let funcs: number[] = session.get('funcs'); let serverId: number = session.get('serverId'); let { hid } = msg; let curHero = await HeroModel.findByHidAndRole(hid, roleId, 'hid star colorStar quality scrollId scrollActive scrollStar scrollColorStar scrollQuality favour favourLv connections attr ce'); if (!curHero) return resResult(STATUS.HERO_NOT_FIND); let dicHero = gameData.hero.get(hid); if (!dicHero) return resResult(STATUS.DIC_DATA_NOT_FOUND); let { star, colorStar, quality, scrollId, scrollActive, scrollStar, scrollColorStar, scrollQuality, favour, favourLv } = curHero; let update = { scrollActive, scrollId, scrollStar, scrollColorStar, scrollQuality, favour, favourLv }; if (!scrollActive) { // 初次激活 update.scrollActive = true; update.scrollStar = dicHero.initialStars; update.scrollQuality = dicHero.quality; update.scrollColorStar = 0; // 获取一定好感度 let maxLv = gameData.maxFriendShipLv.max; if (maxLv > favourLv) { update.favour += SCROLL.SCROLL_ACTIVE_FAVOUR; update.favourLv = getFriendLvByExp(update.favour); } await checkActivityTask(serverId, sid, funcs, roleId, TASK_TYPE.HERO_UNLOCK, 1, { dicHeroes: [dicHero] }) } else { if (star > scrollStar) { // 可以升星 update.scrollStar++; } else if (quality > scrollQuality) { // 可以升品 update.scrollQuality++; } else if (colorStar > scrollColorStar) { // 可以升彩星 update.scrollColorStar++; } else { return resResult(STATUS.ROLE_SCROLL_REACH_MAX); } } let dicHeroScroll = getScollByStar(dicHero.quality, update.scrollStar, update.scrollQuality, update.scrollColorStar); update.scrollId = dicHeroScroll ? dicHeroScroll.id : 0; let hero = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.SCROLL, sid, roleId, curHero, update); // 更新单个武将战力 calAllHeroCe(HERO_SYSTEM_TYPE.SCROLL, sid, roleId, {}, [hid]); // 全局增加战力 // 任务 if (favourLv != hero.favourLv) await checkTaskWithHero(roleId, sid, funcs, TASK_TYPE.HERO_FAVOUR_LV, hero); if (!scrollActive) await checkTask(roleId, sid, funcs, TASK_TYPE.ROLE_SCROLL_ACTIVE, 1, true, {}); return resResult(STATUS.SUCCESS, { curHero: { hid: hero.hid, scrollActive: hero.scrollActive, scrollId: hero.scrollId, scrollStar: hero.scrollStar, scrollColorStar: hero.scrollColorStar, scrollQuality: hero.scrollQuality, favour: hero.favour, favourLv: hero.favourLv, } }); } // 防沉迷调试用,推送窗口 async debugPlayerTime(msg: { type: number }, session: BackendSession) { let { type } = msg; let roleId = session.get('roleId'); let sid = session.get('sid'); if (type == 1) { pinus.app.channelService.pushMessageByUids('onPlayTime', resResult(STATUS.SUCCESS, { isGuest: true, guestTime: 60 * 60, // 游客已体验时间 hasAuthenticated: false, // 是否进行过实名认证 isAdult: false, // 是否已成年 todayPlayTime: 60 * 60, // 今天已游戏时长 type: 1 }), [{ uid: roleId, sid: sid }]); } else if (type == 2) { pinus.app.channelService.pushMessageByUids('onPlayTime', resResult(STATUS.SUCCESS, { isGuest: false, guestTime: 0, // 游客已体验时间 hasAuthenticated: true, // 是否进行过实名认证 isAdult: false, // 是否已成年 todayPlayTime: 60 * 60, // 今天已游戏时长 type: 2 }), [{ uid: roleId, sid: sid }]); } else if (type == 3) { pinus.app.channelService.pushMessageByUids('onPlayTime', resResult(STATUS.SUCCESS, { isGuest: false, guestTime: 0, // 游客已体验时间 hasAuthenticated: true, // 是否进行过实名认证 isAdult: false, // 是否已成年 todayPlayTime: 3 * 60 * 60, // 今天已游戏时长 type: 3 }), [{ uid: roleId, sid: sid }]); } else if (type == 4) { pinus.app.channelService.pushMessageByUids('onPlayTime', resResult(STATUS.SUCCESS, { isGuest: false, guestTime: 0, // 游客已体验时间 hasAuthenticated: true, // 是否进行过实名认证 isAdult: false, // 是否已成年 todayPlayTime: 1.5 * 60 * 60, // 今天已游戏时长 type: 4 }), [{ uid: roleId, sid: sid }]); } return resResult(STATUS.SUCCESS); } // 保存展示阵容 async saveShowLineup(msg: { showLineup: number[] }, session: BackendSession) { let { showLineup } = msg; let roleId = session.get('roleId'); let serverId = session.get('serverId'); let checkHeroes = await checkBattleHeroesByHid(roleId, showLineup); if (showLineup.length > 0 && !checkHeroes) return resResult(STATUS.BATTLE_HERO_NOT_FOUND); if (showLineup.length > LINEUP_NUM) { return resResult(STATUS.LINEUP_MAX); } let role = await RoleModel.updateRoleInfo(roleId, { showLineup }); let r = new Rank(REDIS_KEY.SHOW_LINEUP, {}); await r.generParamAndSet(REDIS_KEY.SHOW_LINEUP, { roleId }, { role }); return resResult(STATUS.SUCCESS, { showLineup: role.showLineup }); } // 更换头像 async setHead(msg: { id: number }, session: BackendSession) { let { id } = msg; let roleId = session.get('roleId'); let role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS); if (!role) return resResult(STATUS.ROLE_NOT_FOUND); let { heads } = role; let curHead = heads.find(cur => cur.id == id); if (!curHead) return resResult(STATUS.HEAD_NOT_FOUND); if (curHead.enable) return resResult(STATUS.HEAD_IS_WEARING); if (!curHead.status) return resResult(STATUS.HEAD_IS_LOCKED); let oldHead = heads.find(cur => cur.enable); // 穿戴中的头像 if (oldHead) { oldHead.enable = false; } curHead.enable = true; role = await RoleModel.updateRoleInfo(roleId, { heads }); await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'head', value: id }]); return resResult(STATUS.SUCCESS, { heads: role.heads, head: role.head }); } // 更换相框 async setFrame(msg: { id: number }, session: BackendSession) { let { id } = msg; let roleId = session.get('roleId'); let role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS); if (!role) return resResult(STATUS.ROLE_NOT_FOUND); let { frames } = role; let curFrame = frames.find(cur => cur.id == id); if (!curFrame) return resResult(STATUS.FRAME_NOT_FOUND); if (curFrame.enable) return resResult(STATUS.FRAME_IS_WEARING); if (!curFrame.status) return resResult(STATUS.FRAME_IS_LOCKED); let oldHead = frames.find(cur => cur.enable); // 穿戴中的头像 if (oldHead) { oldHead.enable = false; } curFrame.enable = true; role = await RoleModel.updateRoleInfo(roleId, { frames }); await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'frame', value: id }]); return resResult(STATUS.SUCCESS, { frames: role.frames, frame: role.frame }); } // 更换形象 async setSpine(msg: { id: number }, session: BackendSession) { let { id } = msg; let roleId = session.get('roleId'); let role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS); if (!role) return resResult(STATUS.ROLE_NOT_FOUND); let { spines } = role; let curSpine = spines.find(cur => cur.id == id); if (!curSpine) return resResult(STATUS.SPINE_NOT_FOUND); if (curSpine.enable) return resResult(STATUS.SPINE_IS_WEARING); if (!curSpine.status) return resResult(STATUS.SPINE_IS_LOCKED); let oldHead = spines.find(cur => cur.enable); // 穿戴中的头像 if (oldHead) { oldHead.enable = false; } curSpine.enable = true; role = await RoleModel.updateRoleInfo(roleId, { spines }); await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'spine', value: id }]); return resResult(STATUS.SUCCESS, { spines: role.spines, spine: role.spine }); } // 改名 async rename(msg: { roleName: string }, session: BackendSession) { let { roleName } = msg; let roleId = session.get('roleId'); let serverId = session.get('serverId'); let checkName = await RoleModel.checkName(roleName, serverId); if (checkName) return resResult(STATUS.NAME_HAS_USED); let role = await RoleModel.updateRoleInfo(roleId, { roleName }); session.set('roleName', role.roleName); session.push('roleName', () => { }); await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'roleName', value: roleName }]); return resResult(STATUS.SUCCESS, { roleName: role.roleName }); } }