Files
ZYZ/game-server/app/servers/battle/handler/expeditionBattleHandler.ts
2020-11-09 17:41:24 +08:00

404 lines
16 KiB
TypeScript

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<number> }, 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
});
}
}