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 } from '../../../services/expeditionService'; import { EXPEDITION_INCREASE_POINT } from '../../../consts/consts'; import { WarReward } from '../../../services/warRewardService'; import { handleFixedReward } from '../../../services/rewardService'; import { getAp, setAp } from '../../../services/actionPointService'; 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 now = new Date(); let today = now.setHours(0, 0, 0, 0); let expeditionRecord = await ExpeditionRecordModel.getTodayRecord(roleId, today); if(!expeditionRecord) { // 每天新建一条记录 let code = genCode(8); expeditionRecord = await ExpeditionRecordModel.createTodayRecord(code, { roleId, roleName, time: today, heroes: [] }); } // 每一关的挑战状态 let { expeditionCode, heroes } = expeditionRecord; let expeditionWarRecord = await ExpeditionWarRecordModel.getRecordByCode(expeditionCode); let curLv = 0; if(expeditionWarRecord.length > 0) { curLv = expeditionWarRecord[expeditionWarRecord.length - 1].expeditionId; } // 点数,和宝箱领取状态 let pointRewards = await getPointRewardStatus(roleId); return { code: 200, data: { expeditionCode, curLv, expeditionWarRecord, pointRewards, heroes } } } /** * 获取敌军数据 * 匹配其他玩家,或机器人数据 */ async getEnemies(msg: { expeditionCode: string, expeditionId: number }, session: BackendSession) { const roleId = session.get('roleId'); // const roleName = session.get('roleName'); const { expeditionCode, expeditionId } = msg; let expeditionWarRecord = await ExpeditionWarRecordModel.getRecordByCodeAndId(expeditionCode, expeditionId); if(!expeditionWarRecord) { // 如果没有信息 // 计算我方战斗力(最高五人) let myCe = await calculateSumCE(roleId, 1, { num: 5 }); 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(scale, range, myCe, enemyObj); // 当数量不够时使用机器人匹配 if(!flag) { flag = await matchRobots(scale, myCe, curDicExpedition.ce, curDicExpedition.json, lv, enemyObj); } if(!flag) { return {code: 202, data:'无法匹配对手'}; } // 保存 let {warId} = curDicExpedition; expeditionWarRecord = await ExpeditionWarRecordModel.saveRecord(expeditionCode, expeditionId, { roleId, battleId: warId, ...enemyObj }); } let { battleId, enemyFrom, enemies, battleStatus } = expeditionWarRecord; return { code: 200, data: { 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 { code: 202, data: "缺少关卡信息" } } let apJson = await getAp(Date.now(), roleId); let {ap} = apJson; if(ap < warInfo.cost) { return { code: 202, data: "体力不足" } } // 前置关卡是否挑战过 let previousGk = warInfo.previousGk; if(previousGk) { let preBattle = await BattleRecordModel.getBattleRecordByIdAndStatus(roleId, previousGk, 1); if(!preBattle) return {code: 202, data: '需要完成上一关才可以挑战'}; } let expeditionWarRecord = await ExpeditionWarRecordModel.getRecordByCodeAndId(expeditionCode, expeditionId); if(!expeditionWarRecord ) { return {code: 202, data: '需要先匹配好对手'} } if(expeditionWarRecord.battleStatus == 1) { return {code: 202, data: '已挑战过这一关'} } 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 { code: 200, data: { expeditionCode, expeditionId, battleId, battleCode, battleStatus: result.battleStatus, apJson } } } /** * 战斗结算 * 结算战斗奖励,更新远征状态 */ async battleEnd(msg: { expeditionCode: string, expeditionId: number, battleCode: string, battleId: number, isSuccess: boolean, heroes: Array<{actorId: 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 { code: 202, data: "缺少关卡信息" } } if(!warInfo.hasOwnProperty('cost')) { warInfo['cost'] = 0; } const BattleRecord = await BattleRecordModel.getBattleRecordByCode(battleCode); if(!BattleRecord || BattleRecord.status != 0) { return { code: 202, data: '关卡状态错误' } } let flag = 1; // 对比hero信息 let { record: { heroes: dbHeroes } } = BattleRecord; for(let {actorId} of heroes) { if(dbHeroes.indexOf(actorId) == -1) flag = 0; } if(!flag) { return { code: 202, data: '关卡信息不同' } } const now = Date.now(); // 当前时间戳 let apJson = await setAp(now, roleId, -1 * warInfo.cost); // 扣除体力 if(!apJson) { return { code: 202, data: '体力不足' } } // 检查record let expeditionRecord = await ExpeditionRecordModel.getExpeditionRecordByCode(expeditionCode); let expeditionWarRecord = await ExpeditionWarRecordModel.getRecordByCodeAndId(expeditionCode, expeditionId); if(!expeditionRecord|| !expeditionWarRecord) { return { code: 202, data:'未找到该记录' } } // 更新我方剩余血量 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_INCREASE_POINT:0); let { expeditionPoint = 0 } = role; // 关卡奖励 let warReward = new WarReward(roleId, roleName, battleId, isSuccess); let reward = await warReward.saveReward(1); return { code: 200, data: { expeditionCode, expeditionId, battleCode, battleId, battleStatus: expeditionWarRecord.battleStatus, goods: reward, apJson, expeditionPoint } } } /** * 领取战斗宝箱 * 领取宝箱,更新远征状态 */ 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 {code: 202, data: '未找到该关卡'} } if(expeditionWarRecord.battleStatus != 1) { return {code: 202, data: '需要战斗胜利后才可以领取'} } if(expeditionWarRecord.received) { return {code: 202, data: '已经领取过了'} } // 设置expeditionWarRecord的received和rewards let dicExpedition = getGamedata('dic_expedition'); let curDicExpedition = dicExpedition.find(cur => cur.id == expeditionId); if(!curDicExpedition) { return {code: 202, data: '未找到该配置'} } 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 { code: 200, data: { 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 {code: 202, data: '该点数不能领取奖励'} } if(point > expeditionPoint) { return {code: 202, data: '点数不足'}; } let pointStatusInDatabase = await ExpeditionPointModel.getExpeditionPoint(roleId); if(pointStatusInDatabase) { let {rewards} = pointStatusInDatabase; let curReward = rewards.find(cur => cur.point == point); if(curReward && curReward.received) { return {code: 202, data: '已领取过'} } } // 标记状态 await ExpeditionPointModel.updatePointStatus(roleId, point, curDicExpeditionPoint.reward); let pointRewards = await getPointRewardStatus(roleId); let goods = await handleFixedReward(roleId, roleName, curDicExpeditionPoint.reward, 1); return { code: 200, data: { 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 {code: 202, data: '已刷新'} } 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 {code: 202, data: '宝箱需要领取完才可以刷新'} } // 刷新 await ExpeditionPointModel.completeStatus(roleId); await RoleModel.increaseExpeditionPoint(roleId, maxPoint * -1); let pointRewards = await getPointRewardStatus(roleId); return { code: 200, data: { pointRewards } } } }