646 lines
24 KiB
TypeScript
646 lines
24 KiB
TypeScript
|
||
import { PvpDefenseModel, Heroes, OppPlayers, PvpDefenseType, HeroScores, pvpUpdateInter } from '../db/PvpDefense';
|
||
import { RoleType } from '../db/Role';
|
||
import { PVP_HERO_POS, REDIS_KEY, PVP_CONST, COUNTER } from '../consts';
|
||
import { setPvpDefResult } from '../services/timeTaskService';
|
||
import { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent";
|
||
import { getRandSingleIndex, genCode, shouldRefresh, getChineseName } from '../pubUtils/util';
|
||
import { oppPlayersInter, pvpEndParamInter } from '../pubUtils/interface';
|
||
import { gameData, getPLvByScore } from "../pubUtils/data";
|
||
import { PVP } from '../pubUtils/dicParam';
|
||
import { PVPConfigModel } from '../db/SystemConfig'
|
||
import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil';
|
||
import { HeroesRecord } from '../db/PvpRecord';
|
||
import { HeroModel } from '../db/Hero';
|
||
import { CeAttrData, CeAttrDataRole, AttributeCal } from '../domain/roleField/attribute';
|
||
import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from '../domain/dbGeneral';
|
||
import { DicWarJson } from '../pubUtils/dictionary/DicWarJson';
|
||
import { findWhere, findIndex } from 'underscore';
|
||
import { pinus } from 'pinus';
|
||
import { PvpHistoryOppModel, PvpHistoryOppType } from '../db/PvpHistoryOpp';
|
||
import { Rank } from './rankService';
|
||
import { CounterModel } from '../db/Counter';
|
||
|
||
export async function getPvpData() {
|
||
|
||
}
|
||
|
||
|
||
export async function initPvpInfo(role: RoleType) {
|
||
let heroes: Array<Heroes> = [];
|
||
//初始化最强5人阵容
|
||
let defCe = 0;
|
||
for (let i = PVP_HERO_POS.START; i <= PVP_HERO_POS.END; i++) {
|
||
let index = i - PVP_HERO_POS.START;
|
||
let item = role.topLineup[index];
|
||
if (item) defCe += item.ce;
|
||
heroes.push({
|
||
actorId: item?.hid || 0,
|
||
hero: item?.hero || null,
|
||
ce: item?.ce || 0,
|
||
dataId: i,
|
||
order: index + 1,
|
||
});
|
||
}
|
||
//初始化对手人阵容
|
||
let oppPlayers: Array<OppPlayers> = await refreshEnemies(role, 0, 1);
|
||
let { seasonNum } = await PVPConfigModel.findCurPVPConfig();
|
||
let challengeCnt = PVP.PVP_CHALLENGE_COUNTS;
|
||
let result = await PvpDefenseModel.createPvpDefense({ roleId: role.roleId, roleName: role.roleName, role: role._id, heroes, oppPlayers, defCe, seasonNum, challengeCnt });
|
||
|
||
//加入排行榜
|
||
let r = new Rank(REDIS_KEY.PVP_RANK, {});
|
||
await r.setRankWithRoleInfo(REDIS_KEY.PVP_RANK, result.score, result.updatedAt.getTime(), role, false);
|
||
|
||
return result;
|
||
}
|
||
|
||
export async function checkPvp(role: RoleType) {
|
||
if (role.hasInit) {
|
||
let result = await PvpDefenseModel.findByRoleId(role.roleId, true);
|
||
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<oppPlayersInter>();
|
||
for (let oppPlayer of oppPlayers) {
|
||
let dicOpponent = dicPvpOpponent.get(oppPlayer.pos);
|
||
let oppDef = <PvpHistoryOppType>oppPlayer.oppDef; // select 'oppRoleId pos roleName head frame spine rankLv pLv defCe'
|
||
if (oppDef) delete oppDef.heroes;
|
||
result.push({
|
||
...oppDef,
|
||
roleId: oppDef.oppRoleId,
|
||
defCe: oppDef.defCe,
|
||
addScore: dicOpponent.score,
|
||
rankLv: oppDef.rankLv,
|
||
plusScore: getPlusScore(winStreakNum)
|
||
});
|
||
}
|
||
return result
|
||
}
|
||
|
||
/**
|
||
* @description 刷新对手三个人
|
||
* @param role 数据库里我的role
|
||
* @param score 我的军功
|
||
* @param pLv 我的排名
|
||
*/
|
||
export async function refreshEnemies(role: RoleType, score: number, pLv: number) {
|
||
let system = await PVPConfigModel.findCurPVPConfig();
|
||
let mapWarJson = gameData.warJson.get(system.warId);
|
||
|
||
let { roleId } = role;
|
||
let oppPlayers = new Array<OppPlayers>();
|
||
let opp = dicPvpOpponent.values()
|
||
for (let dicOpp of opp) {
|
||
let flag = false; // 是否筛选成功
|
||
if (score >= PVP_CONST.SCORE_LINE) { // 将这个放到const
|
||
flag = await matchPlayer(system.seasonNum, oppPlayers, mapWarJson, roleId, pLv, dicOpp); // 按照等级匹配对手
|
||
if (!flag) flag = await matchPlayerByRank(system.seasonNum, oppPlayers, mapWarJson, roleId, dicOpp.id); // 当前后分数段没有时,返回前一名的玩家
|
||
if (!flag) flag = await matchRobot(oppPlayers, mapWarJson, role, pLv, dicOpp);
|
||
} else {
|
||
flag = await matchRobot(oppPlayers, mapWarJson, role, pLv, dicOpp);
|
||
}
|
||
if (!flag) continue;
|
||
}
|
||
|
||
return oppPlayers;
|
||
}
|
||
|
||
export async function matchPlayerByRank(seasonNum: number, oppPlayers: OppPlayers[], mapWarJson: DicWarJson[], roleId: string, pos: number) {
|
||
// console.log('matchPlayerByRank', JSON.stringify(oppPlayers))
|
||
let r = new Rank(REDIS_KEY.PVP_RANK, {});
|
||
let ridRanks = new Array<number>(); // 已经被使用了的排名
|
||
for (let { roleId: curRoleId } of oppPlayers) {
|
||
let rankLv = await r.getMyRank({ roleId: robotIdComBack(curRoleId) });
|
||
ridRanks.push(rankLv);
|
||
}
|
||
|
||
let myRank = await r.getMyRank({ roleId });
|
||
ridRanks.push(myRank);
|
||
|
||
let oppRoleId = '';
|
||
let oppRank = 0;
|
||
if (myRank == 0) {
|
||
return false
|
||
} else if (myRank == 1) { // 第一名
|
||
if (pos == 1) {
|
||
oppRank = 2;
|
||
while (ridRanks.includes(oppRank)) {
|
||
oppRank--;
|
||
}
|
||
} else if (pos == 2) {
|
||
oppRank = 3;
|
||
while (ridRanks.includes(oppRank)) {
|
||
oppRank--;
|
||
}
|
||
} else {
|
||
oppRank = 4;
|
||
while (ridRanks.includes(oppRank)) {
|
||
oppRank++;
|
||
}
|
||
}
|
||
} else if (myRank == 0) {
|
||
return false
|
||
} else {
|
||
if (pos == 1 || pos == 2) { // 刷新我前一名
|
||
oppRank = myRank - 1;
|
||
while (ridRanks.includes(oppRank)) {
|
||
oppRank--;
|
||
}
|
||
} else { // 刷新我后一名
|
||
oppRank = myRank + 1;
|
||
while (ridRanks.includes(oppRank)) {
|
||
oppRank++;
|
||
}
|
||
}
|
||
}
|
||
let result = await r.getUserByRank(oppRank);
|
||
if (result.length <= 0) return false;
|
||
oppRoleId = result[0];
|
||
|
||
let pvpdefense = await PvpDefenseModel.findByRoleIdIncludeAll(oppRoleId);
|
||
if (!pvpdefense || pvpdefense.seasonNum != seasonNum) return false;
|
||
let pvpHistoryOpp = await generPlayerOppHis(pvpdefense, mapWarJson, roleId, pos);
|
||
if (!pvpHistoryOpp) return false;
|
||
|
||
oppPlayers.push({
|
||
roleId: pvpHistoryOpp.oppRoleId,
|
||
oppDef: pvpHistoryOpp._id,
|
||
pos,
|
||
isRobot: false,
|
||
});
|
||
return true
|
||
}
|
||
|
||
async function matchPlayer(seasonNum: number, oppPlayers: OppPlayers[], mapWarJson: DicWarJson[], roleId: string, pLv: number, dicOpp: DicPvpOpponent) {
|
||
// console.log('matchPlayer', JSON.stringify(oppPlayers))
|
||
|
||
let { id: pos, minLv, maxLv } = dicOpp
|
||
let range = await PvpDefenseModel.findByTeamLv(seasonNum, pLv + minLv, pLv + maxLv);
|
||
range = range.filter(cur => {
|
||
return oppPlayers.findIndex(ccur => ccur.roleId == makeRobotId(cur.roleId)) == -1;
|
||
});
|
||
if (range.length <= 0) return false;
|
||
|
||
let index = getRandSingleIndex(range.length);
|
||
let result = range[index]; // 本次匹配结果 pvpdefense
|
||
if (!result) return false;
|
||
if (result.roleId == roleId) {
|
||
range.splice(index, 1);
|
||
if (range.length <= 0) return false;
|
||
index = getRandSingleIndex(range.length);
|
||
result = range[index];
|
||
}
|
||
let pvpHistoryOpp = await generPlayerOppHis(result, mapWarJson, roleId, pos);
|
||
if (!pvpHistoryOpp) return false;
|
||
oppPlayers.push({
|
||
roleId: pvpHistoryOpp.oppRoleId,
|
||
oppDef: pvpHistoryOpp._id,
|
||
pos,
|
||
isRobot: false,
|
||
});
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* @description 对手是玩家时,生成并返回pvpHistoryOpp
|
||
* @param result 随机出的对手pvpDefense
|
||
* @param mapWarJson 本周地图出兵表
|
||
* @param roleId 自己的玩家id
|
||
* @param pos 刷新这个对手的位置
|
||
*/
|
||
async function generPlayerOppHis(pvpdefense: PvpDefenseType, mapWarJson: DicWarJson[], roleId: string, pos: number) {
|
||
let { heroScores, heroes: defenseHeroes } = pvpdefense;
|
||
let role = <RoleType>pvpdefense.role;
|
||
let r = new Rank(REDIS_KEY.PVP_RANK, {});
|
||
let rankLv = await r.getMyRank({ roleId: role.roleId });
|
||
let dbHeroes = await HeroModel.findByRole(role.roleId, [{ field: 'ce', sortBy: -1 }]);
|
||
let heroes = new Array<PvpEnemies>();
|
||
let otherHeroes = new Array<PvpOtherHeroes>(); // 阵容外的所有武将信息
|
||
for (let dbHero of dbHeroes) {
|
||
let h = defenseHeroes.find(cur => cur.actorId == dbHero.hid); // 阵容里是否有这个武将
|
||
let hs = heroScores.find(cur => cur.hid == dbHero.hid); // 这个武将是否有这个得分
|
||
if (!!h) {
|
||
let warJson = mapWarJson.find(cur => cur.dataId == h.dataId);
|
||
if (warJson && warJson.relation == 2) {
|
||
let heroInfo = new PvpHeroInfo();
|
||
heroInfo.setHeroInfo(dbHero);
|
||
heroInfo.setOutIndex(h.order);
|
||
let { attribute, ce } = getPlayerAttribute(dbHero.attr, role.attr);
|
||
heroInfo.setAttribute(attribute);
|
||
let enemy = new PvpEnemies(warJson, heroInfo, hs ? hs.score : 0, ce);
|
||
heroes.push(enemy);
|
||
}
|
||
} else {
|
||
let heroInfo = new PvpOtherHeroes(hs ? hs.score : 0);
|
||
heroInfo.setHeroInfo(dbHero);
|
||
otherHeroes.push(heroInfo);
|
||
}
|
||
}
|
||
heroes.sort((a, b) => b.score - a.score);
|
||
otherHeroes.sort((a, b) => b.score - a.score);
|
||
|
||
let pvpHistoryOpp = await PvpHistoryOppModel.createPvpOpp({
|
||
...pvpdefense, ...role, pos, rankLv, heroes, otherHeroes, roleId, oppRoleId: makeRobotId(pvpdefense.roleId)
|
||
});
|
||
return pvpHistoryOpp;
|
||
}
|
||
|
||
async function matchRobot(oppPlayers: OppPlayers[], mapWarJson: DicWarJson[], role: RoleType, pLv: number, dicOpp: DicPvpOpponent) {
|
||
// console.log('matchRobot', JSON.stringify(oppPlayers))
|
||
|
||
let { lv: myLv, topLineupCe: myCe, roleId } = role;
|
||
let { id: pos, minLv, maxLv, ratio } = dicOpp;
|
||
let range = gameData.pvpWar;
|
||
if (range.length <= 0) return false;
|
||
|
||
let index = getRandSingleIndex(range.length);
|
||
let result = range[index];
|
||
if (!result) return false;
|
||
|
||
let robotWarjson = gameData.warJson.get(result.war_id);
|
||
if (!robotWarjson) { /* TODO 判空处理 */ }
|
||
let heroes = new Array<PvpEnemies>();
|
||
let defCe = 0;
|
||
for (let warJson of mapWarJson) {
|
||
if (warJson.relation == 1) continue;
|
||
let h = robotWarjson.find(cur => cur.dataId == warJson.dataId);
|
||
if (h) {
|
||
let dicHero = gameData.hero.get(h.actorId);
|
||
if (!dicHero) continue;
|
||
let heroInfo = new PvpHeroInfo();
|
||
heroInfo.setRobotInfo(h, myLv, dicHero.initialStars, dicHero.quality);
|
||
let { attribute, ce } = getRobotAttribute(h.attribute, myCe, PVP_CONST.ENEMY_CE, ratio);
|
||
defCe += ce;
|
||
heroInfo.setAttribute(attribute);
|
||
let enemy = new PvpEnemies(warJson, heroInfo, 0, ce);
|
||
heroes.push(enemy);
|
||
}
|
||
}
|
||
|
||
let oppRoleId = generateRobotRoleId();
|
||
let roleName = getChineseName();
|
||
let hisPLv = Math.floor(pLv + (minLv + maxLv) / 2);
|
||
if (hisPLv < 1) hisPLv = 1
|
||
|
||
let pvpHistoryOpp = await PvpHistoryOppModel.createPvpOpp({
|
||
roleId, oppRoleId, roleName, pos, defCe, pLv: hisPLv, lv: myLv, heroes, rankLv: 0
|
||
});
|
||
|
||
oppPlayers.push({
|
||
roleId: oppRoleId,
|
||
oppDef: pvpHistoryOpp._id,
|
||
pos,
|
||
isRobot: true
|
||
});
|
||
return true
|
||
}
|
||
|
||
// 生成机器人roleId
|
||
function generateRobotRoleId() {
|
||
return `${genCode(10)}_r`;
|
||
}
|
||
|
||
// 根据roleId判断是不是机器人
|
||
export function checkRoleIsRobot(roleId: string) {
|
||
return !!roleId.match(/_r/);
|
||
}
|
||
|
||
// 将一般的roleId转为带_r的
|
||
export function makeRobotId(roleId: string) {
|
||
return `${roleId}_r`;
|
||
}
|
||
|
||
// 将一般的roleId去掉_r
|
||
export function robotIdComBack(robotRoleId: string) {
|
||
return robotRoleId.replace(/_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, challengeCnt?: number, challengeRefTime?: number, isUpdate?: boolean) {
|
||
let pvpDefense = await PvpDefenseModel.findByRoleId(role.roleId);
|
||
if (!pvpDefense) return;
|
||
let { heroes, isDefaultHero } = pvpDefense;
|
||
if (!isUpdate && !isDefaultHero) {
|
||
return;
|
||
}
|
||
let orders = [1, 2, 3, 4, 5, 6];
|
||
role.topLineup.sort(function (a, b) {
|
||
return b.ce - a.ce;
|
||
});
|
||
heroes.sort(function (a, b) {
|
||
return b.ce - b.dataId - a.ce + a.dataId;
|
||
});
|
||
for (let hero of heroes) {
|
||
if (!!hero.order && !!hero.hero && findIndex(role.topLineup, { hid: hero.actorId }) != -1) {
|
||
let index = orders.indexOf(hero.order);
|
||
orders.splice(index, 1);
|
||
}
|
||
}
|
||
let defCe = 0;
|
||
let num = 0;
|
||
for (let i = 0; i < role.topLineup.length; i++) {
|
||
let item = role.topLineup[i];
|
||
let index = findIndex(heroes, { actorId: item.hid });
|
||
if (index == -1) {
|
||
for (let j = num; j < heroes.length; j++) {
|
||
let hero = heroes[j];
|
||
if (num >= 6) {
|
||
break;
|
||
}
|
||
if (!!findWhere(role.topLineup, { hid: hero.actorId })) {
|
||
continue;
|
||
}
|
||
if (!orders[0]) {
|
||
break;
|
||
}
|
||
hero.actorId = item.hid;
|
||
hero.hero = item.hero;
|
||
hero.ce = item.ce;
|
||
hero.order = orders[0];
|
||
num = j;
|
||
orders.splice(0, 1);
|
||
break;
|
||
}
|
||
} else {
|
||
heroes[index].ce = item.ce;
|
||
heroes[index].hero = item.hero;
|
||
if (!heroes[index].order) {
|
||
heroes[index].order = orders[0];
|
||
orders.splice(0, 1);
|
||
}
|
||
}
|
||
defCe += item.ce;
|
||
}
|
||
if (!!challengeCnt && !!challengeRefTime) {
|
||
let { heroes: resHeroes } = await PvpDefenseModel.updateInfo(role.roleId, { defCe, heroes, challengeCnt, challengeRefTime, isDefaultHero: true });
|
||
return { resHeroes };
|
||
} else {
|
||
let { heroes: resHeroes } = await PvpDefenseModel.updateInfo(role.roleId, { defCe, heroes, isDefaultHero: true });
|
||
return { resHeroes };
|
||
}
|
||
}
|
||
|
||
export function refresh(challengeCnt: number, challengeRefTime: number, seasonEndTime: number) {
|
||
if (challengeCnt >= PVP.PVP_CHALLENGE_COUNTS) {
|
||
return { challengeCnt, challengeRefTime };
|
||
}
|
||
let period = PVP.PVP_CHALLENGE_NORMALTIMES * 60;
|
||
if (getTimeFun(seasonEndTime).checkDay()) {
|
||
period = PVP.PVP_CHALLENGE_FINALTIMES * 60;
|
||
}
|
||
let time = nowSeconds();
|
||
let num = Math.floor((time - challengeRefTime) / period);
|
||
if (num > 0) {
|
||
challengeCnt += num;
|
||
challengeRefTime = challengeRefTime + period * num;
|
||
}
|
||
challengeCnt = challengeCnt > PVP.PVP_CHALLENGE_COUNTS ? PVP.PVP_CHALLENGE_COUNTS : challengeCnt;
|
||
return { challengeCnt, challengeRefTime };
|
||
}
|
||
|
||
export function comsumeChallengeCnt(challengeCnt: number, challengeRefTime: number, seasonEndTime: number) {
|
||
challengeCnt--;
|
||
if (challengeCnt >= PVP.PVP_CHALLENGE_COUNTS) {
|
||
return { challengeCnt, challengeRefTime };
|
||
}
|
||
if (challengeCnt == PVP.PVP_CHALLENGE_COUNTS - 1) {
|
||
challengeRefTime = nowSeconds();
|
||
return { challengeCnt, challengeRefTime };
|
||
}
|
||
return refresh(challengeCnt, challengeRefTime, seasonEndTime);
|
||
}
|
||
|
||
export async function findPvpDefByRoleId(roleId: string) {
|
||
let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId);
|
||
let { warId, seasonNum, seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
|
||
let oldSeasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM);
|
||
let { seasonEndTime: oldSeasonEndTime } = await PVPConfigModel.findPVPConfig(oldSeasonNum);
|
||
if (pvpDefense.seasonNum !== seasonNum && oldSeasonEndTime < nowSeconds()) {
|
||
let newPvpDefense = await setPvpDefResult(pvpDefense, seasonNum, oldSeasonEndTime);
|
||
return { pvpDefense: newPvpDefense, warId };
|
||
}
|
||
let { challengeCnt, challengeRefTime } = refresh(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
|
||
let { refOppCnt, refOppTime, shouldRefOpp } = getRefOppCnt(pvpDefense.refOppCnt, pvpDefense.refOppTime); // 刷新次数
|
||
if (challengeCnt != pvpDefense.challengeCnt || refOppCnt != pvpDefense.refOppCnt) {
|
||
await PvpDefenseModel.updateInfo(roleId, { challengeCnt, challengeRefTime, refOppCnt });
|
||
pvpDefense.challengeCnt = challengeCnt;
|
||
pvpDefense.challengeRefTime = challengeRefTime;
|
||
pvpDefense.refOppCnt = refOppCnt;
|
||
pvpDefense.refOppTime = refOppTime;
|
||
}
|
||
return { pvpDefense, warId, shouldRefOpp };
|
||
}
|
||
|
||
// 获取刷新对手次数及消耗
|
||
export function getRefOppCnt(refOppCnt: number, refOppTime: Date) {
|
||
let curTime = new Date();
|
||
let shouldRefOpp = shouldRefresh(refOppTime, curTime);
|
||
if (shouldRefOpp) {
|
||
refOppCnt = 0; refOppTime = curTime;
|
||
}
|
||
return {
|
||
shouldRefOpp,
|
||
refOppCnt, refOppTime,
|
||
consume: gameData.pvpRefreshConsume.get(refOppCnt + 1)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获得玩家pvp信息,并检查是否在pvp赛季结算中结算过,未结算的进行结算
|
||
* @param roleId
|
||
*/
|
||
export async function findPvpDefAllByRoleId(roleId: string) {
|
||
let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId);
|
||
let { warId, seasonNum, seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
|
||
let oldSeasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM);
|
||
let { seasonEndTime: oldSeasonEndTime } = await PVPConfigModel.findPVPConfig(oldSeasonNum);
|
||
|
||
if (pvpDefense.seasonNum != seasonNum && oldSeasonEndTime < nowSeconds()) {//检查玩家是否在pvp赛季结算中结算过
|
||
let { score, pLv, winStreakNum, heroScores, challengeCnt, challengeRefTime } = await pinus.app.rpc.systimer.systimerRemote.setPvpDefResult.toServer('systimer-server-1', pvpDefense, seasonNum, oldSeasonEndTime);
|
||
pvpDefense.score = score;
|
||
pvpDefense.pLv = pLv;
|
||
pvpDefense.winStreakNum = winStreakNum;
|
||
pvpDefense.heroScores = heroScores;
|
||
pvpDefense.challengeCnt = challengeCnt;
|
||
pvpDefense.challengeRefTime = challengeRefTime;
|
||
}
|
||
pvpDefense.seasonNum = seasonNum;
|
||
let { challengeCnt, challengeRefTime } = refresh(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
|
||
let { refOppCnt, refOppTime, shouldRefOpp } = getRefOppCnt(pvpDefense.refOppCnt, pvpDefense.refOppTime); // 刷新次数
|
||
if (challengeCnt != pvpDefense.challengeCnt || refOppCnt != pvpDefense.refOppCnt || shouldRefOpp) {
|
||
let update: pvpUpdateInter = {
|
||
challengeCnt, challengeRefTime, refOppCnt, refOppTime
|
||
};
|
||
|
||
if (shouldRefOpp) {
|
||
let role = <RoleType>pvpDefense.role;
|
||
let oppPlayers = await refreshEnemies(role, pvpDefense.score, pvpDefense.pLv);
|
||
update.oppPlayers = oppPlayers;
|
||
}
|
||
|
||
let updateResult = await PvpDefenseModel.updateInfoAndInclude(roleId, update);
|
||
pvpDefense.oppPlayers = updateResult.oppPlayers;
|
||
pvpDefense.challengeCnt = challengeCnt;
|
||
pvpDefense.challengeRefTime = challengeRefTime;
|
||
pvpDefense.refOppCnt = refOppCnt;
|
||
pvpDefense.refOppTime = refOppTime;
|
||
}
|
||
|
||
return { pvpDefense, warId, shouldRefOpp, seasonEndTime, oldSeasonEndTime };
|
||
}
|
||
|
||
/**
|
||
* 根据比例计算机器人属性
|
||
* @param attribute 出兵表中的属性字段
|
||
* @param ce 我的战力
|
||
* @param enemyCe 出兵表对手战力
|
||
* @param ratio 系数
|
||
*/
|
||
export function getRobotAttribute(attribute: { id: number, val: number }[], ce: number, enemyCe: number, ratio: number) {
|
||
|
||
let newAttribute = new AttributeCal();
|
||
newAttribute.setByWarJson(attribute, Math.sqrt(ce / enemyCe * ratio));
|
||
let attrArr = newAttribute.getReduceAttributesToString();
|
||
let newCe = newAttribute.calCelAndReduce();
|
||
return { attribute: attrArr, ce: newCe };
|
||
}
|
||
|
||
/**
|
||
* @description 根据玩家数据获取到他的属性
|
||
* @param ceAttr hero表的ceAttr
|
||
* @param globalCeAttr role表中的globalCeAttr
|
||
*/
|
||
export function getPlayerAttribute(heroAttrs: CeAttrData[] = [], roleAttrs: CeAttrDataRole[] = []) {
|
||
let newAttribute = new AttributeCal();
|
||
newAttribute.setByDbData(roleAttrs, heroAttrs);
|
||
let attribute = newAttribute.getReduceAttributesToString();
|
||
let ce = newAttribute.calCelAndReduce();
|
||
return { attribute, ce };
|
||
}
|
||
|
||
/**
|
||
* @description 根据玩家数据获取到他的主属性
|
||
* @param ceAttr
|
||
* @param globalCeAttr
|
||
*/
|
||
export function getPlayerMainAttribute(heroAttrs: CeAttrData[], roleAttrs: CeAttrDataRole[]) {
|
||
let newAttribute = new AttributeCal();
|
||
newAttribute.setByDbData(roleAttrs, heroAttrs);
|
||
let mainAttributes = newAttribute.getReduceMainAttributes();
|
||
return mainAttributes;
|
||
}
|
||
|
||
// 获取我方战报记录
|
||
export async function generMyRecInfo(heroScores: HeroScores[], winStreakNum: number, role: RoleType, isSuccess: boolean, pos: number, myHeroes: pvpEndParamInter[]) {
|
||
|
||
let { roleId, roleName } = role;
|
||
|
||
const dicOpp = gameData.pvpOpponent.get(pos);
|
||
const plusScore = getPlusScore(winStreakNum);
|
||
let pLv = getLvByScore(heroScores);
|
||
|
||
let myHeroRecords = new Array<HeroesRecord>();
|
||
let showHeroScores = new Array<{ hid: number, addScore: number, plusScore: number, score: number }>();
|
||
let addSumScore = 0;
|
||
for (let { hid, damage, heal, underDamage } of myHeroes) {
|
||
let curHeroScore = heroScores.find(cur => cur.hid == hid);
|
||
if (isSuccess) {
|
||
if (!curHeroScore) {
|
||
curHeroScore = {
|
||
hid, score: dicOpp.score + plusScore
|
||
};
|
||
heroScores.push(curHeroScore);
|
||
} else {
|
||
curHeroScore.score += dicOpp.score + plusScore;
|
||
}
|
||
addSumScore += dicOpp.score + plusScore;
|
||
showHeroScores.push({
|
||
hid, addScore: dicOpp.score, plusScore, score: curHeroScore.score
|
||
});
|
||
} else {
|
||
showHeroScores.push({
|
||
hid, addScore: 0, plusScore: 0, score: curHeroScore ? curHeroScore.score : 0
|
||
});
|
||
}
|
||
const myHero = await HeroModel.findByHidAndRole(hid, roleId, 'quality star colorStar lv');
|
||
let { quality, star, colorStar, lv } = myHero;
|
||
|
||
myHeroRecords.push({
|
||
hid, quality, star, colorStar, lv, damage, heal, underDamage
|
||
});
|
||
}
|
||
|
||
let attackInfo = {
|
||
roleId,
|
||
roleName,
|
||
lv: pLv,
|
||
head: role.head,
|
||
frame: role.frame,
|
||
spine: role.spine,
|
||
title: role.title,
|
||
ce: role.topLineupCe,
|
||
heroes: myHeroRecords,
|
||
isSuccess,
|
||
score: isSuccess ? addSumScore : 0
|
||
}
|
||
|
||
return { attackInfo, showHeroScores, addSumScore }
|
||
}
|
||
|
||
// 获取对手战报记录
|
||
export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayers, oppHeroes: pvpEndParamInter[], myLv: number) {
|
||
let oppHeroRecords = new Array<HeroesRecord>();
|
||
let oppRole = <PvpHistoryOppType>curOpp.oppDef;
|
||
if (!oppRole) { console.error('opp role not found') }
|
||
for (let { hid, damage, heal, underDamage } of oppHeroes) {
|
||
let historyHero = oppRole.heroes.find(cur => cur.actorId == hid);
|
||
if (historyHero) {
|
||
let hs = new HeroesRecord(historyHero, damage, heal, underDamage);
|
||
oppHeroRecords.push(hs);
|
||
}
|
||
}
|
||
return {
|
||
roleId: robotIdComBack(oppRole.oppRoleId),
|
||
roleName: oppRole.roleName,
|
||
lv: oppRole.pLv,
|
||
head: oppRole.head,
|
||
frame: oppRole.frame,
|
||
spine: oppRole.spine,
|
||
title: oppRole.title,
|
||
ce: oppRole.defCe,
|
||
heroes: oppHeroRecords,
|
||
isSuccess: !isSuccess,
|
||
score: 0
|
||
}
|
||
}
|