pvp:修改接口

This commit is contained in:
luying
2021-10-29 16:36:23 +08:00
parent e39b120af4
commit 7fb13da627
10 changed files with 359 additions and 214 deletions
@@ -2,28 +2,29 @@
import { Application, BackendSession, pinus, HandlerService, } from 'pinus'; import { Application, BackendSession, pinus, HandlerService, } from 'pinus';
import { uniq, findWhere, findIndex } from 'underscore'; import { uniq, findWhere, findIndex } from 'underscore';
import { gameData, getPvpBoxs, getPLvByScore } from '../../../pubUtils/data'; 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 { RoleModel, RoleType } from '../../../db/Role';
import { STATUS } from '../../../consts/statusCode'; import { STATUS } from '../../../consts/statusCode';
import { resResult, genCode, checkRoleIsRobot, robotIdComBack } from '../../../pubUtils/util'; import { resResult, genCode, checkRoleIsRobot, robotIdComBack } from '../../../pubUtils/util';
import { PvpDefenseModel, pvpUpdateInter } from '../../../db/PvpDefense'; 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 { PvpSeasonResultModel } from '../../../db/PvpSeasonResult';
import { PvpHistoryOppModel, PvpHistoryOppType } from '../../../db/PvpHistoryOpp';
import { PVPConfigModel } from '../../../db/SystemConfig'; import { PVPConfigModel } from '../../../db/SystemConfig';
import { Rank } from '../../../services/rankService'; import { Rank } from '../../../services/rankService';
import { checkActivityTask, checkTask, checkTaskInPvpEnd } from '../../../services/taskService'; 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) { export default function (app: Application) {
new HandlerService(app, {}); new HandlerService(app, {});
@@ -43,83 +44,90 @@ export class PvpHandler {
let role = await RoleModel.findByRoleId(roleId); let role = await RoleModel.findByRoleId(roleId);
pvpDefense = await PvpDefenseModel.createPvpDefense({ roleId: role.roleId, roleName: role.roleName, role: role._id }); pvpDefense = await PvpDefenseModel.createPvpDefense({ roleId: role.roleId, roleName: role.roleName, role: role._id });
} }
// 如果没有发过,将上赛季的奖励发下
pvpDefense = await sendLastSeasonRewardIfNotSent(pvpDefense); pvpDefense = await sendLastSeasonRewardIfNotSent(pvpDefense);
let { seasonNum, seasonEndTime } = await PVPConfigModel.findCurPVPConfig(); let { seasonNum, seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
let update: pvpUpdateInter = { };
let result = new PvpDataReturn(); // 返回对象
// 刷新次数
let refChallengeObj = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime); let refChallengeObj = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
let refOppObj = refreshRefOppCnt(pvpDefense.refOppCnt, pvpDefense.refDaily); if(refChallengeObj.hasChanged) {
update = { ...update, ...refChallengeObj }
let update: pvpUpdateInter = { ...refChallengeObj, ...refOppObj}; }
let refOppObj = refreshRefOppCnt(pvpDefense.refOppCnt, pvpDefense.setAttackCnt, pvpDefense.refDaily);
let result = new PvpDataReturn(pvpDefense); // 返回对象 // 每天首次打开要刷掉对手
if(refOppObj.shouldRefOpp) { if(refOppObj.shouldRefOpp) {
let role = <RoleType>pvpDefense.role; if(pvpDefense.attack) {
let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack.pLv); let role = <RoleType>pvpDefense.role;
update.oppPlayers = oppPlayers; let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack.pLv||1);
let oppPlayersReturn = await getEnemies(oppPlayers||[], pvpDefense.winStreakNum); update.oppPlayers = oppPlayers;
result.setOppPlayers(oppPlayersReturn); }
} else { update = { ...update, ...refOppObj }
let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers||[], pvpDefense.winStreakNum);
result.setOppPlayers(oppPlayersReturn);
} }
let { score, winStreakNum, refOppCnt, challengeCnt, challengeRefTime, receivedBox, hisScore, heroScores, isFirstEntry } = pvpDefense;
if (pvpDefense.isFirstEntry) { if (pvpDefense.isFirstEntry) {
update.isFirstEntry = false; 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.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) { if (!!pvpSeasonResult && !!pvpSeasonResult.show) {
result.setPvpSeasonResult(pvpSeasonResult); result.setPvpSeasonResult(pvpSeasonResult);
await PvpSeasonResultModel.updatePvpSeasonResult(roleId, pvpSeasonResult.seasonNum, { show: false }); await PvpSeasonResultModel.updatePvpSeasonResult(roleId, pvpSeasonResult.seasonNum, { show: false });
} }
// 拍卖
let r = new Rank(REDIS_KEY.PVP_RANK, {}); let r = new Rank(REDIS_KEY.PVP_RANK, {});
let myRank = await r.getMyRank({ roleId });//去redis中获取排名 let myRank = await r.getMyRank({ roleId });//去redis中获取排名
result.setMyRank(myRank); 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); return resResult(STATUS.SUCCESS, result);
} }
/*
// 刷新对手 // 刷新对手
async refreshOppPlayer(msg: {}, session: BackendSession) { async refreshOppPlayer(msg: {}, session: BackendSession) {
let roleId = session.get('roleId'); let roleId = session.get('roleId');
let sid = session.get('sid'); let sid = session.get('sid');
let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId); 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); let refOppObj = refreshRefOppCnt(pvpDefense.refOppCnt, pvpDefense.setAttackCnt, pvpDefense.refDaily);
if (refOppCnt >= gameData.maxPvpRefreshCnt.max) { if (refOppObj.refOppCnt >= gameData.maxPvpRefreshCnt.max) {
return resResult(STATUS.PVP_REFRESH_CNT_REACH_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); if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH);
refOppObj.refOppCnt ++;
// 刷新对手 // 刷新对手
let role = <RoleType>pvpDefense.role; 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 }); pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { oppPlayers, ...refOppObj });
let result = await getEnemies(pvpDefense.oppPlayers, pvpDefense.winStreakNum);
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) { async getOppPlayer(msg: { roleId: string }, session: BackendSession) {
let roleId = session.get('roleId'); let roleId = session.get('roleId');
@@ -131,14 +139,15 @@ export class PvpHandler {
let curOpp = oppPlayers.find(cur => cur.roleId == oppoRoleId); let curOpp = oppPlayers.find(cur => cur.roleId == oppoRoleId);
if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND); 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) { async pvpStart(msg: { warId: number, roleId: string }, session: BackendSession) {
const { warId, heroes, roleId: oppRoleId } = msg; const { warId, roleId: oppRoleId } = msg;
let roleId = session.get('roleId'); let roleId = session.get('roleId');
let roleName = session.get('roleName'); let roleName = session.get('roleName');
@@ -147,10 +156,7 @@ export class PvpHandler {
return resResult(STATUS.BATTLE_MISS_INFO); return resResult(STATUS.BATTLE_MISS_INFO);
} }
let { isOK } = await checkBattleHeroesByHid(roleId, heroes); let pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
if (!isOK) return resResult(STATUS.BATTLE_HERO_NOT_FOUND);
const pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
if (!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); if (!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN);
// 检查挑战次数 // 检查挑战次数
let { seasonEndTime } = await PVPConfigModel.findCurPVPConfig(); let { seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
@@ -164,6 +170,7 @@ export class PvpHandler {
if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND) if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND)
const battleCode = genCode(8); // 关卡唯一值 const battleCode = genCode(8); // 关卡唯一值
let heroes = pvpDefense.attack.heroes.map(cur => cur.actorId);
await BattleRecordModel.updateBattleRecordByCode(battleCode, { await BattleRecordModel.updateBattleRecordByCode(battleCode, {
$set: { $set: {
@@ -205,26 +212,28 @@ export class PvpHandler {
if (!flag) return resResult(STATUS.BATTLE_INFO_VALIDATE_ERR); 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); 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); let update: pvpUpdateInter = {};
if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND);
const role = await RoleModel.findByRoleId(roleId, null, true); const role = await RoleModel.findByRoleId(roleId, null, true);
if (isSuccess) { if (isSuccess) {
winStreakNum++; update.winStreakNum = pvpDefense.winStreakNum + 1;
} else { } else {
winStreakNum = 0; update.winStreakNum = 0;
} }
const myRecInfo = await generMyRecInfo(heroScores, winStreakNum, role, isSuccess, pos, myHeroes); const myRecInfo = await generMyRecInfo(pvpDefense.heroScores, pvpDefense.winStreakNum, role, isSuccess, pos, myHeroes);
let { attackInfo, showHeroScores, addSumScore, newHeroScore } = myRecInfo
let { attackInfo, showHeroScores, addSumScore } = myRecInfo update.heroScores = newHeroScore;
update.score = pvpDefense.score + addSumScore;
score += addSumScore; if (pvpDefense.hisScore < update.score) {
let pLv = getLvByScore(heroScores); 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); const defenseInfo = await generPVPOppRecInfo(isSuccess, curOpp, oppHeroes, role.lv);
// 战报记录 // 战报记录
@@ -234,130 +243,150 @@ export class PvpHandler {
await PvpHistoryOppModel.setStatus(roleId, oppRoleId, 1); 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 // 更新battleRecord
await BattleRecordModel.updateBattleRecordByCode(battleCode, { await BattleRecordModel.updateBattleRecordByCode(battleCode, {
$set: { status: isSuccess ? 1 : 2 } $set: { status: isSuccess ? 1 : 2 }
}, true); }, true);
let { seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
// 减少挑战次数 // 减少挑战次数
if (hisScore < score) { let refChallengeObj = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
hisScore = score; refChallengeObj.challengeCnt --;
} update = {...update, ...refChallengeObj};
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { oppPlayers: newOppPlayers, heroScores, score, pLv, winStreakNum, challengeCnt: pvpDefense.challengeCnt - 1, hisScore });
let result = await getEnemies(pvpDefense.oppPlayers, pvpDefense.winStreakNum); 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, {}); let r = new Rank(REDIS_KEY.PVP_RANK, {});
await r.setRankWithRoleInfo(roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), role); await r.setRankWithRoleInfo(roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), role);
let myRank = await r.getMyRank({ roleId }); 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) await checkActivityTask(serverId, sid, roleId, TASK_TYPE.PVP, 1)
if (isSuccess) { if (isSuccess) {
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.PVP_WIN, 1) await checkActivityTask(serverId, sid, roleId, TASK_TYPE.PVP_WIN, 1)
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.PVP_WIN_SERIES, 1) await checkActivityTask(serverId, sid, roleId, TASK_TYPE.PVP_WIN_SERIES, 1)
} }
return resResult(STATUS.SUCCESS, { return resResult(STATUS.SUCCESS, {
battleCode, isSuccess, battleCode, isSuccess,
score, pLv, myRank, hisScore,
heroScores: showHeroScores, heroScores: showHeroScores,
oppPlayers: result, ...pick(result, ['score', 'myRank', 'winStreakNum', 'attack', 'oppPlayers', 'challengeCnt', 'challengeRefTime'])
refOppCnt: pvpDefense.refOppCnt,
challengeCnt: pvpDefense.challengeCnt,
challengeRefTime: pvpDefense.challengeRefTime,
winStreakNum: pvpDefense.winStreakNum,
warId
}); });
} }
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. 保存防守阵容 //3. 保存防守阵容
async saveDefense(msg: { heroes: Array<{ actorId: number, dataId: number, order: number }>, isDefaultHero: boolean }, session: BackendSession) { async saveDefense(msg: { heroes: { actorId: number, dataId: number, order: number, ai: number }[], warId: number, buff: number }, session: BackendSession) {
let { heroes, isDefaultHero } = msg; let { heroes, warId, buff } = msg;
let roleId = session.get('roleId'); let roleId = session.get('roleId');
if (heroes.length > LINEUP_NUM || heroes.length <= 0) { if (heroes.length > LINEUP_NUM || heroes.length <= 0) {
return resResult(STATUS.WRONG_PARMS); 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 { seasonEndTime } = await PVPConfigModel.findCurPVPConfig();
let { heroes: defHeros, challengeCnt: lastChallengeCnt, challengeRefTime: lastChallengeRefTime } = await PvpDefenseModel.findByRoleId(roleId); let refChallengeObj = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
let defCe = 0; // 更新防守阵容
let { challengeCnt, challengeRefTime } = refChallengeCnt(lastChallengeCnt, lastChallengeRefTime, seasonEndTime); let score = 0, heroIdMap = new Map<number, string>(), hids: number[] = [];
for(let { actorId } of heroes) {
if (!!isDefaultHero) { let heroScore = pvpDefense.heroScores.find(cur => cur.hid == actorId);
let { topLineup } = await RoleModel.findByRoleId(roleId); if(heroScore) {
let hids = topLineup.filter(cur => { score += heroScore.score;
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);
}
} }
for (let hid of hids) { // 记录hero的objectId,用于存defense.heroes.hero
let dataId = 0; if(pvpDefense.defense && pvpDefense.defense.heroes) {
for (let i = PVP_HERO_POS.START; i <= PVP_HERO_POS.END; i++) { let heroInDefense = pvpDefense.defense.heroes.find(cur => cur.actorId == actorId);
if (dataIds.includes(i)) continue; if(heroInDefense) {
dataIds.push(i); heroIdMap.set(actorId, <string>heroInDefense.hero);
dataId = i; break; } else {
hids.push(actorId);
} }
let order = 0; } else {
for (let i = PVP_HERO_ORDER.START; i <= PVP_HERO_ORDER.END; i++) { hids.push(actorId);
if (orders.includes(i)) continue;
orders.push(i);
order = i; break;
}
heroes.push({
actorId: hid, dataId, order
})
} }
} }
let dbHeroes = await HeroModel.findByHidRange(hids, roleId, '_id hid ce', true);
for (let dataId = PVP_HERO_POS.START; dataId <= PVP_HERO_POS.END; dataId++) { for(let hero of dbHeroes) {
let index = findIndex(heroes, { dataId }); heroIdMap.set(hero.hid, hero._id);
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 { 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. 排行榜 //8. 排行榜
async getRank(msg: {}, session: BackendSession) { async getRank(msg: {}, session: BackendSession) {
@@ -369,7 +398,7 @@ export class PvpHandler {
if (!myRank) { if (!myRank) {
let pvpDefense = await PvpDefenseModel.findByRoleId(roleId); 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 }); return resResult(STATUS.SUCCESS, { ranks, myRank });
@@ -487,9 +516,7 @@ export class PvpHandler {
if (hisScore < score) { if (hisScore < score) {
hisScore = score; hisScore = score;
} }
let pLv = getPLvByScore(score); let pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { score, hisScore, heroScores });
let pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { score, hisScore, pLv, heroScores });
let roleName = session.get('roleName');
const role = await RoleModel.findByRoleId(roleId); const role = await RoleModel.findByRoleId(roleId);
// 加入排行榜 // 加入排行榜
@@ -501,7 +528,7 @@ export class PvpHandler {
return resResult(STATUS.SUCCESS, { score, hisScore, heroScores }); return resResult(STATUS.SUCCESS, { score, hisScore, heroScores });
} }
/*
async debugPvpSeasonReset(msg: {}, session: BackendSession) { async debugPvpSeasonReset(msg: {}, session: BackendSession) {
await pvpSeasonEnd({ name: 'exce setPvpSeasonResult debug' }); await pvpSeasonEnd({ name: 'exce setPvpSeasonResult debug' });
let systemConfig = await createNextPvpSeason(); let systemConfig = await createNextPvpSeason();
@@ -519,6 +546,7 @@ export class PvpHandler {
return resResult(STATUS.SUCCESS, { seasonNum, seasonEndTime }); return resResult(STATUS.SUCCESS, { seasonNum, seasonEndTime });
} }
*/
async debugAddChallengeCnt(msg: { challengeCnt: number }, session: BackendSession) { async debugAddChallengeCnt(msg: { challengeCnt: number }, session: BackendSession) {
let { challengeCnt } = msg; let { challengeCnt } = msg;
let roleId = session.get('roleId'); let roleId = session.get('roleId');
@@ -529,5 +557,4 @@ export class PvpHandler {
return resResult(STATUS.SUCCESS, { challengeCnt, challengeRefTime }); return resResult(STATUS.SUCCESS, { challengeCnt, challengeRefTime });
} }
*/
} }
+38 -15
View File
@@ -1,6 +1,6 @@
import { PvpDefenseModel, PvpDefenseType, pvpUpdateInter } from '../db/PvpDefense'; 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 { RoleType, CeAttrDataRole } from '../db/Role';
import { PVP_HERO_POS, REDIS_KEY, PVP_CONST, COUNTER, TASK_TYPE, MAIL_TYPE } from '../consts'; import { PVP_HERO_POS, REDIS_KEY, PVP_CONST, COUNTER, TASK_TYPE, MAIL_TYPE } from '../consts';
import { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent"; import { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent";
@@ -11,7 +11,7 @@ import { PVP } from '../pubUtils/dicParam';
import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig' import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig'
import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil'; import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil';
import { HeroesRecord } from '../db/PvpRecord'; 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 { AttributeCal } from '../domain/roleField/attribute';
import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from '../domain/dbGeneral'; import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from '../domain/dbGeneral';
import { DicWarJson } from '../pubUtils/dictionary/DicWarJson'; import { DicWarJson } from '../pubUtils/dictionary/DicWarJson';
@@ -37,6 +37,8 @@ export async function getEnemies(oppPlayers: OppPlayer[], winStreakNum: number)
for (let oppPlayer of oppPlayers) { for (let oppPlayer of oppPlayers) {
let dicOpponent = dicPvpOpponent.get(oppPlayer.pos); let dicOpponent = dicPvpOpponent.get(oppPlayer.pos);
let oppDef = <PvpHistoryOppType>oppPlayer.oppDef; // select 'oppRoleId pos roleName head frame spine rankLv pLv defCe' let oppDef = <PvpHistoryOppType>oppPlayer.oppDef; // select 'oppRoleId pos roleName head frame spine rankLv pLv defCe'
console.log('*******', oppDef)
if (oppDef) delete oppDef.heroes; if (oppDef) delete oppDef.heroes;
result.push({ result.push({
...oppDef, ...oppDef,
@@ -239,10 +241,10 @@ async function matchRobot(oppPlayers: OppPlayer[], role: RoleType, pLv: number,
let dicHero = gameData.hero.get(actorId); let dicHero = gameData.hero.get(actorId);
if (!dicHero) continue; if (!dicHero) continue;
let heroInfo = new PvpHeroInfo(); 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); let { attribute, ce } = getRobotAttribute(h.attribute, h.enemyCount, [], pLv, myCe, PVP_CONST.ENEMY_CE, ratio);
defCe += ce; 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); let enemy = new PvpEnemies(h, heroInfo, 0, ce);
heroes.push(enemy); heroes.push(enemy);
} }
@@ -253,7 +255,7 @@ async function matchRobot(oppPlayers: OppPlayer[], role: RoleType, pLv: number,
if (hisPLv < 1) hisPLv = 1 if (hisPLv < 1) hisPLv = 1
let pvpHistoryOpp = await PvpHistoryOppModel.createPvpOpp({ 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({ oppPlayers.push({
@@ -289,8 +291,9 @@ export function getLvByScore(heroScores: HeroScore[]) {
} }
export function refChallengeCnt(challengeCnt: number, challengeRefTime: number, seasonEndTime: number) { export function refChallengeCnt(challengeCnt: number, challengeRefTime: number, seasonEndTime: number) {
let hasChanged = false;
if (challengeCnt >= PVP.PVP_CHALLENGE_COUNTS) { if (challengeCnt >= PVP.PVP_CHALLENGE_COUNTS) {
return { challengeCnt, challengeRefTime }; return { hasChanged, challengeCnt, challengeRefTime };
} }
let period = PVP.PVP_CHALLENGE_NORMALTIMES * 60; let period = PVP.PVP_CHALLENGE_NORMALTIMES * 60;
if (getTimeFun(seasonEndTime).checkDay()) { if (getTimeFun(seasonEndTime).checkDay()) {
@@ -301,9 +304,10 @@ export function refChallengeCnt(challengeCnt: number, challengeRefTime: number,
if (num > 0) { if (num > 0) {
challengeCnt += num; challengeCnt += num;
challengeRefTime = challengeRefTime + period * num; challengeRefTime = challengeRefTime + period * num;
hasChanged = true;
} }
challengeCnt = challengeCnt > PVP.PVP_CHALLENGE_COUNTS ? PVP.PVP_CHALLENGE_COUNTS : challengeCnt; 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) { 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 curTime = new Date();
let shouldRefOpp = shouldRefresh(refDaily, curTime); let shouldRefOpp = shouldRefresh(refDaily, curTime);
if (shouldRefOpp) { if (shouldRefOpp) {
refOppCnt = 0; refDaily = curTime; refOppCnt = 0; setAttackCnt = 0; refDaily = curTime;
} }
return { return {
shouldRefOpp, shouldRefOpp,
refOppCnt, refDaily, refOppCnt, refDaily, setAttackCnt,
consume: gameData.pvpRefreshConsume.get(refOppCnt + 1) consume: gameData.pvpRefreshConsume.get(refOppCnt + 1)
} }
} }
@@ -405,6 +409,7 @@ export async function generMyRecInfo(heroScores: HeroScore[], winStreakNum: numb
const plusScore = getPlusScore(winStreakNum); const plusScore = getPlusScore(winStreakNum);
let pLv = getLvByScore(heroScores); let pLv = getLvByScore(heroScores);
// TODO 这里heroScore可以改为不改变原数据,而创建新数据的方式
let myHeroRecords = new Array<HeroesRecord>(); let myHeroRecords = new Array<HeroesRecord>();
let showHeroScores = new Array<{ hid: number, addScore: number, plusScore: number, score: number }>(); let showHeroScores = new Array<{ hid: number, addScore: number, plusScore: number, score: number }>();
let addSumScore = 0; let addSumScore = 0;
@@ -450,7 +455,7 @@ export async function generMyRecInfo(heroScores: HeroScore[], winStreakNum: numb
score: isSuccess ? addSumScore : 0 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; return pvpSeasonResult;
} }
function getScore(arr, score) { export async function generPvpLineupCe(roleId: string, lineupCe: LineupCe[], newHeroes: AttackHero[]|DefenseHero[], dbHeroes: HeroType[]) {
for (let item of arr) { let newHids: number[] = []; // 本次新增武将
if ((item.max >= score || item.max == -1) && score >= item.min) { let newLineupCe: { hid: number, ce: number }[] = []; // 新生成的lineupCe字段
return item; 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;
} }
+11 -10
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); await r.setRankWithGuildInfoArrParam(guild.code, [guild.lv, guild.activeWeekly, guild.activeUpdateTime], guild);
} }
} else if (type == REDIS_KEY.PVP_RANK) { } else if (type == REDIS_KEY.PVP_RANK) {
let { seasonNum } = await PVPConfigModel.findCurPVPConfig(); let pvpConfig = await PVPConfigModel.findCurPVPConfig();
console.log('execute season resetPvpRanks seasonNum = ' + seasonNum); if(pvpConfig) {
let ranks = await PvpDefenseModel.getRank(seasonNum);//获得全服前1000名的排名,加入到redis中 let ranks = await PvpDefenseModel.getRank(pvpConfig.seasonNum);//获得全服前1000名的排名,加入到redis中
let r = new Rank(type, {}); let r = new Rank(type, {});
r.setIsInit(true); r.setIsInit(true);
for (let { roleId, role: _role, score, updatedAt } of ranks) { for (let { roleId, role: _role, score, updatedAt } of ranks) {
let role = <RoleType>_role; let role = <RoleType>_role;
if (!role) { if (!role) {
continue; 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) { } else if (type == REDIS_KEY.TOP_LINEUP_RANK) {
let serverId = args.serverId; let serverId = args.serverId;
+6 -5
View File
@@ -1,7 +1,7 @@
import { scheduleJob, Job, } from 'node-schedule'; import { scheduleJob, Job, } from 'node-schedule';
import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig'; 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 { getTodayGuildActivity, gameData } from '../pubUtils/data';
import { pvpSeasonEnd } from './pvpService'; import { pvpSeasonEnd } from './pvpService';
import { getAllOnlineRoles, getAllServers, delGuildActivityRank } from './redisService'; import { getAllOnlineRoles, getAllServers, delGuildActivityRank } from './redisService';
@@ -83,7 +83,7 @@ function getSeasonContinueDay(seasonNum: number) {
async function setPvpSeason() { async function setPvpSeason() {
let pvpConfig = await PVPConfigModel.findCurPVPConfig(); let pvpConfig = await PVPConfigModel.findCurPVPConfig();
if(!pvpConfig || pvpConfig.seasonEndTime <= nowSeconds() ) { if(!pvpConfig || pvpConfig.seasonEndTime <= nowSeconds() ) {
if(!pvpConfig.hasSettleReward) { if(pvpConfig && !pvpConfig.hasSettleReward) {
await pvpSeasonEnd(pvpConfig); await pvpSeasonEnd(pvpConfig);
} }
@@ -94,9 +94,10 @@ async function setPvpSeason() {
let during = getSeasonContinueDay(lastSeasonNum + 1) * PER_DAY; let during = getSeasonContinueDay(lastSeasonNum + 1) * PER_DAY;
let rewardTime = SETTLE_DIFF_SECONDS; let rewardTime = SETTLE_DIFF_SECONDS;
if(nowSeconds() - lastSeasonEndTime > during) { 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 setPvpSeasonMakeRewardJob(pvpConfig);
await setNextSeasonJob(pvpConfig); await setNextSeasonJob(pvpConfig);
@@ -128,7 +129,7 @@ async function setNextSeasonJob(pvpConfig: PVPConfigType) {
* @param hour * @param hour
*/ */
export async function resetPvpSeasonTime(hour: number) { export async function resetPvpSeasonTime(hour: number) {
await PVPConfigModel.setCurPvpConfig({ seasonEndTime: getZeroPoint() }); await PVPConfigModel.setCurPvpConfig({ seasonEndTime: <number>getTimeFun().getDayZeroPoint(0) });
return await setPvpSeason(); return await setPvpSeason();
} }
+2
View File
@@ -141,6 +141,8 @@ export const STATUS = {
PVP_NOT_REACH_BOX_SCORE: { code: 20803, simStr: '未达到宝箱领取军功' }, PVP_NOT_REACH_BOX_SCORE: { code: 20803, simStr: '未达到宝箱领取军功' },
PVP_BOX_IS_GOT: { code: 20804, simStr: '宝箱已经领取' }, PVP_BOX_IS_GOT: { code: 20804, simStr: '宝箱已经领取' },
PVP_CHALLENGE_TIMES_NOT_ENOUGH: { code: 20805, 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 // 军团 20900-20999
GUILD_AUTH_NOT_ENOUGH: { code: 20900, simStr: '权限不足' }, GUILD_AUTH_NOT_ENOUGH: { code: 20900, simStr: '权限不足' },
+4 -4
View File
@@ -108,15 +108,15 @@ export default class PvpDefense extends BaseModel {
const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId }) const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId })
.populate('role', 'head frame spine topLineupCe roleId roleName lv globalCeAttr') .populate('role', 'head frame spine topLineupCe roleId roleName lv globalCeAttr')
.populate('heroes.hero') .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; return result;
} }
public static async findByTeamLv(seasonNum: number, min: number, max: number) { public static async findByTeamLv(seasonNum: number, min: number, max: number) {
const result: PvpDefenseType[] = await PvpDefenseModel.find({ seasonNum, 'defense.pLv': { $gte: min, $lte: max } }) 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('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 }); .lean({ getters: true, virtuals: true });
return result; return result;
} }
@@ -125,7 +125,7 @@ export default class PvpDefense extends BaseModel {
delete update._id; delete update._id;
let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set:update}, {new: true}) let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set:update}, {new: true})
.populate('role', 'head frame spine heads frames spines topLineupCe roleId roleName lv') .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; return result;
} }
public static async updateInfo(roleId: string, update: pvpUpdateInter, lean = true) { public static async updateInfo(roleId: string, update: pvpUpdateInter, lean = true) {
+5 -1
View File
@@ -39,7 +39,11 @@ export default class PvpHistoryOpp extends BaseModel {
defCe: number; // 防守战力,缩小过的 defCe: number; // 防守战力,缩小过的
@prop({ required: true, default: 0 }) @prop({ required: true, default: 0 })
rankLv: number; // 对手排名 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[]; // 对手阵容 heroes: PvpEnemies[]; // 对手阵容
@prop({ required: true, type: PvpOtherHeroes, default: [] }) @prop({ required: true, type: PvpOtherHeroes, default: [] })
otherHeroes: PvpOtherHeroes[]; // 阵容以外所有武将信息 otherHeroes: PvpOtherHeroes[]; // 阵容以外所有武将信息
+94 -10
View File
@@ -1,8 +1,9 @@
import { prop, Ref, mongoose } from '@typegoose/typegoose'; import { prop, Ref, mongoose } from '@typegoose/typegoose';
import Hero, { } from '../../db/Hero'; import Hero, { HeroType } from '../../db/Hero';
import { PvpDefenseType } from '../../db/PvpDefense'; import { PvpDefenseType } from '../../db/PvpDefense';
import PvpHistoryOpp from '../../db/PvpHistoryOpp'; import PvpHistoryOpp from '../../db/PvpHistoryOpp';
import { PvpSeasonResultType } from '../../db/PvpSeasonResult'; import { PvpSeasonResultType } from '../../db/PvpSeasonResult';
import { getPLvByScore } from '../../pubUtils/data';
import { RewardInter } from '../../pubUtils/interface'; import { RewardInter } from '../../pubUtils/interface';
@@ -18,6 +19,14 @@ export class DefenseHero {
order: number; order: number;
@prop({ ref: 'Hero', type: mongoose.Schema.Types.ObjectId }) @prop({ ref: 'Hero', type: mongoose.Schema.Types.ObjectId })
hero: Ref<Hero>; 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; // 防守阵容的总军功 score: number; // 防守阵容的总军功
@prop({ required: true }) @prop({ required: true })
pLv: number; // 防守阵容的等级 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; // 防守阵容的总军功 score: number; // 防守阵容的总军功
@prop({ required: true }) @prop({ required: true })
pLv: number; // 防守阵容的等级 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 { export class OppPlayer {
@prop({ required: true }) @prop({ required: true })
roleId: string; roleId: string;
@prop({ ref: 'PvpHistoryOpp', type: mongoose.Schema.Types.ObjectId }) @prop({ ref: () => PvpHistoryOpp, type: mongoose.Schema.Types.ObjectId })
oppDef: Ref<PvpHistoryOpp>; oppDef: Ref<PvpHistoryOpp>;
@prop({ required: true }) @prop({ required: true })
pos: number; pos: number;
@@ -115,6 +138,13 @@ export class DefenseHeroReturn {
ai: number; // ai逻辑,1-进攻型 2-防守型 ai: number; // ai逻辑,1-进攻型 2-防守型
dataId: number; dataId: number;
order: 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 { export class DefenseLineupReturn {
@@ -124,19 +154,44 @@ export class DefenseLineupReturn {
score: number; score: number;
pLv: number; pLv: number;
ce: 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 { export class AttackLineupReturn {
warId: number;
buff: number;
heroes: AttackHero[]; heroes: AttackHero[];
score: number; score: number;
pLv: number; pLv: number;
ce: 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 { export class HeroScoreReturn extends HeroScore {
isDefense: boolean; 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 { export class SeasonDataReturn {
@@ -181,18 +236,47 @@ export class PvpDataReturn {
challengeRefTime: number; challengeRefTime: number;
receiveBox: number[] = []; receiveBox: number[] = [];
hisScore: number = 0; hisScore: number = 0;
heroScores: heroScoreReturn[] = []; heroScores: HeroScoreReturn[] = [];
isFirstEntry: boolean = false; isFirstEntry: boolean = false;
resultRecord: PvpSeasonResultRecord; resultRecord: PvpSeasonResultRecord;
constructor(pvpDefense: PvpDefenseType) { setPvpDefense(pvpDefense: PvpDefenseType) {
this.score = pvpDefense.score; this.score = pvpDefense.score;
this.winStreakNum = pvpDefense.winStreakNum; this.winStreakNum = pvpDefense.winStreakNum;
this.receiveBox = pvpDefense.receivedBox; this.receiveBox = pvpDefense.receivedBox;
this.hisScore = pvpDefense.hisScore; 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[]) { setOppPlayers(oppPlayers: OppPlayerReturn[]) {
+8 -5
View File
@@ -2,6 +2,8 @@ import { prop, mongoose, Ref } from '@typegoose/typegoose';
import { DicWarJson } from '../pubUtils/dictionary/DicWarJson'; import { DicWarJson } from '../pubUtils/dictionary/DicWarJson';
import Hero, { HeroType } from '../db/Hero'; import Hero, { HeroType } from '../db/Hero';
import { nowSeconds } from '../pubUtils/timeUtil'; import { nowSeconds } from '../pubUtils/timeUtil';
import { DicHero } from '../pubUtils/dictionary/DicHero';
import { gameData } from '../pubUtils/data';
// 从玩家数据中覆盖warjson的部分字段 // 从玩家数据中覆盖warjson的部分字段
export class PvpHeroInfo { export class PvpHeroInfo {
@@ -41,13 +43,14 @@ export class PvpHeroInfo {
this.quality = hero.quality; 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.actorId = actorId;
this.skinId = warjson.actorId; this.skinId = actorId;
this.actorName = warjson.actorName; this.actorName = dicHero.name;
this.star = initialStar; this.star = dicHero.initialStars;
this.lv = lv; this.lv = lv;
this.quality = quality; this.quality = dicHero.quality;
} }
setAttribute(attribute: string) { setAttribute(attribute: string) {
+4 -4
View File
@@ -32,15 +32,15 @@ export const PVP = {
PVP_CHALLENGE_COUNTS: 10, // pvp初始挑战次数 PVP_CHALLENGE_COUNTS: 10, // pvp初始挑战次数
PVP_CHALLENGE_NORMALTIMES: 120, // pvp日常挑战次数刷新时间(分钟) PVP_CHALLENGE_NORMALTIMES: 120, // pvp日常挑战次数刷新时间(分钟)
PVP_CHALLENGE_FINALTIMES: 60, // 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_OPPONENT_FREEREFRESH: 3, // pvp挑战对手每日免费刷新次数
PVP_WINREWARD_UPLIMIT: 10, // 连胜奖励军功加成上限 PVP_WINREWARD_UPLIMIT: 10, // 连胜奖励军功加成上限
PVP_LINEUP_HEROS: 6, // pvp最多上阵人数 PVP_LINEUP_HEROS: 6, // pvp最多上阵人数
PVP_SET_ATTACK_FREE_CNT: 2, // pvp每天免费设挑战阵容的次数 PVP_SET_ATTACK_FREE_CNT: 2, // pvp每天免费设挑战阵容的次数
PVP_SET_ATTACK_CNT: 5, // pvp每天设置挑战阵容的次数(包括免费) PVP_SET_ATTACK_CNT: 5, // pvp每天设置挑战阵容的次数(包括免费)
PVP_SET_ATTACK_CNT_GOLD: 100, // pvp收费设置挑战阵容的花费 PVP_SET_ATTACK_CNT_GOLD: 100, // pvp收费设置挑战阵容的花费
PVP_DEFENSE_SUCCESS_REWARD: 5, // pvp防守成功积分奖励 PVP_DEFENSE_SUCCESS_REWARD: 5, // pvp防守成功积分奖励
PVP_DEFENSE_SUCCESS_REWARD_MAX_CNT: 5, // 每天防守成功可以获得的奖励次数 PVP_DEFENSE_SUCCESS_REWARD_MAX_CNT: 5, // 每天防守成功可以获得的奖励
}; };
export const ARMY = { export const ARMY = {
ARMY_CREAT_COST: 188, // 创建军团需要的元宝 ARMY_CREAT_COST: 188, // 创建军团需要的元宝