寻宝:创建队伍超时匹配机器人;战斗超时判负;优化代码并修复部分bug
This commit is contained in:
@@ -2,10 +2,10 @@
|
||||
* @Author: 梁桐川
|
||||
* @Date: 2020-11-30 15:05:48
|
||||
* @Last Modified by: 梁桐川
|
||||
* @Last Modified time: 2020-11-30 18:08:49
|
||||
* @Last Modified time: 2020-11-30 23:45:32
|
||||
*/
|
||||
import { COM_BATTLE_ROBOT_CE_RATIO, COM_BATTLE_ROBOT_ID_NAME, COM_BATTLE_ASSIST_TIME, COM_BATTLE_ROBOT_ROUND_LMT, COM_BATTLE_ROBOT_HURT_RATIO, COM_BATTLE_ROBOT_HURT_CH_RATIO, COM_TEAM_STATUS } from './../../../consts/consts';
|
||||
import { IT_TYPE, GOLD_COST_RATIO, CURRENCY_BY_TYPE, CURRENCY_TYPE } from '../../../consts/consts';
|
||||
import { COM_BATTLE_ASSIST_TIME, COM_BATTLE_ROBOT_ROUND_LMT, COM_BATTLE_ROBOT_HURT_RATIO, COM_BATTLE_ROBOT_HURT_CH_RATIO, COM_TEAM_STATUS } from './../../../consts/consts';
|
||||
import { IT_TYPE, GOLD_COST_RATIO, CURRENCY_BY_TYPE, CURRENCY_TYPE, COM_BATTLE_CAP_TIME, COM_BATTLE_TIME_LMT } from './../../../consts/consts';
|
||||
import { getGoodById, getBossHpByBlueprtId, getComBtlSetByQuality, getBlueprtComposeByQuality, getBluePrtByQuality } from '../../../pubUtils/gamedata';
|
||||
import { COM_TEAM_ENABLE_LV } from '../../../consts/consts';
|
||||
import { ComBattleTeamModel } from '../../../db/ComBattleTeam';
|
||||
@@ -16,9 +16,9 @@ import { resResult, getRandomByLen, calculateNum, getRandValue } from '../../../
|
||||
import { RoleStatus } from '../../../db/ComBattleTeam';
|
||||
import { ItemModel } from '../../../db/Item';
|
||||
import { handleReward } from '../../../services/rewardService';
|
||||
import { getTeamSearchByQuality, setTeamSearchReq } from '../../../services/redisService';
|
||||
import { getRandRobot, transBossHpArr } from '../../../services/battleService';
|
||||
import { getRandBlueprtId } from '../../../services/comBattleService';
|
||||
import { checkRoleInQueue, getTeamSearchByQuality, setTeamSearchReq } from '../../../services/redisService';
|
||||
import { transBossHpArr } from '../../../services/battleService';
|
||||
import { getRandBlueprtId, getRandComBtlRobots, checkComBattleResult } from '../../../services/comBattleService';
|
||||
|
||||
export default function(app: Application) {
|
||||
return new ComBattleHandler(app);
|
||||
@@ -141,16 +141,28 @@ export class ComBattleHandler {
|
||||
channel.add(roleId, sid);
|
||||
}
|
||||
}
|
||||
|
||||
let uids = [];
|
||||
if (teammates) {
|
||||
let uids = [];
|
||||
for (let teammate of teammates) {
|
||||
let { roleId, sid } = teammate;
|
||||
uids.push({uid: roleId, sid});
|
||||
}
|
||||
// TODO: 处理助战 timer
|
||||
channelService.pushMessageByUids('onTeamJoin', {teamInfo: comTeam}, uids);
|
||||
}
|
||||
let thiz = this;
|
||||
// 倒计时一定时间给队长匹配机器人
|
||||
setTimeout(async () => {
|
||||
let team = thiz.teamMap.get(teamCode);
|
||||
if (team.roleIds.length < 3) {
|
||||
let { robotStArr, robotIdArr } = getRandComBtlRobots(topFiveCe, lv, 3 - team.roleIds.length);
|
||||
team.roleIds = team.roleIds.concat(robotIdArr);
|
||||
team.roleStatus = team.roleStatus.concat(robotStArr);
|
||||
for (let st of robotStArr) {
|
||||
await ComBattleTeamModel.addRole(teamCode, st);
|
||||
}
|
||||
}
|
||||
channelService.pushMessageByUids('onTeamJoin', {teamInfo: team}, uids);
|
||||
}, COM_BATTLE_CAP_TIME);
|
||||
|
||||
return resResult(STATUS.SUCCESS, { teamCode, roleStatus });
|
||||
}
|
||||
@@ -179,26 +191,25 @@ export class ComBattleHandler {
|
||||
let thiz = this;
|
||||
// 倒计时匹配两个机器人
|
||||
setTimeout(async () => {
|
||||
let inQueue = await checkRoleInQueue(roleId, sid, qualityArr);
|
||||
if (!inQueue) return;
|
||||
let roleStatus = [];
|
||||
let roleIds = []
|
||||
let robotHeroes = getRandRobot(2); // 随机两个阵容
|
||||
let roleInfo = new RoleStatus(roleId, roleName, false, false, headHid, sHid, topFiveCe, lv);
|
||||
roleStatus.push(roleInfo);
|
||||
roleIds.push(roleId);
|
||||
let blueprtId = (await getRandBlueprtId(qualityArr)).pop();
|
||||
|
||||
// 创建队伍
|
||||
let blueprtId = getRandBlueprtId(qualityArr).pop();
|
||||
let { quality } = getGoodById(blueprtId);
|
||||
let { bossHpSum, bossHpArr } = getBossHpByBlueprtId(blueprtId);
|
||||
let comTeam = new ComTeam(teamCode, false, blueprtId, COM_TEAM_STATUS.DEFAULT, 'robot', 0, bossHpSum || 10000, quality, transBossHpArr(bossHpArr));
|
||||
|
||||
// 将玩家加入队伍
|
||||
let roleInfo = new RoleStatus(roleId, roleName, false, false, headHid, sHid, topFiveCe, lv);
|
||||
roleStatus.push(roleInfo);
|
||||
roleIds.push(roleId);
|
||||
// 创建并添加机器人
|
||||
for (let robot of robotHeroes) {
|
||||
const robotCe = getRandValue(topFiveCe, COM_BATTLE_ROBOT_CE_RATIO, 0);
|
||||
const robotLv = getRandValue(lv, COM_BATTLE_ROBOT_CE_RATIO, 0);
|
||||
const imgHid = robot[Math.floor(Math.random() * robot.length)];
|
||||
const { robotRoleId, robotRoleName } = COM_BATTLE_ROBOT_ID_NAME[Math.floor(Math.random() * COM_BATTLE_ROBOT_ID_NAME.length)];
|
||||
let robotStatus = new RoleStatus(robotRoleId, robotRoleName, false, false, imgHid, imgHid, robotCe, robotLv, robot, true);
|
||||
roleStatus.push(robotStatus);
|
||||
roleIds.push(robotRoleId);
|
||||
}
|
||||
let { robotStArr, robotIdArr } = getRandComBtlRobots(topFiveCe, lv, 2);
|
||||
roleStatus = roleStatus.concat(robotStArr);
|
||||
roleIds = roleIds.concat(robotIdArr);
|
||||
comTeam.roleStatus = roleStatus;
|
||||
comTeam.roleIds = roleIds;
|
||||
let channelService = thiz.app.get('channelService');
|
||||
@@ -243,13 +254,13 @@ export class ComBattleHandler {
|
||||
return resResult(STATUS.COM_BATTLE_CE_LIMIT);
|
||||
}
|
||||
|
||||
let teams = await ComBattleTeamModel.getTeamByRoleAndTime(roleId, teamStatus.quality, new Date(new Date().setHours(0, 0, 0, 0)), true);
|
||||
let teams = await ComBattleTeamModel.getTeamByRoleAndTime(roleId, [teamStatus.quality], new Date(new Date().setHours(0, 0, 0, 0)), true);
|
||||
if (teams.length >= assistanceTime) resResult(STATUS.COM_BATTLE_ASSIST_NOT_ENOUGH);
|
||||
|
||||
// 加入队伍
|
||||
let roleStatus = new RoleStatus(roleId, roleName, false, isFrd, headHid, sHid, topFiveCe, lv);
|
||||
const team = await ComBattleTeamModel.addRole(teamCode, roleStatus);
|
||||
if (!team || team.roleIds.length === 3) {
|
||||
if (!team || team.roleIds.length > 3) {
|
||||
return resResult(STATUS.COM_BATTLE_JOIN_ERR);
|
||||
}
|
||||
|
||||
@@ -447,6 +458,18 @@ export class ComBattleHandler {
|
||||
let channelService = this.app.get('channelService');
|
||||
let channel = channelService.getChannel(teamCode, false);
|
||||
channel.pushMessage('onComBtlStart', {teamCode, roleStatus: teamStatus.roleStatus});
|
||||
// 每场倒计时结算
|
||||
let thiz = this;
|
||||
setTimeout(async () => {
|
||||
let teamStatus = thiz.teamMap.get(teamCode);
|
||||
if (teamStatus.status === COM_TEAM_STATUS.FIGHTING) {
|
||||
let channelService = thiz.app.get('channelService');
|
||||
let channel = channelService.getChannel(teamCode, false);
|
||||
let team = await ComBattleTeamModel.syncTeamData({teamCode, status: COM_TEAM_STATUS.LOOSE, roleStatus: teamStatus.roleStatus});
|
||||
if (!team) return resResult(STATUS.COM_BATTLE_RESULT_ERR);
|
||||
channel.pushMessage('onTeamComplete', {teamCode, result: false});
|
||||
}
|
||||
}, COM_BATTLE_TIME_LMT);
|
||||
return resResult(STATUS.SUCCESS);
|
||||
}
|
||||
|
||||
@@ -521,41 +544,12 @@ export class ComBattleHandler {
|
||||
const roleStatus = teamStatus.roleStatus.map(st => {return {roleId: st.roleId, totalDmg: st.totalDmg, killed: st.killed}});
|
||||
channel.pushMessage('onTeammateAct', {teamCode, bossCurHp: teamStatus.bossCurHp, bossHpArr: teamStatus.bossHpArr, roleStatus});
|
||||
// 判断战斗是否结束
|
||||
if (teamStatus.bossCurHp === 0) {
|
||||
let team = await ComBattleTeamModel.syncTeamData({teamCode, status: COM_TEAM_STATUS.WIN, roleStatus: teamStatus.roleStatus});
|
||||
let battleSt = checkComBattleResult(teamStatus);
|
||||
if (battleSt === COM_TEAM_STATUS.WIN || battleSt === COM_TEAM_STATUS.LOOSE) {
|
||||
let result = battleSt === COM_TEAM_STATUS.WIN;
|
||||
let team = await ComBattleTeamModel.syncTeamData({teamCode, status: battleSt, roleStatus: teamStatus.roleStatus});
|
||||
if (!team) return resResult(STATUS.COM_BATTLE_RESULT_ERR);
|
||||
channel.pushMessage('onTeamComplete', {teamCode, result: true});
|
||||
} else {
|
||||
let allPlayerKilled = true;
|
||||
let robotRestHurt = 0;
|
||||
// 看看是否还有活人
|
||||
teamStatus.roleStatus.forEach(st => {
|
||||
if (!st.isRobot && st.killed.length < st.heroes.length) {
|
||||
allPlayerKilled = false
|
||||
}
|
||||
});
|
||||
// 没有活人的话看看还有没有机器人没打完伤害
|
||||
if (allPlayerKilled && teamStatus.curRnd < COM_BATTLE_ROBOT_ROUND_LMT) {
|
||||
teamStatus.roleStatus.forEach(st => {
|
||||
if (st.isRobot) {
|
||||
const deltaRnd = COM_BATTLE_ROBOT_ROUND_LMT - teamStatus.curRnd;
|
||||
let hurtHp = getRandValue(teamStatus.bossHp / COM_BATTLE_ROBOT_ROUND_LMT * COM_BATTLE_ROBOT_HURT_RATIO, COM_BATTLE_ROBOT_HURT_CH_RATIO, 0) * deltaRnd; // 1 个机器人对 boss 造成的总伤害
|
||||
robotRestHurt += hurtHp;
|
||||
}
|
||||
})
|
||||
}
|
||||
if (allPlayerKilled) {
|
||||
// 没有活人且机器人剩余伤害打不死 boss,战败
|
||||
if (teamStatus.bossCurHp > robotRestHurt) {
|
||||
let team = await ComBattleTeamModel.syncTeamData({teamCode, status: COM_TEAM_STATUS.LOOSE, roleStatus: teamStatus.roleStatus});
|
||||
if (!team) return resResult(STATUS.COM_BATTLE_RESULT_ERR);
|
||||
channel.pushMessage('onTeamComplete', {teamCode, result: false});
|
||||
} else {
|
||||
let team = await ComBattleTeamModel.syncTeamData({teamCode, status: COM_TEAM_STATUS.WIN, roleStatus: teamStatus.roleStatus});
|
||||
if (!team) return resResult(STATUS.COM_BATTLE_RESULT_ERR);
|
||||
channel.pushMessage('onTeamComplete', {teamCode, result: true});
|
||||
}
|
||||
}
|
||||
channel.pushMessage('onTeamComplete', {teamCode, result});
|
||||
}
|
||||
return resResult(STATUS.SUCCESS);
|
||||
}
|
||||
@@ -577,7 +571,6 @@ export class ComBattleHandler {
|
||||
let team = await ComBattleTeamModel.updateResult(teamCode, roleId, isSuccess);
|
||||
if (!team) return resResult(STATUS.COM_BATTLE_RESULT_ERR);
|
||||
// TODO: 根据策划结论考虑是否在推送中添加掉落
|
||||
// TODO: 用户总伤害等的持久化
|
||||
channel.pushMessage('onTeamComplete', {teamCode, result: isSuccess});
|
||||
} else if (!isSuccess) {
|
||||
let team = await ComBattleTeamModel.updateResult(teamCode, roleId, isSuccess);
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import { COM_BATTLE_ROBOT_ID_NAME, COM_BATTLE_ROBOT_CE_RATIO, COM_BATTLE_ROBOT_ROUND_LMT, COM_BATTLE_ROBOT_HURT_RATIO, COM_BATTLE_ROBOT_HURT_CH_RATIO, COM_TEAM_STATUS } from './../consts/consts';
|
||||
import { RoleStatus } from './../db/ComBattleTeam';
|
||||
import { getBluePrtByQuality } from "../pubUtils/gamedata";
|
||||
import { getRandEelm } from "../pubUtils/util";
|
||||
import { getRandEelm, getRandValue } from "../pubUtils/util";
|
||||
import { getRandRobot } from "./battleService";
|
||||
|
||||
/**
|
||||
* 在给定的品质列表中随机返回一定数量的藏宝图Id
|
||||
* @param qualityArr 品质数组,在所有给定品质的藏宝图中筛选1
|
||||
* @param cnt 返回藏宝图数量
|
||||
*/
|
||||
export async function getRandBlueprtId(qualityArr: Array<number>, cnt = 1) {
|
||||
export function getRandBlueprtId(qualityArr: Array<number>, cnt = 1) {
|
||||
if (!qualityArr || !qualityArr.length) return null;
|
||||
let blueprtIdArr = [];
|
||||
for (let q of qualityArr) {
|
||||
@@ -16,3 +19,55 @@ export async function getRandBlueprtId(qualityArr: Array<number>, cnt = 1) {
|
||||
const res = getRandEelm(blueprtIdArr, cnt);
|
||||
return res;
|
||||
}
|
||||
|
||||
export function getRandComBtlRobots(topFiveCe: number, lv: number, cnt: number) {
|
||||
let robotHeroes = getRandRobot(cnt); // 随机两个阵容
|
||||
// 创建并添加机器人
|
||||
let robotStArr = [], robotIdArr = [];
|
||||
for (let robot of robotHeroes) {
|
||||
const robotCe = getRandValue(topFiveCe, COM_BATTLE_ROBOT_CE_RATIO, 0);
|
||||
const robotLv = getRandValue(lv, COM_BATTLE_ROBOT_CE_RATIO, 0);
|
||||
const imgHid = robot[Math.floor(Math.random() * robot.length)];
|
||||
const { robotRoleId, robotRoleName } = COM_BATTLE_ROBOT_ID_NAME[Math.floor(Math.random() * COM_BATTLE_ROBOT_ID_NAME.length)];
|
||||
let robotStatus = new RoleStatus(robotRoleId, robotRoleName, false, false, imgHid, imgHid, robotCe, robotLv, robot, true);
|
||||
robotStArr.push(robotStatus);
|
||||
robotIdArr.push(robotRoleId);
|
||||
}
|
||||
return {
|
||||
robotStArr, robotIdArr
|
||||
}
|
||||
}
|
||||
|
||||
export function checkComBattleResult(teamStatus) {
|
||||
if (teamStatus.bossCurHp === 0) {
|
||||
return COM_TEAM_STATUS.WIN;
|
||||
} else {
|
||||
let allPlayerKilled = true;
|
||||
let robotRestHurt = 0;
|
||||
// 看看是否还有活人
|
||||
teamStatus.roleStatus.forEach(st => {
|
||||
if (!st.isRobot && st.killed.length < st.heroes.length) {
|
||||
allPlayerKilled = false
|
||||
}
|
||||
});
|
||||
// 没有活人的话看看还有没有机器人没打完伤害
|
||||
if (allPlayerKilled && teamStatus.curRnd < COM_BATTLE_ROBOT_ROUND_LMT) {
|
||||
teamStatus.roleStatus.forEach(st => {
|
||||
if (st.isRobot) {
|
||||
const deltaRnd = COM_BATTLE_ROBOT_ROUND_LMT - teamStatus.curRnd;
|
||||
let hurtHp = getRandValue(teamStatus.bossHp / COM_BATTLE_ROBOT_ROUND_LMT * COM_BATTLE_ROBOT_HURT_RATIO, COM_BATTLE_ROBOT_HURT_CH_RATIO, 0) * deltaRnd; // 1 个机器人对 boss 造成的总伤害
|
||||
robotRestHurt += hurtHp;
|
||||
}
|
||||
})
|
||||
}
|
||||
if (allPlayerKilled) {
|
||||
// 没有活人且机器人剩余伤害打不死 boss,战败
|
||||
if (teamStatus.bossCurHp > robotRestHurt) {
|
||||
return COM_TEAM_STATUS.LOOSE;
|
||||
} else {
|
||||
return COM_TEAM_STATUS.WIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
return COM_TEAM_STATUS.FIGHTING;
|
||||
}
|
||||
@@ -11,6 +11,7 @@ declare module 'redis' {
|
||||
hdelAsync(...args: any[]): Promise<any>;
|
||||
spopAsync(...args: any[]): Promise<any>;
|
||||
sremAsync(...args: any[]): Promise<any>;
|
||||
sismemberAsync(...args: any[]): Promise<any>;
|
||||
srandmemberAsync(...args: any[]): Promise<any>;
|
||||
}
|
||||
export interface Multi extends Commands<Multi> {
|
||||
@@ -177,6 +178,16 @@ export async function getTeamSearchByQuality(quality: number) {
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function checkRoleInQueue(roleId: string, sid: string, qualityArr: Array<number>) {
|
||||
for (let quality of qualityArr) {
|
||||
let res = await client.sismemberAsync(`${REDIS_KEY.COM_TEAM_SEARCH_PRE}${quality}`, `${roleId}:${sid}`);
|
||||
if (res) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
/**************** 寻宝相关 end */
|
||||
|
||||
////// redis方法
|
||||
|
||||
@@ -277,8 +277,8 @@ export const COM_TEAM_ENABLE_LV = 1;
|
||||
export const COM_ASSIST_DROP_RATE = 0.5;
|
||||
// 藏宝图伪随机所需体力
|
||||
export const COM_BLUEPRT_DROP_PER_AP = 10;
|
||||
// 每局时长限制,秒
|
||||
export const COM_BATTLE_TIME_LMT = 10 * 60;
|
||||
// 每局时长限制
|
||||
export const COM_BATTLE_TIME_LMT = 10 * 60 * 1000;
|
||||
// 机器人生成时间,秒
|
||||
// export const COM_BATTLE_ROBOT_TIME_LMT = 1;
|
||||
// 每个机器人消耗 boss 血量百分比
|
||||
|
||||
@@ -102,7 +102,7 @@ export default class ComBattleTeam extends BaseModel {
|
||||
}
|
||||
|
||||
public static async addRole(teamCode: string, roleStatus: RoleStatus, lean = true) {
|
||||
const team = await ComBattleTeamModel.findOneAndUpdate({ teamCode }, {$push: {roleIds: roleStatus.roleId, roleStatus}}, {upsert: true, new: true}).lean(lean);
|
||||
const team = await ComBattleTeamModel.findOneAndUpdate({ teamCode }, {$push: {roleIds: roleStatus.roleId, roleStatus}}, {new: true}).lean(lean);
|
||||
return team;
|
||||
}
|
||||
|
||||
@@ -173,10 +173,10 @@ export default class ComBattleTeam extends BaseModel {
|
||||
return team;
|
||||
}
|
||||
|
||||
public static async getTeamByRoleAndTime(roleId: string, quality?: number, time?: Date, isAssist?: boolean, limitCnt = 50, lean = true) {
|
||||
public static async getTeamByRoleAndTime(roleId: string, qualityArr?: Array<number>, time?: Date, isAssist?: boolean, limitCnt = 50, lean = true) {
|
||||
let query = {roleIds: roleId};
|
||||
if (quality) {
|
||||
query = Object.assign(query, {quality});
|
||||
if (qualityArr) {
|
||||
query = Object.assign(query, {quality: {$in: qualityArr}});
|
||||
}
|
||||
if (time) {
|
||||
query = Object.assign(query, {createdAt: {$gte: time}});
|
||||
|
||||
Reference in New Issue
Block a user