import { Application, BackendSession } from 'pinus'; import { getGamedata, getWarById, hasExpeditionById } 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 { getPointRewardStatus, getResetRemainCnt, findOrCreateEnemies } from '../../../services/expeditionService'; import { EXPEDITION_CONST, EXPEDITION_WAR_RECORD_STATUS } from '../../../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 }); await findOrCreateEnemies(roleId, myCe, expeditionRecord.expeditionCode, 1, EXPEDITION_WAR_RECORD_STATUS.WAITING); } // 每一关的挑战状态 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: heroes.map(cur => {return {"dataId": cur.seqId, "hp": cur.hp, "ap": cur.ap}}), 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 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(hasExpeditionById(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 } = 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 == 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 } } }, 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, 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 sid = session.get('sid'); 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); // 更新敌人剩余状态及战斗状态 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); // 更新点数 let 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); } return resResult(STATUS.SUCCESS, { expeditionCode, expeditionId, battleCode, battleId, battleStatus: expeditionWarRecord.battleStatus, battleGoods: reward, apJson, 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'); 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); } } // 标记状态 let {rewards: resultRewards} = await ExpeditionPointModel.updatePointStatus(roleId, point, curDicExpeditionPoint.reward); let hasReceivedAll = true, maxPoint = 0; for(let dic of dicExpeditionPoint) { let curReward = resultRewards.find(cur => cur.point == dic.point); if(!curReward || !curReward.received) { hasReceivedAll = false; } if(dic.point > maxPoint) maxPoint = dic.point; } if(hasReceivedAll) { // 全部领取了,刷新 await ExpeditionPointModel.completeStatus(roleId); await RoleModel.increaseExpeditionPoint(roleId, maxPoint * -1); } let pointRewards = await getPointRewardStatus(roleId); let goods = await handleFixedReward(roleId, roleName, sid, curDicExpeditionPoint.reward, 1); return resResult(STATUS.SUCCESS, { costPoint: hasReceivedAll?maxPoint: 0, pointRewards, goods }) } }