import { Application, BackendSession, HandlerService, } from 'pinus'; import { BattleRecordModel } from '../../../db/BattleRecord'; import { ExpeditionRecordModel } from '../../../db/ExpeditionRecord'; import { ExpeditionWarRecordModel } from '../../../db/ExpeditionWarRecord'; import { ExpeditionPointModel } from '../../../db/ExpeditionPoint'; import { RoleModel } from '../../../db/Role'; import { calculateSumCE, genCode } from '../../../pubUtils/util'; import { getPointRewardStatus, getResetRemainCnt, findOrCreateEnemies, getExpeditionStatus } from '../../../services/expeditionService'; import { EXPEDITION_CONST, EXPEDITION_WAR_RECORD_STATUS, LINEUP_NUM, TASK_TYPE } from '../../../consts'; import { WarReward } from '../../../services/warRewardService'; import { addItems } from '../../../services/rewardService'; import { getAp, setAp } from '../../../services/actionPointService'; import { STATUS } from '../../../consts/statusCode'; import { resResult } from '../../../pubUtils/util'; import { checkBattleHeroes, roleLevelup } from '../../../services/normalBattleService'; import { checkActivityTask, checkTask, checkTaskInBattleEnd } from '../../../services/taskService'; import { gameData } from '../../../pubUtils/data'; export default function (app: Application) { new HandlerService(app, {}); return new ExpeditionBattleHandler(app); } export class ExpeditionBattleHandler { constructor(private app: Application) { } /** * 获取初始数据 * 获取当前远征挑战情况,远征点数,点数宝箱领取情况 */ async getStatus(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let res = await getExpeditionStatus(roleId, roleName); if (!res) return resResult(STATUS.ROLE_IS_NOT_INIT); return resResult(STATUS.SUCCESS, res); } /** * 重置远征本 * 每天5点可以重置远征本 */ async resetStatus(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let curTime = new Date(); let { needRefresh, resetCnt } = await getResetRemainCnt(curTime, roleId); if (resetCnt <= 0) { return resResult(STATUS.EXPEDITION_RESET_NUM_NOT_ENOUGH) } await ExpeditionRecordModel.hideRecord(roleId); // 刷掉旧关卡 // 我方战力(暂定) let myCe = await calculateSumCE(roleId, 1, { num: LINEUP_NUM }); // 每一关的挑战状态 let { expeditionCode, heroes } = await ExpeditionRecordModel.createRecord({ roleId, roleName, heroes: [], myCe }); await findOrCreateEnemies(roleId, myCe, expeditionCode, 1, EXPEDITION_WAR_RECORD_STATUS.WAITING); await RoleModel.increaseExpeditionResetCnt(roleId, needRefresh, curTime); let expeditionWarRecord = await ExpeditionWarRecordModel.getRecordByCode(expeditionCode); let curLv = 0; if (expeditionWarRecord.length > 0) { curLv = expeditionWarRecord[expeditionWarRecord.length - 1].expeditionId; } return resResult(STATUS.SUCCESS, { expeditionCode, curLv, expeditionWarRecord, heroes, resetCnt: resetCnt - 1 }); } /** * 获取敌军数据 * 匹配其他玩家,或机器人数据 */ async getEnemies(msg: { expeditionCode: string, expeditionId: number }, session: BackendSession) { const roleId = session.get('roleId'); // const roleName = session.get('roleName'); const { expeditionCode, expeditionId } = msg; let { myCe } = await ExpeditionRecordModel.getExpeditionRecordByCode(expeditionCode); let curExpeditionWarRecord = await findOrCreateEnemies(roleId, myCe, expeditionCode, expeditionId, EXPEDITION_WAR_RECORD_STATUS.WAITING); if (!curExpeditionWarRecord) { return resResult(STATUS.EXPEDITION_MATCH_NO_PLAYER); } let { battleId, enemyFrom, enemies, battleStatus, ce: curCe } = curExpeditionWarRecord; let nextCe = 0; // 下一关战力 if (gameData.expedition.has(expeditionId + 1)) { let nextExpeditionWarRecord = await findOrCreateEnemies(roleId, myCe, expeditionCode, expeditionId + 1, EXPEDITION_WAR_RECORD_STATUS.HIDE); if (nextExpeditionWarRecord) nextCe = nextExpeditionWarRecord.ce; } return resResult(STATUS.SUCCESS, { expeditionCode, expeditionId, battleId, battleStatus, enemyFrom, enemies, curCe, nextCe }); } /** * 进入战斗 * 记录我军数据,生成战斗唯一表示,记录状态 */ async checkBattle(msg: { expeditionCode: string, expeditionId: number, battleId: number, heroes: Array }, session: BackendSession) { const { expeditionCode, expeditionId, battleId, heroes: seqIds = [] } = msg; let roleId = session.get('roleId'); let roleName = session.get('roleName'); let warInfo = gameData.war.get(battleId); if (!warInfo) { return resResult(STATUS.BATTLE_MISS_INFO); } let role = await RoleModel.findByRoleId(roleId, 'lv'); let apJson = await getAp(roleId, role.lv); let { ap } = apJson; if (ap < warInfo.cost) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); } // 前置关卡是否挑战过 let previousGk = warInfo.previousGk; if (previousGk) { let preBattle = await BattleRecordModel.getBattleRecordByIdAndStatus(roleId, previousGk, 1); if (!preBattle) return resResult(STATUS.BATTLE_NEED_PREVIOUS_GK); } let { isOK, heroes } = await checkBattleHeroes(roleId, seqIds); if (!isOK) return resResult(STATUS.BATTLE_HERO_NOT_FOUND); let expeditionWarRecord = await ExpeditionWarRecordModel.getRecordByCodeAndId(expeditionCode, expeditionId); if (!expeditionWarRecord) { return resResult(STATUS.EXPEDITION_MISS_WAR_RECORD); } if (expeditionWarRecord.battleStatus == EXPEDITION_WAR_RECORD_STATUS.SUCCESS) { return resResult(STATUS.EXPEDITION_DUPLICATE_CHALLENGE); } const battleCode = genCode(8); await BattleRecordModel.updateBattleRecordByCode(battleCode, { $set: { roleId, roleName, battleId, status: 0, warName: warInfo.gk_name, warType: warInfo.warType, record: { heroes, seqIds } } }, true); let result = await ExpeditionWarRecordModel.updateBattleCode(expeditionCode, expeditionId, EXPEDITION_WAR_RECORD_STATUS.WAITING, battleCode); return resResult(STATUS.SUCCESS, { expeditionCode, expeditionId, battleId, battleCode, battleStatus: result.battleStatus }); } /** * 战斗结算 * 结算战斗奖励,更新远征状态 */ async battleEnd(msg: { expeditionCode: string, expeditionId: number, battleCode: string, battleId: number, isSuccess: boolean, heroes: Array<{ dataId: number, hp: number, ap: number }>, enemies: Array<{ dataId: number, hp: number, ap: number }>, star: number }, session: BackendSession) { const { expeditionCode, battleCode, battleId, expeditionId, isSuccess, heroes = [], star, enemies } = msg; let roleId = session.get('roleId'); let roleName = session.get('roleName'); const serverId = session.get('serverId'); let sid = session.get('sid'); let funcs: number[] = session.get('funcs'); let warInfo = gameData.war.get(battleId); if (!warInfo) { return resResult(STATUS.BATTLE_MISS_INFO); } const BattleRecord = await BattleRecordModel.getBattleRecordByCode(battleCode); if (!BattleRecord || BattleRecord.status != 0) { return resResult(STATUS.BATTLE_STATUS_WRONG); } let flag = 1; // 对比hero信息 let { record: { heroes: dbHeroes, seqIds: dbSeqIds } } = BattleRecord; for (let { dataId } of heroes) { if (dbSeqIds.indexOf(dataId) == -1) flag = 0; } if (!flag) { return resResult(STATUS.BATTLE_INFO_VALIDATE_ERR); } let role = await RoleModel.findByRoleId(roleId, 'lv'); let apJson = await setAp(roleId, role.lv, isSuccess?-1 * warInfo.cost: 0, sid, funcs); // 扣除体力 if (!apJson) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); } // 检查record let expeditionRecord = await ExpeditionRecordModel.getExpeditionRecordByCode(expeditionCode); let expeditionWarRecord = await ExpeditionWarRecordModel.getRecordByCodeAndId(expeditionCode, expeditionId); if (!expeditionRecord || !expeditionWarRecord) { return resResult(STATUS.EXPEDITION_MISS_WAR_RECORD); } // 更新我方剩余血量 await ExpeditionRecordModel.updateHeroStatus(expeditionCode, expeditionRecord.heroes, heroes); // 更新敌人剩余状态及战斗状态 let battleStatus = isSuccess ? EXPEDITION_WAR_RECORD_STATUS.SUCCESS : EXPEDITION_WAR_RECORD_STATUS.FAIL; expeditionWarRecord = await ExpeditionWarRecordModel.updateEnemiesStatus(expeditionCode, expeditionId, battleStatus, enemies); // 更新battleRecord状态 await BattleRecordModel.updateBattleRecordByCode(battleCode, { $set: { status: isSuccess ? 1 : 2, star } }, true); // 更新点数 role = await RoleModel.increaseExpeditionPoint(roleId, isSuccess ? EXPEDITION_CONST.INCREASE_POINT : 0); let { expeditionPoint = 0 } = role; // 关卡奖励 let warReward = new WarReward(roleId, roleName, sid, battleId, isSuccess); let reward = await warReward.saveReward(1); let actordata = await roleLevelup(roleId, isSuccess ? warInfo.kingExp : 0, session);// 主公升级经验 if (isSuccess) { // 更新下一关状态 await ExpeditionWarRecordModel.updateStatus(expeditionCode, expeditionId + 1, EXPEDITION_WAR_RECORD_STATUS.WAITING); } await checkTaskInBattleEnd(serverId, roleId, sid, funcs, battleId, dbHeroes, star); return resResult(STATUS.SUCCESS, { expeditionCode, expeditionId, battleCode, battleId, battleStatus: expeditionWarRecord.battleStatus, battleGoods: reward, expeditionPoint, ...actordata }); } /** * 领取点数宝箱 * 领取点数宝箱,不扣除点数,那么就需要记录领取状态并且有返回 */ async pointReward(msg: { point: number }, session: BackendSession) { const { point } = msg; let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); const funcs: number[] = session.get('funcs'); const serverId = session.get('serverId'); let role = await RoleModel.findByRoleId(roleId); let { expeditionPoint } = role; let dicExpeditionPoint = gameData.expeditionPoint; let curDicExpeditionPoint = dicExpeditionPoint.get(point); if (!curDicExpeditionPoint) { return resResult(STATUS.EXPEDITION_MISS_POINT_INFO); } if (point > expeditionPoint) { return resResult(STATUS.EXPEDITION_POINT_NOT_ENOUGH); } let pointStatusInDatabase = await ExpeditionPointModel.getExpeditionPoint(roleId); if (pointStatusInDatabase) { let { rewards } = pointStatusInDatabase; let curReward = rewards.find(cur => cur.point == point); if (curReward && curReward.received) { return resResult(STATUS.EXPEDITION_WRONG_RECEIVE_STATUS); } } // 标记状态 let { rewards: resultRewards } = await ExpeditionPointModel.updatePointStatus(roleId, point, curDicExpeditionPoint.reward); let hasReceivedAll = true, maxPoint = 0; for (let [point] of dicExpeditionPoint) { let curReward = resultRewards.find(cur => cur.point == point); if (!curReward || !curReward.received) { hasReceivedAll = false; } if (point > maxPoint) maxPoint = point; } if (hasReceivedAll) { // 全部领取了,刷新 await ExpeditionPointModel.completeStatus(roleId); await RoleModel.increaseExpeditionPoint(roleId, maxPoint * -1); } let pointRewards = await getPointRewardStatus(roleId); // 任务 await checkTask(roleId, sid, funcs, TASK_TYPE.BATTLE_EXPEDITION_BOX, 1, true, { point }); await checkActivityTask(serverId, sid, funcs, roleId, TASK_TYPE.BATTLE_EXPEDITION_BOX, 1) let goods = await addItems(roleId, roleName, sid, curDicExpeditionPoint.reward); return resResult(STATUS.SUCCESS, { costPoint: hasReceivedAll ? maxPoint : 0, pointRewards, goods }) } }