Files
ZYZ/game-server/app/servers/battle/handler/normalBattleHandler.ts
2020-12-18 17:13:49 +08:00

368 lines
14 KiB
TypeScript

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';
export default function(app: Application) {
return new NormalBattleHandler(app);
}
export class NormalBattleHandler {
constructor(private app: Application) {
}
// 获取关卡列表
async checkBattle(msg: {battleId: number, heroes: Array<number> }, 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<any>, }, 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 = getWarById(battleId);
if(!warInfo) {
return resResult(STATUS.BATTLE_MISS_INFO);
}
// 寻宝不使用通用战斗模块结算
if (warInfo.warType == WAR_TYPE.WARLOARDS) {
return resResult(STATUS.BATTLE_END_WRONG_TYPE);
}
if(!warInfo.hasOwnProperty('cost')) {
warInfo['cost'] = 0;
}
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 channelService = this.app.get('channelService');
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(this.app, session, roleId, battleId, isSuccess, battleCode);
} else if (warInfo.warType == WAR_TYPE.TOWER) {
let towerEndResult = await towerBattleEnd(channelService, 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, this.app, 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, this.app, session);// 主公升级经验
// 返回值:
// towerStatus: false-本层未通过, true-本层已通过
return resResult(STATUS.SUCCESS, {
battleCode, battleId, status,
goods: 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, this.app, session)// 主公升级经验
// 扫荡记录
await BattleSweepRecordModel.saveBattleSweepRecordById(roleId, battleId, {
$set: {
roleName,
warName: warInfo.gk_name,
warType: warInfo.warType
},
$inc: { count }
});
return resResult(STATUS.SUCCESS, {
battleId, count,
goods: 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<number> }, 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 });
}
}