import { STATUS } from './../../../consts/statusCode'; import { HANG_UP_CONSTS, GOLD_COST_RATIO, TOWER_TASK_CONST, REDIS_KEY } from './../../../consts'; import { TowerTaskRecModel } from './../../../db/TowerTaskRec'; import { HangUpSpdUpRecModel } from './../../../db/HangUpSpdUpRec'; import { HangUpRecordModel } from './../../../db/HangUpRecord'; import { RoleModel } from './../../../db/Role'; import { TowerRecordModel } from './../../../db/TowerRecord'; import { Application, BackendSession } from 'pinus'; import { resResult, shouldRefresh, calculateNum, genCode } from '../../../pubUtils/util'; import { calcuHangUpReward, checkTaskConditions, checkHangUpSpdUpCnt, createCurTasks, treatTask, getRemainTime, getDoingOrWaitingTasks, getTowerStatus, getHungupRewards, getTasks } from '../../../services/battleService'; import { addItems, handleCost } from '../../../services/rewardService'; import { checkBattleHeroes } from '../../../services/normalBattleService'; import { getGoldObject } from '../../../pubUtils/itemUtils'; import { Rank } from '../../../services/rankService'; import { gameData } from '../../../pubUtils/data'; import { ItemInter } from '../../../pubUtils/interface'; export default function(app: Application) { return new TowerBattleHandler(app); } export class TowerBattleHandler { constructor(private app: Application) { } /** * 获取天梯当前挑战状态 * @param session */ async getStatus(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let serverId = session.get('serverId'); let role = await RoleModel.findByRoleId(roleId); let data = await getTowerStatus(role); return resResult(STATUS.SUCCESS, data); } /** * 重置天梯当前层的挑战记录 * @param towerLv 要重置的天梯层数 * @param session */ async resetLv(msg: {towerLv: number}, session: BackendSession) { let roleId = session.get('roleId'); let { towerLv } = await RoleModel.findByRoleId(roleId); if (msg.towerLv !== towerLv) { return resResult(STATUS.TOWER_RESET_ERR); } const record = await TowerRecordModel.resetRecordByLv(roleId, towerLv); if (!record) { return resResult(STATUS.TOWER_NOT_FOUND); } return resResult(STATUS.SUCCESS, record); } async checkHangUpRewards(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let result = await getHungupRewards(roleId); if(result.status == -1) { return result.resResult; } return resResult(STATUS.SUCCESS, result.data); } async recHangUpRewards(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); const result = await calcuHangUpReward(roleId); if(result.status == -1) { return result.resResult } let { timeReward, endLv, endTime, deltaTime, needReceiveGoods } = result.data; const goods = await addItems(roleId, roleName, sid, timeReward); await HangUpRecordModel.updateRec(roleId, roleName, endLv, endTime, needReceiveGoods); return resResult(STATUS.SUCCESS, { endTime, hangUpPassTime: Math.floor((deltaTime%HANG_UP_CONSTS.UNIT_TIME)/1000), goods }); } async hangUpSpeedUp(msg: {speedUpCnt: number}, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); if (msg.speedUpCnt <= 0) { return resResult(STATUS.WRONG_PARMS); } const curTime = new Date(); const calResult = await calcuHangUpReward(roleId, true, msg.speedUpCnt, curTime); if(calResult.status == -1) { return calResult.resResult; } let { timeReward, endLv, deltaTime, needReceiveGoods } = calResult.data; let result = await checkHangUpSpdUpCnt(roleId, msg.speedUpCnt, curTime); if(result.status == -1) return result.resResult; let {data: {hangUpSpdUpCnt, gold}} = result; const costGold = this.getHangUpCost(hangUpSpdUpCnt, msg.speedUpCnt); if(costGold > gold) { return resResult(STATUS.TOWER_GOLD_NOT_ENOUGH); } await handleCost(roleId, sid, [getGoldObject(costGold)]) const spdUpResult = await RoleModel.hangUpSpdUp(roleId, msg.speedUpCnt, curTime); if (!spdUpResult) { return resResult(STATUS.TOWER_HANG_UP_FAILED); } const spdUpRec = await HangUpSpdUpRecModel.updateRec(roleId, roleName, msg.speedUpCnt, endLv, needReceiveGoods); const goods = await addItems(roleId, roleName, sid, timeReward); hangUpSpdUpCnt -= msg.speedUpCnt; let num = HANG_UP_CONSTS.MAX_SPD_UP_CNT - hangUpSpdUpCnt + 1; let nextCostGold = calculateNum(GOLD_COST_RATIO.TOWER_HANG_SPDUP, {num}, 50); return resResult(STATUS.SUCCESS, { goods, hangUpSpdUpCnt, nextCostGold, hangUpPassTime: Math.floor(deltaTime/1000), rewardLv: endLv, costGold }); } getHangUpCost(originCnt: number, count: number) { let gold = 0; for(let i = 1; i <= count; i++) { let num = HANG_UP_CONSTS.MAX_SPD_UP_CNT - originCnt + i; if(num < 0) num = i; gold += calculateNum(GOLD_COST_RATIO.TOWER_HANG_SPDUP, {num}, 50); } return gold } async getTasks(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let role = await RoleModel.findByRoleId(roleId); let result = await getTasks(role); return resResult(STATUS.SUCCESS, result); } async refreshTasks(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let curTime = new Date(); let { towerLv, towerTaskCnt = 0, towerTaskReCnt=0 } = await RoleModel.findByRoleId(roleId); if(TOWER_TASK_CONST.MAX_TASK_REF_CNT <= towerTaskCnt) { // 每派遣一个任务加一,最多8个完成任务 return resResult(STATUS.TOWER_REF_CNT_NOT_ENOUGH); } let costGold = calculateNum(GOLD_COST_RATIO.TOWER_TASK_REF, {num: towerTaskReCnt}, 50); let {gold} = await RoleModel.findByRoleId(roleId); if(costGold > gold) { return resResult(STATUS.TOWER_GOLD_NOT_ENOUGH); } // 只刷掉当前面板上没有做派遣的任务 const batchCode = genCode(8); let curTasks = await TowerTaskRecModel.getCurTasks(roleId); // 当前显示中的任务 let {waitingTaskCode, doingTaskCode, doingIds} = getDoingOrWaitingTasks(curTasks, curTime); await TowerTaskRecModel.hideTask(roleId, waitingTaskCode); // 隐藏没有在做的任务 await TowerTaskRecModel.updateBatchCode(roleId, doingTaskCode, batchCode); // 更新留下来的旧任务的batchCode await createCurTasks(towerLv, batchCode, roleId, roleName, 0, waitingTaskCode.length, doingIds); curTasks = await TowerTaskRecModel.getCurTasks(roleId); await RoleModel.increaseTowerRefCnt(roleId, 1); let refRemainTime = getRemainTime(curTime); let nextCostGold = calculateNum(GOLD_COST_RATIO.TOWER_TASK_REF, {num: towerTaskReCnt + 1}, 50); return resResult(STATUS.SUCCESS, { curTasks: treatTask(curTasks, curTime), costGold, nextCostGold, refRemainTime}); } async sendTaskHero(msg: {batchCode: string, tasks: Array<{taskCode: string, heroes: Array}>}, session: BackendSession) { let roleId = session.get('roleId'); const curTime = new Date(); let curTasks = await TowerTaskRecModel.getCurTasks(roleId); // 当前一批的任务 if (!curTasks || curTasks.length == 0) { return resResult(STATUS.TOWER_TASK_NOT_FOUND); } let usedHeroes = [], tasks = []; const tasksCode = []; const taskMap = new Map() curTasks.forEach(task => { usedHeroes = usedHeroes.concat(task.heroes); tasksCode.push(task.taskCode); taskMap.set(task.taskCode, task); }); for (let task of msg.tasks) { let curTask = taskMap.get(task.taskCode); // 数据库中,这个任务的数据 if(!curTask) { return resResult(STATUS.TOWER_TASK_MISSING) } let taskInfo = gameData.towerTask.get(curTask.taskId); if (task.heroes.length !== taskInfo.actorNeeded) { // 武将数,从策划表中读取 return resResult(STATUS.TOWER_TASK_MAX_HERO); } let { isOK } = await checkBattleHeroes(roleId, task.heroes); if(!isOK) return resResult(STATUS.BATTLE_HERO_NOT_FOUND); if (tasksCode.indexOf(task.taskCode) === -1) { return resResult(STATUS.TOWER_TASK_CODE_NOT_FOUND); } if (usedHeroes.length > 0) { // 是否在其他任务重使用了武将 let used = !!task.heroes.find(seqId => usedHeroes.indexOf(seqId) !== -1); if (used) { return resResult(STATUS.TOWER_TASK_HERO_HAS_USED); } } tasks.push({...task, completeTime: taskInfo.completeTime}) } const recs = await TowerTaskRecModel.sendHeroes(roleId, msg.batchCode, tasks, curTime,); if (!recs || recs.length === 0) { return resResult(STATUS.TOWER_TASK_SEND_ERR); } await RoleModel.increaseTowerCnt(roleId, tasks.length) let refRemainTime = getRemainTime(curTime); curTasks = await TowerTaskRecModel.getCurTasks(roleId); // 当前显示中的任务 let costGold = TOWER_TASK_CONST.COST_GOLD; return resResult(STATUS.SUCCESS, { curTasks: treatTask(curTasks, curTime), refRemainTime, nextCostGold: costGold }); } async settleTask(msg: {batchCode: string, taskCode: string}, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); let allFlag = !msg.taskCode; const curTime = new Date(); let curTasks = await TowerTaskRecModel.getCurTasks(roleId); if (!curTasks || curTasks.length == 0) { return resResult(STATUS.TOWER_TASK_NOT_FOUND); } const compTasks: string[] = []; let rewards: ItemInter[] = []; for (let task of curTasks) { if (task.batchCode !== msg.batchCode) { return resResult(STATUS.TOWER_TASK_BATCH_NOT_FOUND); } if ((allFlag || task.taskCode === msg.taskCode) && task.status === 1) { let {completeTime, reward, termsForAdd, additionalReward} = gameData.towerTask.get(task.taskId); if (task.sendTime && task.sendTime.getTime() + completeTime * 1000 < curTime.getTime()) { compTasks.push(task.taskCode); rewards = rewards.concat(reward); if(termsForAdd) { const result = await checkTaskConditions(roleId, task.heroes, termsForAdd); if(result) { rewards = rewards.concat(additionalReward) } } } } } let goods = await addItems(roleId, roleName, sid, rewards); await TowerTaskRecModel.finishTask(msg.batchCode, compTasks); await TowerTaskRecModel.showTask(roleId, msg.batchCode, compTasks.length); let refRemainTime = getRemainTime(curTime); curTasks = await TowerTaskRecModel.getCurTasks(roleId); // 当前显示中的任务 let costGold = TOWER_TASK_CONST.COST_GOLD; return resResult(STATUS.SUCCESS, { curTasks: treatTask(curTasks, curTime), goods, refRemainTime, nextCostGold: costGold }); } }