import { Application, BackendSession } from 'pinus'; import { BattleRecordModel } from '../../../db/BattleRecord'; import { BattleSweepRecordModel } from '../../../db/BattleSweepRecord'; import { getWarById, } from '../../../pubUtils/gamedata'; import { genCode } from '../../../pubUtils/util'; import { WAR_TYPE, EVENT_STATUS, FUNC_OPT_TYPE } from '../../../consts'; import { checkDaily, checkDailyAndIncrease } from '../../../services/dailyBattleService'; import { checkTowerWar, towerBattleEnd } from '../../../services/battleService'; import { WarReward } from '../../../services/warRewardService'; import { getAp, setAp } from '../../../services/actionPointService'; import { setBattleStatus, checkEventBattle } from '../../../services/eventSercive'; import { STATUS } from '../../../consts/statusCode'; import { resResult } from '../../../pubUtils/util'; import { HeroModel } from '../../../db/Hero'; import { RoleModel } from '../../../db/Role'; import { RScriptRecordModel } from '../../../db/RScriptRecord'; import { updateWarStar, checkBattleHeroes, roleLevelup } from '../../../services/normalBattleService'; import { checkDungeonNum, checkDungeonAndIncrease } from '../../../services/dungeonService'; import { switchOnFunc } from '../../../services/funcSwitchService'; import { gameData } from '../../../pubUtils/data'; export default function(app: Application) { return new NormalBattleHandler(app); } export class NormalBattleHandler { constructor(private app: Application) { } // 获取关卡列表 async checkBattle(msg: {battleId: number, heroes: Array }, session: BackendSession) { const { 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); } if(!warInfo.hasOwnProperty('cost')) { warInfo['cost'] = 0; } 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 {warStar} = await RoleModel.findByRoleId(roleId); let preBattle = warStar.findIndex(cur => cur.id == previousGk); if(preBattle == -1) return resResult(STATUS.BATTLE_NEED_PREVIOUS_GK); } let checkHeroes = await checkBattleHeroes(roleId, heroes); if(!checkHeroes) return resResult(STATUS.BATTLE_HERO_NOT_FOUND); const battleCode = genCode(8); // 关卡唯一值 let dailyNum = {}; let towerData = {}; let dungeonNum = {}; if(warInfo.warType == WAR_TYPE.DAILY) { let checkResult = await checkDaily(roleId, battleId, 1); if(checkResult.status == -1) { return checkResult.resResult } dailyNum = Object.assign(dailyNum, checkResult.data); } else if (warInfo.warType == WAR_TYPE.TOWER) { let checkResult = await checkTowerWar(roleId, battleId, heroes); if(checkResult.status == -1) { return checkResult.resResult } towerData = Object.assign(towerData, checkResult.data); } else if (warInfo.warType == WAR_TYPE.EVENT) { // 记录事件状态 let eventStatus = session.get('eventStatus')||EVENT_STATUS.WAITING; let checkResult = await checkEventBattle( roleId, eventStatus, battleId, battleCode); if(checkResult.status == -1) { return checkResult.resResult } } else if (warInfo.warType == WAR_TYPE.MYSTERY || warInfo.warType == WAR_TYPE.MYSTERY_ELITE) { let checkResult = await checkDungeonNum(roleId, 1); if(checkResult.status == -1) { return checkResult.resResult } dungeonNum = Object.assign(dungeonNum, checkResult.data); } const BattleRecord = await BattleRecordModel.updateBattleRecordByCode(battleCode, { $set: { roleId, roleName, battleId, status: 0, warName: warInfo.gk_name, warType: warInfo.warType, record: { heroes } } }, true); let {status} = BattleRecord; return resResult(STATUS.SUCCESS, { battleId, battleCode, status, apJson, dailyNum, towerData, dungeonNum }); } // 关卡列表 async getBattleList(msg: {type: number }, session: BackendSession) { const { type } = msg; let roleId = session.get('roleId'); let role = await RoleModel.findByRoleId(roleId); let {warStar} = role; let scripts = await RScriptRecordModel.findbyRole(roleId, type); let result = []; // 去重 for(let {battleId, scriptBefore = '', scriptAfter = ''} of scripts) { result.push({ battleId, status: 0, star: 0, scriptBefore, scriptAfter }); } for(let {id, star, warType} of warStar) { if(warType == type) { let curResult = result.find(cur => cur.battleId == id); if(curResult) { curResult.status = 1; curResult.star = star; } else { result.push({ battleId: id, status: 1, star, scriptBefore: '', scriptAfter: '' }); } } } result = result.sort((a, b) => {return a.battleId - b.battleId}); return resResult(STATUS.SUCCESS, { list: result }); } // 关卡结算,记录使用的武将,获得奖励 async battleEnd(msg: {battleCode: string, battleId: number, isSuccess: boolean, star: number, heroes: Array, }, session: BackendSession) { const { battleCode, battleId, isSuccess, heroes, star } = msg; let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); let serverId = session.get('serverId'); let warInfo = gameData.war.get(battleId); if(!warInfo) { return resResult(STATUS.BATTLE_MISS_INFO); } // 寻宝不使用通用战斗模块结算 if (warInfo.warType == WAR_TYPE.WARLOARDS) { return resResult(STATUS.BATTLE_END_WRONG_TYPE); } const BattleRecord = await BattleRecordModel.getBattleRecordByCode(battleCode, true); if(!BattleRecord || BattleRecord.status != 0) { return resResult(STATUS.BATTLE_STATUS_WRONG); } let flag = 1; // 对比hero信息 let { record: { heroes: dbHeroes } } = BattleRecord; for(let hid of heroes) { if(dbHeroes.indexOf(hid) == -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); } let warReward = new WarReward(roleId, roleName, sid, battleId, isSuccess); let dailyNum = {}; let towerStatus = null; let dungeonNum = {}; if(warInfo.warType == WAR_TYPE.DAILY) { let checkResult = await checkDailyAndIncrease(roleId, battleId, 1, false); if(checkResult.status == -1) { return checkResult.resResult; } dailyNum = Object.assign(dailyNum, checkResult.data) } else if (warInfo.warType == WAR_TYPE.EVENT) { // 记录事件状态 await setBattleStatus(session, roleId, battleId, isSuccess, battleCode); } else if (warInfo.warType == WAR_TYPE.TOWER) { let towerEndResult = await towerBattleEnd(sid, roleId, serverId, battleCode, battleId, isSuccess, heroes); if(towerEndResult) { if(towerEndResult.status == -1) { return towerEndResult.resResult; } towerStatus = towerEndResult.data.towerStatus; if(towerEndResult.data.towerReward) warReward.setFixReward(towerEndResult.data.towerReward) } } else if (warInfo.warType == WAR_TYPE.MYSTERY || warInfo.warType == WAR_TYPE.MYSTERY_ELITE) { let checkResult = await checkDungeonAndIncrease(roleId, 1, false); await RoleModel.saveDungeonHero(roleId, battleId, heroes, isSuccess); if(checkResult.status == -1) { return checkResult.resResult; } dungeonNum = Object.assign(dungeonNum, checkResult.data) } if(isSuccess) { // 挑战胜利 // 是否首通 let {warStar} = await RoleModel.findByRoleId(roleId); let condition1 = warStar.find(cur => cur.id == battleId); if(!condition1) { await switchOnFunc(roleId, FUNC_OPT_TYPE.BATTLE_END, battleId, session); warReward.setCondition(0, true); } // 是否首次3星 if(star == 3 && (!condition1 || condition1.star != 3)) { warReward.setCondition(1, true); } await updateWarStar(roleId, battleId, warInfo.warType, star); } let reward = await warReward.saveReward(1); const updateResult = await BattleRecordModel.updateBattleRecordByCode(battleCode, { $set: { status: isSuccess?1:2, star, record: { heroes } } }, true); let { status } = updateResult; let actordata = await roleLevelup(roleId, isSuccess?warInfo.kingExp:0, session);// 主公升级经验 // 返回值: // towerStatus: false-本层未通过, true-本层已通过 return resResult(STATUS.SUCCESS, { battleCode, battleId, status, battleGoods: reward, apJson, towerStatus, dailyNum, dungeonNum, ...actordata }); } async battleSweep(msg: {battleId: number, count: number }, session: BackendSession) { const { battleId, count } = 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); } // 校验是否三星通关过 let { warStar } = await RoleModel.findByRoleId(roleId); let curWar = warStar.find(cur => cur.id == battleId); if(!curWar || curWar.star != 3) { return resResult(STATUS.BATTLE_SWEEP_CONDITION_STAR); } // 扣体力 if(!warInfo.hasOwnProperty('cost')) { warInfo['cost'] = 0; } const now = Date.now(); // 当前时间戳 let apJson = await setAp(now, roleId, -1 * warInfo.cost * count); // 扣除体力 if(!apJson) { return resResult(STATUS.BATTLE_ACTION_POINT_LACK); } // 扫荡次数 let dailyNum = {}; let dungeonNum = {}; if(warInfo.warType == WAR_TYPE.DAILY) { let checkResult = await checkDailyAndIncrease(roleId, battleId, count, true); if(checkResult.status == -1) { return checkResult.resResult } dailyNum = Object.assign(dailyNum, checkResult.data) } else if(warInfo.warType == WAR_TYPE.MYSTERY|| warInfo.warType == WAR_TYPE.MYSTERY_ELITE) { let checkResult = await checkDungeonAndIncrease(roleId, count, true); if(checkResult.status == -1) { return checkResult.resResult } dungeonNum = Object.assign(dungeonNum, checkResult.data) } // 发奖励 let warReward = new WarReward(roleId, roleName, sid, battleId, true); let result = await warReward.saveReward(count); let actordata = await roleLevelup(roleId, warInfo.kingExp * count, session)// 主公升级经验 // 扫荡记录 await BattleSweepRecordModel.saveBattleSweepRecordById(roleId, battleId, { $set: { roleName, warName: warInfo.gk_name, warType: warInfo.warType }, $inc: { count } }); return resResult(STATUS.SUCCESS, { battleId, count, battleGoods: result, apJson, dailyNum, dungeonNum, ...actordata }); } async saveScript(msg: {battleId: number, type: number, script: string }, session: BackendSession) { const { battleId, type, script } = msg; let roleId = session.get('roleId'); let warInfo = getWarById(battleId); let result = await RScriptRecordModel.setScript(roleId, battleId, warInfo.warType, type, script); if(result) { if(!result.scriptBefore) result.scriptBefore = ''; if(!result.scriptAfter) result.scriptAfter = ''; return resResult(STATUS.SUCCESS, result); } else { console.error('script not created'); return resResult(STATUS.INTERNAL_ERR); } } async getScriptByBattle(msg: {battleIds: Array }, session: BackendSession) { const { battleIds } = msg; let roleId = session.get('roleId'); let list = new Array(); for(let battleId of battleIds) { let result = await RScriptRecordModel.findbyRoleAndBattle(roleId, battleId); if(result) { let {scriptBefore = '', scriptAfter = ''} = result; list.push({battleId, scriptBefore, scriptAfter}); } else { list.push({battleId, scriptBefore: '', scriptAfter: ''}); } } return resResult(STATUS.SUCCESS, { list }); } }