pvp随机地图

This commit is contained in:
mamengke01
2021-01-07 12:25:40 +08:00
parent a339b8adcc
commit 94fc48a59a
17 changed files with 327 additions and 84 deletions
+10 -1
View File
@@ -14,7 +14,7 @@ import * as routeUtil from './app/util/routeUtil';
import { preload } from './preload';
var checkEventFilter = require('./app/servers/battle/filter/checkEventFilter');
import { connectRedis } from './config/redis';
import * as timeTaskService from './app/services/timeTaskService';
// TODO 需要整理。
import _pinus = require('pinus');
@@ -102,6 +102,15 @@ app.configure('production|development|alpha|dev', 'gate', function () {
});
});
app.configure('production|development|alpha|dev', 'systimer', function () {
app.set('connectorConfig',
{
connector: pinus.connectors.hybridconnector,
useProtobuf: true
});
timeTaskService.init();
});
function errorHandler(err: Error, msg: any, resp: any,
session: FrontendOrBackendSession, cb: HandlerCallback) {
@@ -1,7 +1,7 @@
import {Application, BackendSession} from 'pinus';
const _ = require('underscore');
import { gameData } from '../../../pubUtils/data';
import { checkPvp, initPvpInfo, refreshEnemies, getEnemies } from '../../../pubUtils/pvpUtil';
import { checkPvp, initPvpInfo, refreshEnemies, getEnemies, } from '../../../services/pvpService';
import { RoleModel, RoleType } from '../../../db/Role';
import { STATUS } from '../../../consts/statusCode';
import { resResult } from '../../../pubUtils/util';
@@ -25,13 +25,15 @@ export class PvpHandler {
async getData (msg: {}, session: BackendSession) {
let roleId = session.get('roleId');
let roleName = session.get('roleName');
let sid = session.get('sid');
let serverId = session.get('serverId');
let result = await PvpDefenseModel.findByRoleIdIncludeAll(roleId);
let system = await SystemConfigModel.findSystemConfig();
return resResult(STATUS.SUCCESS, { data: result });
let {heroes, score, pLv, winStreakNum, oppPlayers: oppPlayerInfos, refOppCnt, challengeCnt, challengeRefTime, receivedBox, hisScore, heroScores, seasonNum: playerSeaSonNum} = await PvpDefenseModel.findByRoleIdIncludeAll(roleId);
let oppPlayers = getEnemies(oppPlayerInfos, winStreakNum);
let {warId, seasonNum, seasonEndTime} = await SystemConfigModel.findSystemConfig();
if (playerSeaSonNum !== seasonNum) {
//TODO去结算
}
let myRank = 999;//TODO去redis中获取
let data = {warId, seasonNum, seasonEndTime, myRank, oppPlayers, heroes, score, pLv, winStreakNum, refOppCnt, challengeCnt, challengeRefTime, receivedBox, hisScore, heroScores}
return resResult(STATUS.SUCCESS, { data: data });
}
@@ -2,7 +2,7 @@
* 体力系统
*/
import { fromCallback } from 'bluebird';
import { checkPvp } from '../pubUtils/pvpUtil'
import { checkPvp } from '../services/pvpService'
import { getFuncsSwitch } from '../pubUtils/data';
import { FUNCS_ID, FUNC_OPT_TYPE } from '../consts/constModules/sysConst';
import { RoleModel } from '../db/Role'
+156
View File
@@ -0,0 +1,156 @@
/**
* 体力系统
*/
import { PvpDefenseModel, Heroes, OppPlayers, Robot, PvpDefenseType } from '../../../shared/db/pvpDefense';
import { RoleType } from '../../../shared/db/Role';
import { PVP_HERO_POS, ROBOT_NAME } from '../../../shared/consts';
import { dicPvpOpponent, DicPvpOpponent } from "../../../shared/pubUtils/dictionary/DicPvpOpponent";
import { getRandomIndexByLen, genCode, getRandomByLen } from '../../../shared/pubUtils/util';
import { oppPlayersInter } from '../../../shared/pubUtils/interface';
import { gameData } from "../../../shared/pubUtils/data";
export async function initPvpInfo(role: RoleType) {
let heroes: Array<Heroes> = [];
//初始化最强5人阵容
for (let i = 0; i < role.topFive.length; i++) {
let item = role.topFive[i];
if (item.hid) {
heroes.push({
actorId: item.hid,
hero: item.hero,
ce: item.ce,
dataId: PVP_HERO_POS.START + i,
order: i + 1,
});
}
}
//初始化对手人阵容
let oppPlayers: Array<OppPlayers> = await refreshEnemies(role, 0, 1);
let result = await PvpDefenseModel.createPvpDefense({ roleId: role.roleId, roleName: role.roleName, role: role._id, heroes, oppPlayers, defCe: role.topFiveCe });
//加入排行榜 TODO
return result;
}
export async function checkPvp(role: RoleType) {
let result = await PvpDefenseModel.findByRoleId(role.roleId);
if (!!result)
return result;
result = await initPvpInfo(role);
return result;
}
/**
* 返回对手三人信息
*
* @param oppPlayers pvpDefense表中的oppPlayers字段,需要populate过的
* @param pLv 玩家本人的队伍等级
*/
export function getEnemies(oppPlayers: OppPlayers[], winStreakNum: number) {
let result = new Array<oppPlayersInter>();
for(let {pos, isRobot, oppDef, robot} of oppPlayers) {
let dicOpponent = dicPvpOpponent.get(pos);
if(isRobot) {
let { roleId, roleName, headHid, sHid, pLv, defCe } = robot;
result.push({
pos, roleId, roleName, headHid, sHid, pLv, defCe,
addScore: dicOpponent.score,
plusScore: getPlusScore(winStreakNum)
});
} else {
let opp = <PvpDefenseType>oppDef;
let role = <RoleType>opp.role;
let { roleId, roleName, headHid, sHid } = role;
let { pLv, defCe } = opp;
result.push({
pos, roleId, roleName, headHid, sHid, pLv, defCe,
addScore: dicOpponent.score,
plusScore: getPlusScore(winStreakNum)
});
}
}
return result
}
// TODO 刷新对手
export async function refreshEnemies(role: RoleType, score: number, pLv: number) {
let { roleId, topFiveCe } = role;
let oppPlayers = new Array<OppPlayers>();
let opp = dicPvpOpponent.values()
for(let dicOpp of opp) {
let flag = false; // 是否筛选成功
if(score > 3000) { // TODO 将这个放到const
flag = await matchPlayer(oppPlayers, roleId, pLv, dicOpp);
// TODO 当前后分数段没有时,返回前一名的玩家
if(!flag) flag = matchRobot(oppPlayers, topFiveCe, pLv, dicOpp);
} else {
flag = matchRobot(oppPlayers, topFiveCe, pLv, dicOpp);
}
if(!flag) continue;
}
return oppPlayers;
}
async function matchPlayer(oppPlayers: OppPlayers[], roleId: string, pLv: number, dicOpp: DicPvpOpponent ) {
let { id: pos, minLv, maxLv } = dicOpp
let range = await PvpDefenseModel.findByTeamLv(pLv + minLv, pLv + maxLv);
if(range.length <= 0) return false;
let index = getRandomIndexByLen(range.length);
let result = range[index];
if(!result) return false;
if(result.roleId == roleId) {
range.splice(index, 1);
if(range.length <= 0) return false;
index = getRandomIndexByLen(range.length);
result = range[range.length];
}
oppPlayers.push({
oppDef: result._id,
pos,
isRobot: false,
robot: null
});
return true;
}
function matchRobot(oppPlayers: OppPlayers[], myCe: number, pLv: number, dicOpp: DicPvpOpponent) {
let { id: pos, minLv, maxLv, ratio } = dicOpp;
let range = gameData.pvpWar;
if(range.length <= 0) return false;
let index = getRandomIndexByLen(range.length);
let result = range[index];
if(!result) return false;
let roleId = generateRobotRoleId();
let roleName = getRandomByLen(ROBOT_NAME);
let robot = new Robot(roleId, roleName, Math.floor(myCe * ratio), Math.floor(pLv + (minLv + maxLv)/2), result.war_id)
oppPlayers.push({
oppDef: null,
pos,
isRobot: true,
robot
});
return true
}
// 生成机器人roleId
function generateRobotRoleId() {
return `${genCode(10)}_r`;
}
// 根据roleId判断是不是机器人
export function checkRoleIsRobot(roleId: string) {
return !!roleId.match(/_r/);
}
// 根据连胜次数,获得加成的积分
export function getPlusScore(win: number) {
let result = win - 1;
if(result > 10) result = 10;
return result;
}
+62 -4
View File
@@ -2,12 +2,70 @@
* 体力系统
*/
import { scheduleJob, cancelJob } from 'pinus-scheduler';
import { scheduleJob } from 'pinus-scheduler';
import { SystemConfigModel } from '../db/SystemConfig';
import PvpDefenseType,{ PvpDefenseModel } from '../db/pvpDefense';
import { PVP } from '../pubUtils/dicParam';
import { nowSeconds, getTodayZeroPoint } from '../pubUtils/timeUtil';
import { getPvpGkWarIds } from '../pubUtils/data';
import { getRandomArr } from '../pubUtils/util';
const _ = require('underscore');
const PER_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60;
const SETTLE_DIFF = 29 * 60;
const LIMIT_NUM = 1000;
export async function init() {
scheduleJob("0 31 23 * * *", setPvpSeasonResult, {name:'setPvpSeasonResult'})
let seasonEndTime = 0;
let systemConfig = await SystemConfigModel.findSystemConfig();
if (!systemConfig) {
let warIds = getPvpGkWarIds();
let warId = warIds[0];//TODO随机地图
seasonEndTime = PVP.PVP_SEASON_DAYS * PER_DAY + getTodayZeroPoint();
await SystemConfigModel.createSystemConfig( seasonEndTime, warId );
} else {
seasonEndTime = systemConfig.seasonEndTime;
if (systemConfig.seasonEndTime - SETTLE_DIFF <= nowSeconds()) {
await setPvpSeasonResult();
seasonEndTime = PVP.PVP_SEASON_DAYS * PER_DAY + getTodayZeroPoint();
systemConfig.seasonNum++;
await SystemConfigModel.updateSystemConfig({ seasonEndTime, seasonNum: systemConfig.seasonNum});
}
}
let settleTime = seasonEndTime - SETTLE_DIFF - nowSeconds();
// setTimeout(setPvpSeasonResult, settleTime * PER_SECOND);
scheduleJob("0 0 0 * * 1", resetPvpWarId)
}
export async function setPvpSeasonResult() {
console.log('setPvpSeasonResult');
let pvpDefenses = await PvpDefenseModel.getPvpDef(LIMIT_NUM);
for (let pvpDefense of pvpDefenses) {
await setPvpDefResult(pvpDefense);
}
await setNextPvpTime();
}
async function setPvpDefResult(pvpDefense: PvpDefenseType) {
await PvpDefenseModel.updateInfo(pvpDefense.roleId, {score:100, pLv: 1});
}
export async function resetPvpWarId() {
console.log('resetPvpWarId');
let systemConfig = await SystemConfigModel.findSystemConfig();
let warIds = getPvpGkWarIds();
let index = _.indexOf(warIds, systemConfig.warId);
if (index != -1) {
warIds.splice(index, 1);
}
let res = getRandomArr(warIds, 1);
let warId = res[0];//TODO随机地图
await SystemConfigModel.updateSystemConfig({ warId });
}
async function setNextPvpTime() {
let seasonEndTime = PVP.PVP_SEASON_DAYS * PER_DAY + getTodayZeroPoint();
await SystemConfigModel.updateSeason(seasonEndTime);
let settleTime = seasonEndTime - SETTLE_DIFF - nowSeconds();
setTimeout(setPvpSeasonResult, settleTime * PER_SECOND);
}
+1 -2
View File
@@ -19,5 +19,4 @@ module.exports = [{
}, {
'type': 'systimer',
'token': 'agarxhqb98rpajloaxn34ga8xrunpagkjwlaw3ruxnpaagl29w4rxn'
}
];
}];
+96 -1
View File
@@ -1,3 +1,98 @@
module.exports = {
'onChat': {
'required string msg': 1,
'required string from': 2,
'required string target': 3
},
'onItemUpdate': {
'message Data': {
"message Good": {
'required uInt32 id': 1,
'required uInt32 count': 2,
},
'repeated Good goods': 1,
},
'required string msg': 1,
'required uInt32 code': 2,
'required Data data': 3
},
'onPlayerCeUpdate': {
'message Data': {
"message Hero": {
'required uInt32 hid': 1,
'required uInt32 ce': 2,
},
'required uInt32 ce': 1,
'repeated Hero heros': 2,
'required uInt32 topFiveCe': 3
},
'required string msg': 1,
'required uInt32 code': 2,
'required Data data': 3
},
'onPlayerDataChange': {
'message Data': {
'optional uInt32 coin': 1,
'optional uInt32 giftGold': 2,
'optional uInt32 gold': 3,
'optional uInt32 ap': 4
},
'required string msg': 1,
'required uInt32 code': 2,
'required Data data': 3
},
'onHeroSkinChange': {
'message Data': {
"message SkinInfo": {
"message Skin": {
'required uInt32 id': 1,
'required boolean enable': 2
},
'repeated Skin skins': 1,
},
'repeated SkinInfo skinInfos': 1
},
'required string msg': 1,
'required uInt32 code': 2,
'required Data data': 3
},
'onEquipAdd': {
'message Data': {
"message EquipInfo": {
"message RandSe": {
'required uInt32 id': 1,
'required uInt32 seid': 2,
'required int32 rand': 3,
'required boolean locked': 4
},
"message Hole": {
'required uInt32 id': 1,
'required boolean isOpen': 2,
'required uInt32 jewel': 3
},
'repeated Hole holes': 1,
'repeated RandSe randSe': 2,
'required uInt32 seqId': 3,
'required uInt32 id': 4,
'required uInt32 hid': 6,
'required uInt32 count': 7,
'required uInt32 quality': 8,
'required uInt32 ePlaceId': 9,
'required uInt32 suitId': 11,
'required int32 randRange': 12
},
'repeated EquipInfo equipInfos': 1
},
'required string msg': 1,
'required uInt32 code': 2,
'required Data data': 3
},
'onEquipDel': {
'message Data': {
'repeated uInt32 equips': 1
},
'required string msg': 1,
'required uInt32 code': 2,
'required Data data': 3
}
};
+3
View File
@@ -40,6 +40,9 @@ module.exports = {
'frontend': true,
"args": " --inspect=9236"
}
],
'systimer': [
{'id': 'systimer-server-1', 'host': '127.0.0.1', 'port': 6056, "args": " --inspect=9233"}
]
},
'production': {