pvp:修改接口

This commit is contained in:
luying
2021-10-26 19:10:25 +08:00
parent e39b120af4
commit 7fb13da627
10 changed files with 359 additions and 214 deletions

View File

@@ -2,28 +2,29 @@
import { Application, BackendSession, pinus, HandlerService, } from 'pinus';
import { uniq, findWhere, findIndex } from 'underscore';
import { gameData, getPvpBoxs, getPLvByScore } from '../../../pubUtils/data';
import { refreshEnemies, getEnemies, getLvByScore, comsumeChallengeCnt, refChallengeCnt, generPVPOppRecInfo, generMyRecInfo, sendLastSeasonRewardIfNotSent, refreshRefOppCnt } from '../../../services/pvpService';
import { refreshEnemies, getEnemies, getLvByScore, comsumeChallengeCnt, refChallengeCnt, generPVPOppRecInfo, generMyRecInfo, sendLastSeasonRewardIfNotSent, refreshRefOppCnt, generPvpLineupCe } from '../../../services/pvpService';
import { RoleModel, RoleType } from '../../../db/Role';
import { STATUS } from '../../../consts/statusCode';
import { resResult, genCode, checkRoleIsRobot, robotIdComBack } from '../../../pubUtils/util';
import { PvpDefenseModel, pvpUpdateInter } from '../../../db/PvpDefense';
import { pvpEndParamInter } from '../../../pubUtils/interface';
import { PlayerDetail, PlayerDetailHero } from '../../../domain/battleField/guild';
import { PVP_HERO_POS, PVP_HERO_ORDER, REDIS_KEY, LINEUP_NUM, TASK_TYPE, COUNTER } from '../../../consts';
import { PVP } from '../../../pubUtils/dicParam';
import { addItems } from '../../../services/rewardService';
import { HeroModel } from '../../../db/Hero';
import { checkBattleHeroesByHid } from '../../../services/normalBattleService';
import { BattleRecordModel } from '../../../db/BattleRecord';
import { PvpRecordModel } from '../../../db/PvpRecord';
import { handleCost } from '../../../services/rewardService';
import { nowSeconds, getSeconds } from '../../../pubUtils/timeUtil';
import { PvpSeasonResultModel } from '../../../db/PvpSeasonResult';
import { PvpHistoryOppModel, PvpHistoryOppType } from '../../../db/PvpHistoryOpp';
import { PVPConfigModel } from '../../../db/SystemConfig';
import { Rank } from '../../../services/rankService';
import { checkActivityTask, checkTask, checkTaskInPvpEnd } from '../../../services/taskService';
import { PvpDataReturn } from '../../../domain/battleField/pvp';
import { Attack, AttackHero, Defense, DefenseHero, PvpDataReturn } from '../../../domain/battleField/pvp';
import { LINEUP_NUM, REDIS_KEY, TASK_TYPE } from '../../../consts';
import { PVP } from '../../../pubUtils/dicParam';
import { getGoldObject } from '../../../pubUtils/itemUtils';
import { addItems, handleCost } from '../../../services/rewardService';
import { pick } from "underscore";
import { HeroModel } from '../../../db/Hero';
import PvpHistoryOpp, { PvpHistoryOppModel } from '../../../db/PvpHistoryOpp';
import { checkBattleHeroesByHid } from '../../../services/normalBattleService';
import { BattleRecordModel } from '../../../db/BattleRecord';
import { PvpRecordModel } from '../../../db/PvpRecord';
import { pvpEndParamInter } from '../../../pubUtils/interface';
import { getSeconds, nowSeconds } from '../../../pubUtils/timeUtil';
import { PlayerDetail, PlayerDetailHero } from '../../../domain/battleField/guild';
export default function (app: Application) {
new HandlerService(app, {});
@@ -43,83 +44,90 @@ export class PvpHandler {
let role = await RoleModel.findByRoleId(roleId);
pvpDefense = await PvpDefenseModel.createPvpDefense({ roleId: role.roleId, roleName: role.roleName, role: role._id });
}
// 如果没有发过,将上赛季的奖励发下
pvpDefense = await sendLastSeasonRewardIfNotSent(pvpDefense);
let { seasonNum, seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
let update: pvpUpdateInter = { };
let result = new PvpDataReturn(); // 返回对象
// 刷新次数
let refChallengeObj = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
let refOppObj = refreshRefOppCnt(pvpDefense.refOppCnt, pvpDefense.refDaily);
let update: pvpUpdateInter = { ...refChallengeObj, ...refOppObj};
let result = new PvpDataReturn(pvpDefense); // 返回对象
if(refChallengeObj.hasChanged) {
update = { ...update, ...refChallengeObj }
}
let refOppObj = refreshRefOppCnt(pvpDefense.refOppCnt, pvpDefense.setAttackCnt, pvpDefense.refDaily);
// 每天首次打开要刷掉对手
if(refOppObj.shouldRefOpp) {
let role = <RoleType>pvpDefense.role;
let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack.pLv);
update.oppPlayers = oppPlayers;
let oppPlayersReturn = await getEnemies(oppPlayers||[], pvpDefense.winStreakNum);
result.setOppPlayers(oppPlayersReturn);
} else {
let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers||[], pvpDefense.winStreakNum);
result.setOppPlayers(oppPlayersReturn);
if(pvpDefense.attack) {
let role = <RoleType>pvpDefense.role;
let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack.pLv||1);
update.oppPlayers = oppPlayers;
}
update = { ...update, ...refOppObj }
}
let { score, winStreakNum, refOppCnt, challengeCnt, challengeRefTime, receivedBox, hisScore, heroScores, isFirstEntry } = pvpDefense;
if (pvpDefense.isFirstEntry) {
update.isFirstEntry = false;
result.setIsFirstEntry(true);
}
if(Object.keys(update).length > 0) {
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, update);
}
let pvpSeasonResult = await PvpSeasonResultModel.getPvpSeasonResult(roleId, pvpDefense.seasonNum);
result.setPvpConfig(seasonNum, seasonEndTime);
result.setPvpDefense(pvpDefense);
let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers||[], pvpDefense.winStreakNum);
result.setOppPlayers(oppPlayersReturn);
// 赛季结算
let pvpSeasonResult = await PvpSeasonResultModel.getPvpSeasonResult(roleId, pvpDefense.seasonNum);
if (!!pvpSeasonResult && !!pvpSeasonResult.show) {
result.setPvpSeasonResult(pvpSeasonResult);
await PvpSeasonResultModel.updatePvpSeasonResult(roleId, pvpSeasonResult.seasonNum, { show: false });
}
// 拍卖
let r = new Rank(REDIS_KEY.PVP_RANK, {});
let myRank = await r.getMyRank({ roleId });//去redis中获取排名
result.setMyRank(myRank);
// let data: any = {
// warId, seasonNum, seasonEndTime, myRank, oppPlayers, heroes: heroes.map(cur => {
// let { actorId, dataId, order } = cur;
// return { actorId, dataId, order }
// }), score, pLv, winStreakNum, refOppCnt, challengeCnt, challengeRefTime, receivedBox, hisScore, heroScores, isFirstEntry, isDefaultHero
// }
return resResult(STATUS.SUCCESS, result);
}
/*
// 刷新对手
async refreshOppPlayer(msg: {}, session: BackendSession) {
let roleId = session.get('roleId');
let sid = session.get('sid');
let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId);
if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN);
if(!pvpDefense.attack) return resResult(STATUS.PVP_NOT_SET_ATTACK);
// 刷新次数及消耗
let { refOppCnt, refOppTime, consume } = getRefOppCnt(pvpDefense.refOppCnt, pvpDefense.refOppTime);
if (refOppCnt >= gameData.maxPvpRefreshCnt.max) {
let refOppObj = refreshRefOppCnt(pvpDefense.refOppCnt, pvpDefense.setAttackCnt, pvpDefense.refDaily);
if (refOppObj.refOppCnt >= gameData.maxPvpRefreshCnt.max) {
return resResult(STATUS.PVP_REFRESH_CNT_REACH_MAX);
}
let costResult = await handleCost(roleId, sid, consume);
let costResult = await handleCost(roleId, sid, refOppObj.consume);
if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
refOppObj.refOppCnt ++;
// 刷新对手
let role = <RoleType>pvpDefense.role;
let oppPlayers = await refreshEnemies(role, pvpDefense.score, pvpDefense.pLv);
let { seasonNum } = await PVPConfigModel.findCurPVPConfig();
let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack.pLv||1);
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { oppPlayers, refOppCnt: refOppCnt + 1, refOppTime });
let result = await getEnemies(pvpDefense.oppPlayers, pvpDefense.winStreakNum);
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { oppPlayers, ...refOppObj });
let result = new PvpDataReturn(); // 返回对象
result.setPvpDefense(pvpDefense);
let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers, pvpDefense.winStreakNum);
result.setOppPlayers(oppPlayersReturn);
return resResult(STATUS.SUCCESS, { oppPlayers: result, refOppCnt: pvpDefense.refOppCnt });
return resResult(STATUS.SUCCESS, pick(result, ['oppPlayers', 'refOppCnt', 'setAttackCnt']));
}
// 获取对手阵容具体信息
async getOppPlayer(msg: { roleId: string }, session: BackendSession) {
let roleId = session.get('roleId');
@@ -131,14 +139,15 @@ export class PvpHandler {
let curOpp = oppPlayers.find(cur => cur.roleId == oppoRoleId);
if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND);
let { oppRoleId, heroes } = <PvpHistoryOppType>curOpp.oppDef;
let pvpHistoryOpp = <PvpHistoryOpp>curOpp.oppDef;
return resResult(STATUS.SUCCESS, { roleId: oppRoleId, pos: curOpp.pos, heroes });
return resResult(STATUS.SUCCESS, { roleId: pvpHistoryOpp.oppRoleId, ...pick(pvpHistoryOpp, ['pos', 'warId', 'buff', 'heroes']) });
}
// 开战
async pvpStart(msg: { warId: number, heroes: number[], roleId: string }, session: BackendSession) {
const { warId, heroes, roleId: oppRoleId } = msg;
async pvpStart(msg: { warId: number, roleId: string }, session: BackendSession) {
const { warId, roleId: oppRoleId } = msg;
let roleId = session.get('roleId');
let roleName = session.get('roleName');
@@ -147,10 +156,7 @@ export class PvpHandler {
return resResult(STATUS.BATTLE_MISS_INFO);
}
let { isOK } = await checkBattleHeroesByHid(roleId, heroes);
if (!isOK) return resResult(STATUS.BATTLE_HERO_NOT_FOUND);
const pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
let pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
if (!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN);
// 检查挑战次数
let { seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
@@ -164,6 +170,7 @@ export class PvpHandler {
if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND)
const battleCode = genCode(8); // 关卡唯一值
let heroes = pvpDefense.attack.heroes.map(cur => cur.actorId);
await BattleRecordModel.updateBattleRecordByCode(battleCode, {
$set: {
@@ -205,26 +212,28 @@ export class PvpHandler {
if (!flag) return resResult(STATUS.BATTLE_INFO_VALIDATE_ERR);
// 更新军功
let { pvpDefense, warId } = await findPvpDefByRoleId(roleId);
let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId);
if (!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN);
let { oppPlayers, winStreakNum, heroScores, score, hisScore } = pvpDefense;
let curOpp = oppPlayers.find(cur => cur.roleId == oppRoleId && cur.pos == pos);
if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND);
let update: pvpUpdateInter = {};
const role = await RoleModel.findByRoleId(roleId, null, true);
if (isSuccess) {
winStreakNum++;
update.winStreakNum = pvpDefense.winStreakNum + 1;
} else {
winStreakNum = 0;
update.winStreakNum = 0;
}
const myRecInfo = await generMyRecInfo(heroScores, winStreakNum, role, isSuccess, pos, myHeroes);
let { attackInfo, showHeroScores, addSumScore } = myRecInfo
score += addSumScore;
let pLv = getLvByScore(heroScores);
const myRecInfo = await generMyRecInfo(pvpDefense.heroScores, pvpDefense.winStreakNum, role, isSuccess, pos, myHeroes);
let { attackInfo, showHeroScores, addSumScore, newHeroScore } = myRecInfo
update.heroScores = newHeroScore;
update.score = pvpDefense.score + addSumScore;
if (pvpDefense.hisScore < update.score) {
update.hisScore = update.score;
}
let curOpp = pvpDefense.oppPlayers.find(cur => cur.roleId == oppRoleId && cur.pos == pos);
if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND);
const defenseInfo = await generPVPOppRecInfo(isSuccess, curOpp, oppHeroes, role.lv);
// 战报记录
@@ -234,130 +243,150 @@ export class PvpHandler {
await PvpHistoryOppModel.setStatus(roleId, oppRoleId, 1);
// 刷新对手
let newOppPlayers: Array<OppPlayers> = await refreshEnemies(role, score, pLv);
let { seasonNum, seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack.pLv||1);
update.oppPlayers = oppPlayers;
// 更新battleRecord
await BattleRecordModel.updateBattleRecordByCode(battleCode, {
$set: { status: isSuccess ? 1 : 2 }
}, true);
let { seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
// 减少挑战次数
if (hisScore < score) {
hisScore = score;
}
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { oppPlayers: newOppPlayers, heroScores, score, pLv, winStreakNum, challengeCnt: pvpDefense.challengeCnt - 1, hisScore });
let result = await getEnemies(pvpDefense.oppPlayers, pvpDefense.winStreakNum);
let refChallengeObj = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
refChallengeObj.challengeCnt --;
update = {...update, ...refChallengeObj};
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, update);
let result = new PvpDataReturn(); // 返回对象
result.setPvpDefense(pvpDefense);
let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers, pvpDefense.winStreakNum);
result.setOppPlayers(oppPlayersReturn);
// 加入排行榜
let r = new Rank(REDIS_KEY.PVP_RANK, {});
await r.setRankWithRoleInfo(roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), role);
let myRank = await r.getMyRank({ roleId });
result.setMyRank(myRank);
await checkTaskInPvpEnd(roleId, sid, isSuccess, heroScores);
await checkTaskInPvpEnd(roleId, sid, isSuccess, pvpDefense.heroScores);
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.PVP, 1)
if (isSuccess) {
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.PVP_WIN, 1)
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.PVP_WIN_SERIES, 1)
}
return resResult(STATUS.SUCCESS, {
battleCode, isSuccess,
score, pLv, myRank, hisScore,
heroScores: showHeroScores,
oppPlayers: result,
refOppCnt: pvpDefense.refOppCnt,
challengeCnt: pvpDefense.challengeCnt,
challengeRefTime: pvpDefense.challengeRefTime,
winStreakNum: pvpDefense.winStreakNum,
warId
...pick(result, ['score', 'myRank', 'winStreakNum', 'attack', 'oppPlayers', 'challengeCnt', 'challengeRefTime'])
});
}
async saveAttack(msg: { heroes: { actorId: number, order: number }[] }, session: BackendSession) {
let { heroes } = msg;
let roleId = session.get('roleId');
let sid = session.get('sid');
if (heroes.length > LINEUP_NUM || heroes.length <= 0) {
return resResult(STATUS.WRONG_PARMS);
}
let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId);
if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN);
// 次数
let refOppObj = refreshRefOppCnt(pvpDefense.refOppCnt, pvpDefense.setAttackCnt, pvpDefense.refDaily);
if(refOppObj.setAttackCnt >= PVP.PVP_SET_ATTACK_CNT) {
return resResult(STATUS.PVP_SET_ATTACK_CNT_NOT_ENOUGH);
}
if(refOppObj.setAttackCnt >= PVP.PVP_SET_ATTACK_FREE_CNT) {
let gold = getGoldObject(PVP.PVP_SET_ATTACK_CNT_GOLD);
let result = await handleCost(roleId, sid, [gold]);
if(!result) return resResult(STATUS.TOWER_GOLD_NOT_ENOUGH);
}
refOppObj.setAttackCnt ++;
let { seasonNum, seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
let refChallengeObj = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
// 刷对手
let role = <RoleType>pvpDefense.role;
let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack?.pLv||1);
// 更新挑战阵容
let score = 0;
for(let { actorId } of heroes) {
let heroScore = pvpDefense.heroScores.find(cur => cur.hid == actorId);
if(heroScore) {
score += heroScore.score;
}
}
let attack = new Attack(heroes, score);
let lineupCe = await generPvpLineupCe(roleId, pvpDefense.lineupCe, attack.heroes, []);
// 保存
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { ...refOppObj, ...refChallengeObj, attack, oppPlayers, lineupCe });
// 返回
let result = new PvpDataReturn();
result.setPvpDefense(pvpDefense);
let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers||[], pvpDefense.winStreakNum);
result.setOppPlayers(oppPlayersReturn);
return resResult(STATUS.SUCCESS, pick(result, ['attack', 'oppPlayers', 'setAttackCnt', 'challengeCnt', 'challengeRefTime']));
}
//3. 保存防守阵容
async saveDefense(msg: { heroes: Array<{ actorId: number, dataId: number, order: number }>, isDefaultHero: boolean }, session: BackendSession) {
let { heroes, isDefaultHero } = msg;
async saveDefense(msg: { heroes: { actorId: number, dataId: number, order: number, ai: number }[], warId: number, buff: number }, session: BackendSession) {
let { heroes, warId, buff } = msg;
let roleId = session.get('roleId');
if (heroes.length > LINEUP_NUM || heroes.length <= 0) {
return resResult(STATUS.WRONG_PARMS);
}
heroes = uniq(heroes, function (item) {
return item.order;
});
let pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN);
// 刷新次数
let { seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
let { heroes: defHeros, challengeCnt: lastChallengeCnt, challengeRefTime: lastChallengeRefTime } = await PvpDefenseModel.findByRoleId(roleId);
let defCe = 0;
let { challengeCnt, challengeRefTime } = refChallengeCnt(lastChallengeCnt, lastChallengeRefTime, seasonEndTime);
if (!!isDefaultHero) {
let { topLineup } = await RoleModel.findByRoleId(roleId);
let hids = topLineup.filter(cur => {
return !heroes.find(ccur => ccur.actorId == cur.hid);
}).map(cur => cur.hid);
let dataIds = new Array<number>(), orders = new Array<number>();
for (let hero of heroes) {
if (hero.actorId) {
let isInTop = topLineup.find(cur => cur.hid == hero.actorId);
if (!isInTop) {
hero.actorId = hids.shift();
}
dataIds.push(hero.dataId);
orders.push(hero.order);
}
let refChallengeObj = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
// 更新防守阵容
let score = 0, heroIdMap = new Map<number, string>(), hids: number[] = [];
for(let { actorId } of heroes) {
let heroScore = pvpDefense.heroScores.find(cur => cur.hid == actorId);
if(heroScore) {
score += heroScore.score;
}
for (let hid of hids) {
let dataId = 0;
for (let i = PVP_HERO_POS.START; i <= PVP_HERO_POS.END; i++) {
if (dataIds.includes(i)) continue;
dataIds.push(i);
dataId = i; break;
// 记录hero的objectId用于存defense.heroes.hero
if(pvpDefense.defense && pvpDefense.defense.heroes) {
let heroInDefense = pvpDefense.defense.heroes.find(cur => cur.actorId == actorId);
if(heroInDefense) {
heroIdMap.set(actorId, <string>heroInDefense.hero);
} else {
hids.push(actorId);
}
let order = 0;
for (let i = PVP_HERO_ORDER.START; i <= PVP_HERO_ORDER.END; i++) {
if (orders.includes(i)) continue;
orders.push(i);
order = i; break;
}
heroes.push({
actorId: hid, dataId, order
})
} else {
hids.push(actorId);
}
}
for (let dataId = PVP_HERO_POS.START; dataId <= PVP_HERO_POS.END; dataId++) {
let index = findIndex(heroes, { dataId });
let defIndex = findIndex(defHeros, { dataId });
if (defIndex == -1) {
defIndex = defHeros.length;
defHeros.push({ actorId: 0, order: 0, ce: 0, hero: null, dataId });
}
if (index == -1) {
defHeros[defIndex].actorId = 0;
defHeros[defIndex].order = 0;
defHeros[defIndex].ce = 0;
defHeros[defIndex].hero = null;
defHeros[defIndex].dataId = dataId;
continue;
}
if (heroes[index].order < 1 || heroes[index].order > LINEUP_NUM) {
return resResult(STATUS.WRONG_PARMS);
}
let hero = await HeroModel.findByHidAndRole(heroes[index].actorId, roleId);
if (!hero) {
continue;
}
defHeros[defIndex].actorId = heroes[index].actorId;
defHeros[defIndex].order = heroes[index].order;
defHeros[defIndex].ce = hero.ce;
defHeros[defIndex].hero = hero._id;
defCe += hero.ce;
let dbHeroes = await HeroModel.findByHidRange(hids, roleId, '_id hid ce', true);
for(let hero of dbHeroes) {
heroIdMap.set(hero.hid, hero._id);
}
let { heroes: resHeroes } = await PvpDefenseModel.updateInfo(roleId, { defCe, heroes: defHeros, challengeCnt, challengeRefTime, isDefaultHero });
return resResult(STATUS.SUCCESS, { heroes: resHeroes, challengeCnt, challengeRefTime, isDefaultHero });
let defenseHeroes = heroes.map(cur => {
return new DefenseHero(cur, heroIdMap.get(cur.actorId));
});
let defense = new Defense(defenseHeroes, score, warId, buff);
let lineupCe = await generPvpLineupCe(roleId, pvpDefense.lineupCe, defense.heroes, dbHeroes);
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { ...refChallengeObj, defense, lineupCe });
// 返回
let result = new PvpDataReturn();
result.setPvpDefense(pvpDefense);
return resResult(STATUS.SUCCESS, pick(result, ['defense', 'challengeCnt', 'challengeRefTime']));
}
//8. 排行榜
async getRank(msg: {}, session: BackendSession) {
@@ -369,7 +398,7 @@ export class PvpHandler {
if (!myRank) {
let pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
myRank = await r.generMyRankWithRole(roleId, pvpDefense.score, getSeconds(pvpDefense.refOppTime));
myRank = await r.generMyRankWithRole(roleId, pvpDefense.score, getSeconds(pvpDefense.refDaily));
}
return resResult(STATUS.SUCCESS, { ranks, myRank });
@@ -487,9 +516,7 @@ export class PvpHandler {
if (hisScore < score) {
hisScore = score;
}
let pLv = getPLvByScore(score);
let pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { score, hisScore, pLv, heroScores });
let roleName = session.get('roleName');
let pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { score, hisScore, heroScores });
const role = await RoleModel.findByRoleId(roleId);
// 加入排行榜
@@ -501,7 +528,7 @@ export class PvpHandler {
return resResult(STATUS.SUCCESS, { score, hisScore, heroScores });
}
/*
async debugPvpSeasonReset(msg: {}, session: BackendSession) {
await pvpSeasonEnd({ name: 'exce setPvpSeasonResult debug' });
let systemConfig = await createNextPvpSeason();
@@ -519,6 +546,7 @@ export class PvpHandler {
return resResult(STATUS.SUCCESS, { seasonNum, seasonEndTime });
}
*/
async debugAddChallengeCnt(msg: { challengeCnt: number }, session: BackendSession) {
let { challengeCnt } = msg;
let roleId = session.get('roleId');
@@ -529,5 +557,4 @@ export class PvpHandler {
return resResult(STATUS.SUCCESS, { challengeCnt, challengeRefTime });
}
*/
}

View File

@@ -1,6 +1,6 @@
import { PvpDefenseModel, PvpDefenseType, pvpUpdateInter } from '../db/PvpDefense';
import { Defense, Attack, LineupCe, OppPlayer, HeroScore, HeroReward, OppPlayerReturn } from '../domain/battleField/pvp';
import { Defense, Attack, LineupCe, OppPlayer, HeroScore, HeroReward, OppPlayerReturn, AttackHero, DefenseHero } from '../domain/battleField/pvp';
import { RoleType, CeAttrDataRole } from '../db/Role';
import { PVP_HERO_POS, REDIS_KEY, PVP_CONST, COUNTER, TASK_TYPE, MAIL_TYPE } from '../consts';
import { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent";
@@ -11,7 +11,7 @@ import { PVP } from '../pubUtils/dicParam';
import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig'
import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil';
import { HeroesRecord } from '../db/PvpRecord';
import { HeroModel, CeAttrData } from '../db/Hero';
import { HeroModel, CeAttrData, HeroType } from '../db/Hero';
import { AttributeCal } from '../domain/roleField/attribute';
import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from '../domain/dbGeneral';
import { DicWarJson } from '../pubUtils/dictionary/DicWarJson';
@@ -37,6 +37,8 @@ export async function getEnemies(oppPlayers: OppPlayer[], winStreakNum: number)
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'
console.log('*******', oppDef)
if (oppDef) delete oppDef.heroes;
result.push({
...oppDef,
@@ -239,10 +241,10 @@ async function matchRobot(oppPlayers: OppPlayer[], role: RoleType, pLv: number,
let dicHero = gameData.hero.get(actorId);
if (!dicHero) continue;
let heroInfo = new PvpHeroInfo();
heroInfo.setRobotInfo(h, actorId, myLv, dicHero.initialStars, dicHero.quality);
heroInfo.setRobotInfo(actorId, myLv);
let { attribute, ce } = getRobotAttribute(h.attribute, h.enemyCount, [], pLv, myCe, PVP_CONST.ENEMY_CE, ratio);
defCe += ce;
heroInfo.setAttribute(attribute);
heroInfo.setAttribute("1&3500|2&500|4&400|5&400|9&0|10&0|11&0|12&0|13&0|14&10000|18&0");
let enemy = new PvpEnemies(h, heroInfo, 0, ce);
heroes.push(enemy);
}
@@ -253,7 +255,7 @@ async function matchRobot(oppPlayers: OppPlayer[], role: RoleType, pLv: number,
if (hisPLv < 1) hisPLv = 1
let pvpHistoryOpp = await PvpHistoryOppModel.createPvpOpp({
roleId, oppRoleId, roleName, pos, defCe, pLv: hisPLv, lv: myLv, heroes, rankLv: 0
roleId, oppRoleId, roleName, pos, defCe, pLv: hisPLv, lv: myLv, heroes, rankLv: 0, warId: result.war_id, buff: getRandSingleEelm(result.mapseid)||0,
});
oppPlayers.push({
@@ -289,8 +291,9 @@ export function getLvByScore(heroScores: HeroScore[]) {
}
export function refChallengeCnt(challengeCnt: number, challengeRefTime: number, seasonEndTime: number) {
let hasChanged = false;
if (challengeCnt >= PVP.PVP_CHALLENGE_COUNTS) {
return { challengeCnt, challengeRefTime };
return { hasChanged, challengeCnt, challengeRefTime };
}
let period = PVP.PVP_CHALLENGE_NORMALTIMES * 60;
if (getTimeFun(seasonEndTime).checkDay()) {
@@ -301,9 +304,10 @@ export function refChallengeCnt(challengeCnt: number, challengeRefTime: number,
if (num > 0) {
challengeCnt += num;
challengeRefTime = challengeRefTime + period * num;
hasChanged = true;
}
challengeCnt = challengeCnt > PVP.PVP_CHALLENGE_COUNTS ? PVP.PVP_CHALLENGE_COUNTS : challengeCnt;
return { challengeCnt, challengeRefTime };
return { hasChanged, challengeCnt, challengeRefTime };
}
export function comsumeChallengeCnt(challengeCnt: number, challengeRefTime: number, seasonEndTime: number) {
@@ -328,15 +332,15 @@ export async function sendLastSeasonRewardIfNotSent(pvpDefense: PvpDefenseType)
}
// 获取刷新对手次数及消耗
export function refreshRefOppCnt(refOppCnt: number, refDaily: Date) {
export function refreshRefOppCnt(refOppCnt: number, setAttackCnt: number, refDaily: Date) {
let curTime = new Date();
let shouldRefOpp = shouldRefresh(refDaily, curTime);
if (shouldRefOpp) {
refOppCnt = 0; refDaily = curTime;
refOppCnt = 0; setAttackCnt = 0; refDaily = curTime;
}
return {
shouldRefOpp,
refOppCnt, refDaily,
refOppCnt, refDaily, setAttackCnt,
consume: gameData.pvpRefreshConsume.get(refOppCnt + 1)
}
}
@@ -405,6 +409,7 @@ export async function generMyRecInfo(heroScores: HeroScore[], winStreakNum: numb
const plusScore = getPlusScore(winStreakNum);
let pLv = getLvByScore(heroScores);
// TODO 这里heroScore可以改为不改变原数据而创建新数据的方式
let myHeroRecords = new Array<HeroesRecord>();
let showHeroScores = new Array<{ hid: number, addScore: number, plusScore: number, score: number }>();
let addSumScore = 0;
@@ -450,7 +455,7 @@ export async function generMyRecInfo(heroScores: HeroScore[], winStreakNum: numb
score: isSuccess ? addSumScore : 0
}
return { attackInfo, showHeroScores, addSumScore }
return { attackInfo, showHeroScores, addSumScore, newHeroScore: heroScores }
}
// 获取对手战报记录
@@ -571,10 +576,28 @@ export async function savePvpSeasonResult(pvpDefense: PvpDefenseType, seasonNum:
return pvpSeasonResult;
}
function getScore(arr, score) {
for (let item of arr) {
if ((item.max >= score || item.max == -1) && score >= item.min) {
return item;
export async function generPvpLineupCe(roleId: string, lineupCe: LineupCe[], newHeroes: AttackHero[]|DefenseHero[], dbHeroes: HeroType[]) {
let newHids: number[] = []; // 本次新增武将
let newLineupCe: { hid: number, ce: number }[] = []; // 新生成的lineupCe字段
for(let { actorId } of newHeroes) {
let n = newLineupCe.find(cur => cur.hid == actorId);
if(!n) {
let lineup = lineupCe.find(cur => cur.hid == actorId);
if(lineup) {
newLineupCe.push(lineup);
} else {
let dbHero = dbHeroes.find(cur => cur.hid == actorId);
if(dbHero) {
newLineupCe.push({ hid: actorId, ce: dbHero.ce });
} else {
newHids.push(actorId);
}
}
}
}
let heroes = await HeroModel.findByHidRange(newHids, roleId, 'hid ce', true);
for(let { hid, ce } of heroes) {
newLineupCe.push({ hid, ce });
}
return newLineupCe;
}

View File

@@ -930,17 +930,18 @@ export async function setRankRedisFromDb(type: string, args?: { serverId?: numbe
await r.setRankWithGuildInfoArrParam(guild.code, [guild.lv, guild.activeWeekly, guild.activeUpdateTime], guild);
}
} else if (type == REDIS_KEY.PVP_RANK) {
let { seasonNum } = await PVPConfigModel.findCurPVPConfig();
console.log('execute season resetPvpRanks seasonNum = ' + seasonNum);
let ranks = await PvpDefenseModel.getRank(seasonNum);//获得全服前1000名的排名加入到redis中
let r = new Rank(type, {});
r.setIsInit(true);
for (let { roleId, role: _role, score, updatedAt } of ranks) {
let role = <RoleType>_role;
if (!role) {
continue;
let pvpConfig = await PVPConfigModel.findCurPVPConfig();
if(pvpConfig) {
let ranks = await PvpDefenseModel.getRank(pvpConfig.seasonNum);//获得全服前1000名的排名加入到redis中
let r = new Rank(type, {});
r.setIsInit(true);
for (let { roleId, role: _role, score, updatedAt } of ranks) {
let role = <RoleType>_role;
if (!role) {
continue;
}
await r.setRankWithRoleInfo(roleId, score, updatedAt.getTime(), role);
}
await r.setRankWithRoleInfo(roleId, score, updatedAt.getTime(), role);
}
} else if (type == REDIS_KEY.TOP_LINEUP_RANK) {
let serverId = args.serverId;

View File

@@ -1,7 +1,7 @@
import { scheduleJob, Job, } from 'node-schedule';
import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig';
import { nowSeconds, getTimeFun, getZeroPoint } from '../pubUtils/timeUtil';
import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil';
import { getTodayGuildActivity, gameData } from '../pubUtils/data';
import { pvpSeasonEnd } from './pvpService';
import { getAllOnlineRoles, getAllServers, delGuildActivityRank } from './redisService';
@@ -83,7 +83,7 @@ function getSeasonContinueDay(seasonNum: number) {
async function setPvpSeason() {
let pvpConfig = await PVPConfigModel.findCurPVPConfig();
if(!pvpConfig || pvpConfig.seasonEndTime <= nowSeconds() ) {
if(!pvpConfig.hasSettleReward) {
if(pvpConfig && !pvpConfig.hasSettleReward) {
await pvpSeasonEnd(pvpConfig);
}
@@ -94,9 +94,10 @@ async function setPvpSeason() {
let during = getSeasonContinueDay(lastSeasonNum + 1) * PER_DAY;
let rewardTime = SETTLE_DIFF_SECONDS;
if(nowSeconds() - lastSeasonEndTime > during) {
newSeasonStartTime = getZeroPoint();
newSeasonStartTime = <number>getTimeFun().getDayZeroPoint(0);
}
pvpConfig = await PVPConfigModel.createPVPConfig(lastSeasonNum + 1, newSeasonStartTime, newSeasonStartTime + during - rewardTime, newSeasonStartTime + during - PER_MINUTE);
let newSeasonNum = await CounterModel.getNewCounter(COUNTER.PVP_SEASON_NUM);
pvpConfig = await PVPConfigModel.createPVPConfig(newSeasonNum, newSeasonStartTime, newSeasonStartTime + during - rewardTime, newSeasonStartTime + during - PER_MINUTE);
}
await setPvpSeasonMakeRewardJob(pvpConfig);
await setNextSeasonJob(pvpConfig);
@@ -128,7 +129,7 @@ async function setNextSeasonJob(pvpConfig: PVPConfigType) {
* @param hour
*/
export async function resetPvpSeasonTime(hour: number) {
await PVPConfigModel.setCurPvpConfig({ seasonEndTime: getZeroPoint() });
await PVPConfigModel.setCurPvpConfig({ seasonEndTime: <number>getTimeFun().getDayZeroPoint(0) });
return await setPvpSeason();
}

View File

@@ -141,6 +141,8 @@ export const STATUS = {
PVP_NOT_REACH_BOX_SCORE: { code: 20803, simStr: '未达到宝箱领取军功' },
PVP_BOX_IS_GOT: { code: 20804, simStr: '宝箱已经领取' },
PVP_CHALLENGE_TIMES_NOT_ENOUGH: { code: 20805, simStr: '挑战次数不足' },
PVP_SET_ATTACK_CNT_NOT_ENOUGH: { code: 20806, simStr: '设置挑战阵容次数不足' },
PVP_NOT_SET_ATTACK: { code: 20807, simStr: '未设置挑战阵容' },
// 军团 20900-20999
GUILD_AUTH_NOT_ENOUGH: { code: 20900, simStr: '权限不足' },

View File

@@ -108,15 +108,15 @@ export default class PvpDefense extends BaseModel {
const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId })
.populate('role', 'head frame spine topLineupCe roleId roleName lv globalCeAttr')
.populate('heroes.hero')
.populate('oppPlayer.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv title lv pLv defCe heroes').lean({ getters: true, virtuals: true });
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv title lv pLv defCe heroes').lean({ getters: true, virtuals: true });
return result;
}
public static async findByTeamLv(seasonNum: number, min: number, max: number) {
const result: PvpDefenseType[] = await PvpDefenseModel.find({ seasonNum, 'defense.pLv': { $gte: min, $lte: max } })
.populate('role', 'head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr')
.populate('role', '_id head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr')
.populate('heroes.hero')
.populate('oppPlayer.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes')
.lean({ getters: true, virtuals: true });
return result;
}
@@ -125,7 +125,7 @@ export default class PvpDefense extends BaseModel {
delete update._id;
let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set:update}, {new: true})
.populate('role', 'head frame spine heads frames spines topLineupCe roleId roleName lv')
.populate('oppPlayer.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes').lean({ getters: true, virtuals: true });
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes').lean({ getters: true, virtuals: true });
return result;
}
public static async updateInfo(roleId: string, update: pvpUpdateInter, lean = true) {

View File

@@ -39,7 +39,11 @@ export default class PvpHistoryOpp extends BaseModel {
defCe: number; // 防守战力,缩小过的
@prop({ required: true, default: 0 })
rankLv: number; // 对手排名
@prop({ required: true, type: PvpEnemies, default: [] })
@prop({ required: true })
warId: number; // 对手选择的地图id
@prop({ required: true })
buff: number; // 对手选择的buff
@prop({ required: true, type: PvpEnemies, default: [], _id: false })
heroes: PvpEnemies[]; // 对手阵容
@prop({ required: true, type: PvpOtherHeroes, default: [] })
otherHeroes: PvpOtherHeroes[]; // 阵容以外所有武将信息

View File

@@ -1,8 +1,9 @@
import { prop, Ref, mongoose } from '@typegoose/typegoose';
import Hero, { } from '../../db/Hero';
import Hero, { HeroType } from '../../db/Hero';
import { PvpDefenseType } from '../../db/PvpDefense';
import PvpHistoryOpp from '../../db/PvpHistoryOpp';
import { PvpSeasonResultType } from '../../db/PvpSeasonResult';
import { getPLvByScore } from '../../pubUtils/data';
import { RewardInter } from '../../pubUtils/interface';
@@ -18,6 +19,14 @@ export class DefenseHero {
order: number;
@prop({ ref: 'Hero', type: mongoose.Schema.Types.ObjectId })
hero: Ref<Hero>;
constructor(param: { actorId: number, ai: number, dataId: number, order: number }, heroId: string) {
this.actorId = param.actorId;
this.ai = param.ai;
this.dataId = param.dataId;
this.order = param.order;
this.hero = heroId;
}
}
// 防守阵容
@@ -32,6 +41,14 @@ export class Defense {
score: number; // 防守阵容的总军功
@prop({ required: true })
pLv: number; // 防守阵容的等级
constructor(heroes: DefenseHero[], score: number, warId: number, buff: number) {
this.heroes = heroes;
this.score = score;
this.pLv = getPLvByScore(score);
this.warId = warId;
this.buff = buff;
}
}
// 挑战阵容武将
@@ -50,6 +67,12 @@ export class Attack {
score: number; // 防守阵容的总军功
@prop({ required: true })
pLv: number; // 防守阵容的等级
constructor(heroes: AttackHero[], score: number) {
this.heroes = heroes;
this.score = score;
this.pLv = getPLvByScore(score);
}
}
// 两个阵容中的武将的分别的战力
@@ -63,7 +86,7 @@ export class LineupCe {
export class OppPlayer {
@prop({ required: true })
roleId: string;
@prop({ ref: 'PvpHistoryOpp', type: mongoose.Schema.Types.ObjectId })
@prop({ ref: () => PvpHistoryOpp, type: mongoose.Schema.Types.ObjectId })
oppDef: Ref<PvpHistoryOpp>;
@prop({ required: true })
pos: number;
@@ -115,6 +138,13 @@ export class DefenseHeroReturn {
ai: number; // ai逻辑1-进攻型 2-防守型
dataId: number;
order: number;
constructor(defenseHero: DefenseHero) {
this.actorId = defenseHero.actorId;
this.ai = defenseHero.ai;
this.dataId = defenseHero.dataId;
this.order = defenseHero.order;
}
}
export class DefenseLineupReturn {
@@ -124,19 +154,44 @@ export class DefenseLineupReturn {
score: number;
pLv: number;
ce: number;
constructor(defense: Defense, defenseCe: number) {
this.warId = defense.warId;
this.buff = defense.buff;
this.heroes = defense.heroes.map(cur => new DefenseHeroReturn(cur));
this.score = defense.score;
this.pLv = defense.pLv;
this.ce = defenseCe;
}
}
export class AttackLineupReturn {
warId: number;
buff: number;
heroes: AttackHero[];
score: number;
pLv: number;
ce: number;
constructor(attack: Attack, attackCe: number) {
this.heroes = attack.heroes;
this.score = attack.score;
this.pLv = attack.pLv;
this.ce = attackCe;
}
}
export class heroScoreReturn extends HeroScore {
isDefense: boolean;
export class HeroScoreReturn extends HeroScore {
isDefense: boolean = false;
constructor(heroScore: HeroScore, defense: Defense) {
super();
this.hid = heroScore.hid;
this.score = heroScore.score;
if(defense && defense.heroes) {
let index = defense.heroes.findIndex(cur => cur.actorId == this.hid);
if(index != -1) {
this.isDefense = true;
}
}
}
}
export class SeasonDataReturn {
@@ -181,18 +236,47 @@ export class PvpDataReturn {
challengeRefTime: number;
receiveBox: number[] = [];
hisScore: number = 0;
heroScores: heroScoreReturn[] = [];
heroScores: HeroScoreReturn[] = [];
isFirstEntry: boolean = false;
resultRecord: PvpSeasonResultRecord;
constructor(pvpDefense: PvpDefenseType) {
setPvpDefense(pvpDefense: PvpDefenseType) {
this.score = pvpDefense.score;
this.winStreakNum = pvpDefense.winStreakNum;
this.receiveBox = pvpDefense.receivedBox;
this.hisScore = pvpDefense.hisScore;
// this.oppPlayers
// this.heroScores
this.refOppCnt = pvpDefense.refOppCnt;
this.setAttackCnt = pvpDefense.setAttackCnt;
this.challengeCnt = pvpDefense.challengeCnt;
this.challengeRefTime = pvpDefense.challengeRefTime;
let { attackCe, defenseCe } = PvpDataReturn.getAttackAndDefenseCe(pvpDefense);
if(pvpDefense.attack) this.attack = new AttackLineupReturn(pvpDefense.attack, attackCe);
if(pvpDefense.defense) this.defense = new DefenseLineupReturn(pvpDefense.defense, defenseCe);
this.heroScores = pvpDefense.heroScores.map(cur => new HeroScoreReturn(cur, pvpDefense.defense));
}
static getAttackAndDefenseCe(pvpDefense: PvpDefenseType) {
let { lineupCe, attack, defense } = pvpDefense;
let attackCe = 0, defenseCe = 0;
for(let { hid, ce } of lineupCe) {
if(attack && attack.heroes) {
let hero = attack.heroes.find(cur => cur.actorId == hid);
if(hero) attackCe += ce;
}
if(defense && defense.heroes) {
let hero = defense.heroes.find(cur => cur.actorId == hid);
if(hero) defenseCe += ce;
}
}
return { attackCe, defenseCe };
}
setIsFirstEntry(isFirstEntry: boolean) {
this.isFirstEntry = isFirstEntry;
}
setOppPlayers(oppPlayers: OppPlayerReturn[]) {

View File

@@ -2,6 +2,8 @@ import { prop, mongoose, Ref } from '@typegoose/typegoose';
import { DicWarJson } from '../pubUtils/dictionary/DicWarJson';
import Hero, { HeroType } from '../db/Hero';
import { nowSeconds } from '../pubUtils/timeUtil';
import { DicHero } from '../pubUtils/dictionary/DicHero';
import { gameData } from '../pubUtils/data';
// 从玩家数据中覆盖warjson的部分字段
export class PvpHeroInfo {
@@ -41,13 +43,14 @@ export class PvpHeroInfo {
this.quality = hero.quality;
}
setRobotInfo(warjson: DicWarJson, actorId: number, lv: number, initialStar: number, quality: number) {
setRobotInfo(actorId: number, lv: number) {
let dicHero = gameData.hero.get(actorId);
this.actorId = actorId;
this.skinId = warjson.actorId;
this.actorName = warjson.actorName;
this.star = initialStar;
this.skinId = actorId;
this.actorName = dicHero.name;
this.star = dicHero.initialStars;
this.lv = lv;
this.quality = quality;
this.quality = dicHero.quality;
}
setAttribute(attribute: string) {

View File

@@ -32,15 +32,15 @@ export const PVP = {
PVP_CHALLENGE_COUNTS: 10, // pvp初始挑战次数
PVP_CHALLENGE_NORMALTIMES: 120, // pvp日常挑战次数刷新时间分钟
PVP_CHALLENGE_FINALTIMES: 60, // PVP赛季最后一天挑战次数刷新时间分钟
PVP_SEASON_DAYS: 30, // PVP一个赛季的时间
PVP_SEASON_DAYS: "1&7|2&10|3&20", // PVP一个赛季的时间
PVP_OPPONENT_FREEREFRESH: 3, // pvp挑战对手每日免费刷新次数
PVP_WINREWARD_UPLIMIT: 10, // 连胜奖励军功加成上限
PVP_LINEUP_HEROS: 6, // pvp最多上阵人数
PVP_SET_ATTACK_FREE_CNT: 2, // pvp每天免费设挑战阵容的次数
PVP_SET_ATTACK_CNT: 5, // pvp每天设置挑战阵容的次数包括免费
PVP_SET_ATTACK_CNT_GOLD: 100, // pvp收费设置挑战阵容的花费
PVP_DEFENSE_SUCCESS_REWARD: 5, // pvp防守成功积分奖励
PVP_DEFENSE_SUCCESS_REWARD_MAX_CNT: 5, // 每天防守成功可以获得的奖励次数
PVP_SET_ATTACK_CNT_GOLD: 100, // pvp收费设置挑战阵容的花费
PVP_DEFENSE_SUCCESS_REWARD: 5, // pvp防守成功积分奖励
PVP_DEFENSE_SUCCESS_REWARD_MAX_CNT: 5, // 每天防守成功可以获得的奖励
};
export const ARMY = {
ARMY_CREAT_COST: 188, // 创建军团需要的元宝