import { Application, BackendSession } from 'pinus'; import { getGamedata, getWarById } from '../../../pubUtils/gamedata'; 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 { matchPlayers, matchRobots, getPointRewardStatus, getCEScaleAndRange, getResetRemainCnt } from '../../../services/expeditionService'; import { EXPEDITION_CONST } from '../../../consts/consts'; import { WarReward } from '../../../services/warRewardService'; import { handleFixedReward } 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'; export default function(app: Application) { 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 expeditionRecord = await ExpeditionRecordModel.getCurRecord(roleId); if(!expeditionRecord) { // 首次新建一条记录 // 我方战力(暂定) let myCe = await calculateSumCE(roleId, 1, { num: 5 }); expeditionRecord = await ExpeditionRecordModel.createRecord({ roleId, roleName, heroes: [], myCe }); } // 每一关的挑战状态 let { expeditionCode, heroes } = expeditionRecord; let expeditionWarRecord = await ExpeditionWarRecordModel.getRecordByCode(expeditionCode); let curLv = 0; if(expeditionWarRecord.length > 0) { curLv = expeditionWarRecord[expeditionWarRecord.length - 1].expeditionId; } // 重置次数 let role = await RoleModel.findByRoleId(roleId); let curTime = new Date(); let {resetCnt} = await getResetRemainCnt(curTime, roleId, role); // 点数,和宝箱领取状态 let pointRewards = await getPointRewardStatus(roleId, role); return resResult(STATUS.SUCCESS, { expeditionCode, curLv, expeditionWarRecord, pointRewards, heroes, resetCnt }); } /** * 重置远征本 * 每天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: 5 }); // 每一关的挑战状态 let { expeditionCode, heroes } = await ExpeditionRecordModel.createRecord({ roleId, roleName, heroes: [], myCe }); await RoleModel.increaseExpeditionResetCnt(roleId, needRefresh, curTime); return resResult(STATUS.SUCCESS, { expeditionCode, curLv: 0, 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 expeditionWarRecord = await ExpeditionWarRecordModel.getRecordByCodeAndId(expeditionCode, expeditionId); if(!expeditionWarRecord) { // 如果没有信息 let enemyObj = { enemyFrom: 0, enemyId: '', enemies: new Array() }; let dicExpedition = getGamedata('dic_expedition'); let curDicExpedition = dicExpedition.find(cur => cur.id == expeditionId); // 获取系数和步长 let {scale, range, lv} = await getCEScaleAndRange(roleId, curDicExpedition); // 优先匹配其他玩家 let flag = await matchPlayers(roleId, scale, range, myCe, curDicExpedition.json, enemyObj); // 当数量不够时使用机器人匹配 if(!flag) { flag = await matchRobots(scale, myCe, curDicExpedition.ce, curDicExpedition.json, lv, enemyObj); } if(!flag) { return resResult(STATUS.EXPEDITION_MATCH_NO_PLAYER); } // 保存 let {warId} = curDicExpedition; expeditionWarRecord = await ExpeditionWarRecordModel.saveRecord(expeditionCode, expeditionId, { roleId, battleId: warId, ...enemyObj }); } let { battleId, enemyFrom, enemies, battleStatus } = expeditionWarRecord; return resResult(STATUS.SUCCESS, { expeditionCode, expeditionId, battleId, battleStatus, enemyFrom, enemies }); } /** * 进入战斗 * 记录我军数据,生成战斗唯一表示,记录状态 */ async checkBattle(msg: { expeditionCode: string, expeditionId: number, battleId: number, heroes: Array }, session: BackendSession) { const { expeditionCode, expeditionId, battleId, heroes } = msg; let roleId = session.get('roleId'); let roleName = session.get('roleName'); let warInfo = getWarById(battleId); if(!warInfo) { return resResult(STATUS.BATTLE_MISS_INFO); } let apJson = await getAp(Date.now(), roleId); 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 checkHeroes = await checkBattleHeroes(roleId, heroes); if(!checkHeroes) 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 == 1) { 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 } } }, true); let result = await ExpeditionWarRecordModel.updateStatus(expeditionCode, expeditionId, 0, battleCode); return resResult(STATUS.SUCCESS, { expeditionCode, expeditionId, battleId, battleCode, battleStatus: result.battleStatus, apJson }); } /** * 战斗结算 * 结算战斗奖励,更新远征状态 */ 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'); let warInfo = getWarById(battleId); if(!warInfo) { return resResult(STATUS.BATTLE_MISS_INFO); } if(!warInfo.hasOwnProperty('cost')) { warInfo['cost'] = 0; } 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 } } = BattleRecord; for(let {dataId} of heroes) { if(dbHeroes.indexOf(dataId) == -1) flag = 0; } if(!flag) { return resResult(STATUS.BATTLE_INFO_VALIDATE_ERR); } const now = Date.now(); // 当前时间戳 let apJson = await setAp(now, roleId, -1 * warInfo.cost); // 扣除体力 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); // 更新敌人剩余状态及战斗状态 expeditionWarRecord = await ExpeditionWarRecordModel.updateEnemiesStatus(expeditionCode, expeditionId, isSuccess?1:2, enemies); // 更新battleRecord状态 await BattleRecordModel.updateBattleRecordByCode(battleCode, { $set: { status: isSuccess?1: 2, star } }, true); // 更新点数 let role = await RoleModel.increaseExpeditionPoint(roleId, isSuccess?EXPEDITION_CONST.INCREASE_POINT:0); let { expeditionPoint = 0 } = role; // 关卡奖励 let warReward = new WarReward(roleId, roleName, battleId, isSuccess); let reward = await warReward.saveReward(1); let actordata = await roleLevelup(roleId, isSuccess?warInfo.kingExp:0);// 主公升级经验 return resResult(STATUS.SUCCESS, { expeditionCode, expeditionId, battleCode, battleId, battleStatus: expeditionWarRecord.battleStatus, ...reward, apJson, expeditionPoint, ...actordata }); } /** * 领取战斗宝箱 * 领取宝箱,更新远征状态 */ async battleReward(msg: { expeditionCode: string, expeditionId: number }, session: BackendSession) { const { expeditionCode, expeditionId } = msg; let roleId = session.get('roleId'); let roleName = session.get('roleName'); // 检查expeditionWarRecord的battleStatus let expeditionWarRecord = await ExpeditionWarRecordModel.getRecordByCodeAndId(expeditionCode, expeditionId); if(!expeditionWarRecord) { return resResult(STATUS.EXPEDITION_MISS_WAR_RECORD); } if(expeditionWarRecord.battleStatus != 1) { return resResult(STATUS.EXPEDITION_WRONG_STATUS_WHEN_RECEIVE); } if(expeditionWarRecord.received) { return resResult(STATUS.EXPEDITION_WRONG_RECEIVE_STATUS); } // 设置expeditionWarRecord的received和rewards let dicExpedition = getGamedata('dic_expedition'); let curDicExpedition = dicExpedition.find(cur => cur.id == expeditionId); if(!curDicExpedition) { return resResult(STATUS.EXPEDITION_MISS_INFO); } let result = await ExpeditionWarRecordModel.updateBoxStatus(expeditionCode, expeditionId, true, curDicExpedition.reward); let { battleId, battleCode, battleStatus, received } = result; // 获取东西 let goods = await handleFixedReward(roleId, roleName, curDicExpedition.reward, 1); return resResult(STATUS.SUCCESS, { expeditionCode, expeditionId, battleId, battleCode, battleStatus, received, ...goods }); } /** * 领取点数宝箱 * 领取点数宝箱,不扣除点数,那么就需要记录领取状态并且有返回 */ async pointReward(msg: { point }, session: BackendSession) { const { point } = msg; let roleId = session.get('roleId'); let roleName = session.get('roleName'); let role = await RoleModel.findByRoleId(roleId); let {expeditionPoint} = role; let dicExpeditionPoint = getGamedata('dic_expedition_point'); let curDicExpeditionPoint = dicExpeditionPoint.find(cur => cur.point == 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); } } // 标记状态 await ExpeditionPointModel.updatePointStatus(roleId, point, curDicExpeditionPoint.reward); let pointRewards = await getPointRewardStatus(roleId); let goods = await handleFixedReward(roleId, roleName, curDicExpeditionPoint.reward, 1); return resResult(STATUS.SUCCESS, { pointRewards, ...goods }) } /** * 刷新点数宝箱 * 扣除远征点数,并刷新箱子状态 */ async resetPointReward(msg: { }, session: BackendSession) { let roleId = session.get('roleId'); // let roleName = session.get('roleName'); let pointStatusInDatabase = await ExpeditionPointModel.getExpeditionPoint(roleId); if(!pointStatusInDatabase) { return resResult(STATUS.EXPEDITION_POINT_RECORD_NOT_FOUND); } let { rewards } = pointStatusInDatabase; let dicExpeditionPoint = getGamedata('dic_expedition_point'); let flag = true, maxPoint = 0; for(let dic of dicExpeditionPoint) { let curReward = rewards.find(cur => cur.point == dic.point); if(!curReward || !curReward.received) { flag = false; } if(dic.point > maxPoint) maxPoint = dic.point; } if(!flag) { return resResult(STATUS.EXPEDITION_POINT_NEED_ALL_RECEIVED); } // 刷新 await ExpeditionPointModel.completeStatus(roleId); await RoleModel.increaseExpeditionPoint(roleId, maxPoint * -1); let pointRewards = await getPointRewardStatus(roleId); return resResult(STATUS.SUCCESS, { pointRewards }); } }