/** * 体力系统 */ import { PvpDefenseModel, Heroes, OppPlayers, Robot, PvpDefenseType, HeroScores } from '../db/PvpDefense'; import { RoleType } from '../db/Role'; import { PVP_HERO_POS, ROBOT_NAME, REDIS_KEY } from '../consts'; import { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent"; import { getRandomIndexByLen, genCode, getRandomByLen } from '../pubUtils/util'; import { oppPlayersInter, RankParam } from '../pubUtils/interface'; import { gameData, getPLvByScore } from "../pubUtils/data"; import { PVP } from '../pubUtils/dicParam'; import { SystemConfigModel } from '../db/SystemConfig' import { setRank, getMyRank } from './redisService'; const _ = require('underscore'); export async function initPvpInfo(role: RoleType) { let heroes: Array = []; //初始化最强5人阵容 for (let i = PVP_HERO_POS.START; i <= PVP_HERO_POS.END; i++) { let index = i - PVP_HERO_POS.START; let item = role.topFive[index]; heroes.push({ actorId: item?.hid||0, hero: item?.hero||null, ce: item?.ce||0, dataId: i, order: index + 1, }); } //初始化对手人阵容 let oppPlayers: Array = await refreshEnemies(role, 0, 1); let {warId, seasonNum } = await SystemConfigModel.findSystemConfig(); let challengeCnt = PVP.PVP_CHALLENGE_COUNTS; let result = await PvpDefenseModel.createPvpDefense({ roleId: role.roleId, roleName: role.roleName, role: role._id, heroes, oppPlayers, defCe: role.topFiveCe, seasonNum, warId, challengeCnt }); //加入排行榜 let { roleId, roleName, lv, vLv, headHid, sHid, title } = role; let params = new RankParam(roleName, lv, vLv, headHid, sHid, title); await setRank(REDIS_KEY.PVP_RANK, 0, roleId, result.score, result.updatedAt.getTime(), params); 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 async function getEnemies(oppPlayers: OppPlayers[], winStreakNum: number) { let result = new Array(); 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, rankLv: 0, plusScore: getPlusScore(winStreakNum) }); } else { let opp = oppDef; let role = opp.role; let { roleId, roleName, headHid, sHid } = role; let { pLv, defCe } = opp; let rankLv = await getMyRank(REDIS_KEY.PVP_RANK, 0, roleId); result.push({ pos, roleId, roleName, headHid, sHid, pLv, defCe, addScore: dicOpponent.score, rankLv, // 读取排名 plusScore: getPlusScore(winStreakNum) }); } } return result } // TODO 刷新对手 export async function refreshEnemies(role: RoleType, score: number, pLv: number) { let { roleId, topFiveCe } = role; let oppPlayers = new Array(); 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) { console.log(range.length) range.splice(index, 1); console.log(JSON.stringify(range)) if(range.length <= 0) return false; index = getRandomIndexByLen(range.length); result = range[index]; } oppPlayers.push({ roleId: result.roleId, 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 hisPLv = Math.floor(pLv + (minLv + maxLv)/2); if(hisPLv < 1) hisPLv = 1 let robot = new Robot(roleId, roleName, Math.floor(myCe * ratio), hisPLv, result.war_id) oppPlayers.push({ roleId, 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 < 0) result = 0; if(result > PVP.PVP_WINREWARD_UPLIMIT) result = PVP.PVP_WINREWARD_UPLIMIT; return result; } export function getLvByScore(heroScores: HeroScores[]) { heroScores.sort((a, b) => b.score - a.score); let score = 0; for(let i = 0; i < 5; i++) { if(!heroScores[i]) break; score += heroScores[i].score; } return getPLvByScore(score); } export async function defaultHeroes ( role:RoleType) { let { heroes } = await PvpDefenseModel.findByRoleId(role.roleId); heroes.sort(function(a, b) { return a.ce + a.dataId - b.ce + b.dataId; }); role.topFive.sort(function(a, b) { return a.ce - b.ce; }); let defCe = 0; for (let i = 1; i < role.topFive.length; i++) { let item = role.topFive[i]; if (!_.findWhere(heroes, {actorId: item.hid})) { for (let j = 0; j < heroes.length; j++) { let hero = heroes[j]; if (heroes.length >= 5 && !hero.actorId) { continue; } let index = _.findIndex(role.topFive,{hid: hero.actorId}); if (index == -1) { hero.actorId = item.hid; hero.hero = item.hero||''; hero.ce = item.ce||0; } else { heroes[index].ce = item.ce||0; } } } defCe += item.ce; } let { heroes: resHeroes} = await PvpDefenseModel.updateInfo(role.roleId, {defCe, heroes}); return { resHeroes}; }