diff --git a/game-server/app/servers/battle/handler/pvpHandler.ts b/game-server/app/servers/battle/handler/pvpHandler.ts index df4a153a1..dcbec2762 100644 --- a/game-server/app/servers/battle/handler/pvpHandler.ts +++ b/game-server/app/servers/battle/handler/pvpHandler.ts @@ -218,19 +218,10 @@ export class PvpHandler { let update: pvpUpdateInter = {}; const role = await RoleModel.findByRoleId(roleId, null, true); - if (isSuccess) { - update.winStreakNum = pvpDefense.winStreakNum + 1; - } else { - update.winStreakNum = 0; - } - 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; - } + const myRecInfo = await generMyRecInfo(pvpDefense, role, isSuccess, pos, myHeroes); + let { attackInfo, showHeroScores, updateParam } = myRecInfo + update = { ...update, ...updateParam }; let curOpp = pvpDefense.oppPlayers.find(cur => cur.roleId == oppRoleId && cur.pos == pos); if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND); @@ -311,9 +302,6 @@ export class PvpHandler { refOppObj.setAttackCnt ++; let { seasonNum, seasonEndTime } = await PVPConfigModel.findCurPVPConfig(); let refChallengeObj = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime); - // 刷对手 - let role = pvpDefense.role; - let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.attack.score, pvpDefense.attack?.pLv||1); // 更新挑战阵容 let score = 0; for(let { actorId } of heroes) { @@ -324,6 +312,9 @@ export class PvpHandler { } let attack = new Attack(heroes, score); let lineupCe = await generPvpLineupCe(roleId, pvpDefense.lineupCe, attack.heroes, []); + // 刷对手 + let role = pvpDefense.role; + let oppPlayers = await refreshEnemies(role, seasonNum, attack?.score||0, attack?.pLv||1); // 保存 pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { ...refOppObj, ...refChallengeObj, attack, oppPlayers, lineupCe }); // 返回 diff --git a/game-server/app/services/pvpService.ts b/game-server/app/services/pvpService.ts index 302430ee8..c67e9c697 100644 --- a/game-server/app/services/pvpService.ts +++ b/game-server/app/services/pvpService.ts @@ -10,7 +10,7 @@ import { gameData, getPLvByScore, getPvpHeroRewardsByScore, getPvpRankRewardsByR import { PVP } from '../pubUtils/dicParam'; import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig' import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil'; -import { HeroesRecord } from '../db/PvpRecord'; +import { HeroesRecord, PvpRecordPlayerInfo } from '../db/PvpRecord'; import { HeroModel, CeAttrData, HeroType } from '../db/Hero'; import { AttributeCal } from '../domain/roleField/attribute'; import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from '../domain/dbGeneral'; @@ -37,7 +37,6 @@ export async function getEnemies(oppPlayers: OppPlayer[], winStreakNum: number) for (let oppPlayer of oppPlayers) { let dicOpponent = dicPvpOpponent.get(oppPlayer.pos); let oppDef = oppPlayer.oppDef; // select 'oppRoleId pos roleName head frame spine rankLv pLv defCe' -console.log('*******', oppDef) if (oppDef) delete oppDef.heroes; result.push({ @@ -393,19 +392,24 @@ export function getPlayerMainAttribute(heroAttrs: CeAttrData[], roleAttrs: CeAtt } // 获取我方战报记录 -export async function generMyRecInfo(heroScores: HeroScore[], winStreakNum: number, role: RoleType, isSuccess: boolean, pos: number, myHeroes: pvpEndParamInter[]) { - - let { roleId, roleName } = role; +export async function generMyRecInfo(pvpDefense: PvpDefenseType, role: RoleType, isSuccess: boolean, pos: number, myHeroes: pvpEndParamInter[]) { + let { attack, defense, heroScores, winStreakNum, score, hisScore } = pvpDefense; + let { roleId } = role; + if (isSuccess) { + winStreakNum ++; + } else { + winStreakNum = 0; + } const dicOpp = gameData.pvpOpponent.get(pos); const plusScore = getPlusScore(winStreakNum); let pLv = getLvByScore(heroScores); - // TODO 这里heroScore可以改为不改变原数据,而创建新数据的方式 - let myHeroRecords = new Array(); + let myHeroRecords: HeroesRecord[] = []; // 存入rec里面的数据 let showHeroScores = new Array<{ hid: number, addScore: number, plusScore: number, score: number }>(); let addSumScore = 0; - for (let { hid, damage, heal, underDamage } of myHeroes) { + for (let { actorId: hid } of attack.heroes) { + let params = myHeroes.find(cur => cur.hid == hid); let curHeroScore = heroScores.find(cur => cur.hid == hid); if (isSuccess) { if (!curHeroScore) { @@ -426,28 +430,35 @@ export async function generMyRecInfo(heroScores: HeroScore[], winStreakNum: numb }); } const myHero = await HeroModel.findByHidAndRole(hid, roleId, 'quality star colorStar lv skinId'); - let { quality, star, colorStar, lv, skinId } = myHero; - myHeroRecords.push({ - hid, quality, star, colorStar, lv, damage, heal, underDamage, skinId - }); + let record = new HeroesRecord(); + record.setByHero(myHero, params); + myHeroRecords.push(record); } - let attackInfo = { - roleId, - roleName, - lv: pLv, - head: role.head, - frame: role.frame, - spine: role.spine, - title: role.title, - ce: role.topLineupCe, - heroes: myHeroRecords, - isSuccess, - score: isSuccess ? addSumScore : 0 + let attackInfo = new PvpRecordPlayerInfo(); + attackInfo.setByRole(role, myHeroRecords, isSuccess, isSuccess ? addSumScore : 0, pLv) + + let newAttack = calLineupScore(attack, heroScores); + let newDefense = calLineupScore(defense, heroScores); + + let updateParam = { + winStreakNum, attack: newAttack, defense: newDefense, heroScores, score: score + addSumScore, hisScore: hisScore > score + addSumScore? hisScore: score + addSumScore } - return { attackInfo, showHeroScores, addSumScore, newHeroScore: heroScores } + return { attackInfo, showHeroScores, updateParam } +} + +function calLineupScore(lineup: Attack|Defense, heroScores: HeroScore[]) { + let score = 0; + for(let { actorId } of lineup.heroes) { + let hs = heroScores.find(cur => cur.hid == actorId); + if(hs) { + score += hs.score; + } + } + let pLv = getPLvByScore(score); + return {...lineup, score, pLv} } // 获取对手战报记录 @@ -455,26 +466,41 @@ export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayer, let oppHeroRecords = new Array(); let oppRole = curOpp.oppDef; if (!oppRole) { console.error('opp role not found') } - for (let { hid, damage, heal, underDamage } of oppHeroes) { - let historyHero = oppRole.heroes.find(cur => cur.actorId == hid); + + for (let params of oppHeroes) { + let historyHero = oppRole.heroes.find(cur => cur.actorId == params.hid); if (historyHero) { - let hs = new HeroesRecord(historyHero, damage, heal, underDamage); + let hs = new HeroesRecord(); + hs.setByPvpHeroInfo(historyHero, params); oppHeroRecords.push(hs); } } - return { - roleId: robotIdComBack(oppRole.oppRoleId), - roleName: oppRole.roleName, - lv: oppRole.pLv, - head: oppRole.head, - frame: oppRole.frame, - spine: oppRole.spine, - title: oppRole.title, - ce: oppRole.defCe, - heroes: oppHeroRecords, - isSuccess: !isSuccess, - score: 0 + let addSumScore = 0; + if(!curOpp.isRobot && !isSuccess) { + let pvpDefense = await PvpDefenseModel.findByRoleId(oppRole.roleId); + if(pvpDefense && pvpDefense.defense) { + let { attack, defense, heroScores, score } = pvpDefense; + for(let { actorId } of defense.heroes) { + let hs = heroScores.find(cur => cur.hid == actorId); + if(hs) { + hs.score += PVP.PVP_DEFENSE_SUCCESS_REWARD; + } else { + heroScores.push({ hid: actorId, score: PVP.PVP_DEFENSE_SUCCESS_REWARD }) + } + addSumScore += PVP.PVP_DEFENSE_SUCCESS_REWARD; + } + + let newAttack = calLineupScore(attack, heroScores); + let newDefense = calLineupScore(defense, heroScores); + + await PvpDefenseModel.updateInfo(oppRole.roleId, { attack: newAttack, defense: newDefense, heroScores, score: score + addSumScore }); + + } } + + let defenseInfo = new PvpRecordPlayerInfo(); + defenseInfo.setByHistoryOpp(oppRole, oppHeroRecords, !isSuccess, isSuccess ? 0 : addSumScore) + return defenseInfo } /** diff --git a/shared/db/PvpDefense.ts b/shared/db/PvpDefense.ts index e7646595b..720f41b1f 100644 --- a/shared/db/PvpDefense.ts +++ b/shared/db/PvpDefense.ts @@ -94,8 +94,8 @@ export default class PvpDefense extends BaseModel { } - public static async updateCe(roleId: string, hid: number, defCe: number, lean = true) { - const rec: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId, 'heroes.actorId': hid }, { $inc: { defCe } }).lean(lean); + public static async updateCe(roleId: string, hid: number, incCe: number, lean = true) { + const rec: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId, 'lineupCe.hid': hid }, { $inc: { ce: incCe } }).lean(lean); return rec } diff --git a/shared/db/PvpRecord.ts b/shared/db/PvpRecord.ts index b08de8190..1af75a61c 100644 --- a/shared/db/PvpRecord.ts +++ b/shared/db/PvpRecord.ts @@ -1,9 +1,13 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; import { getTimeFun } from '../pubUtils/timeUtil'; -import { genCode } from '../pubUtils/util'; +import { genCode, robotIdComBack } from '../pubUtils/util'; import { PvpHeroInfo } from '../domain/dbGeneral'; import { EXTERIOR } from '../pubUtils/dicParam'; +import { RoleType } from './Role'; +import { PvpHistoryOppType } from './PvpHistoryOpp'; +import { HeroType } from './Hero'; +import { pvpEndParamInter } from '../pubUtils/interface'; export class HeroesRecord { @prop({ required: true, default: 0 }) @@ -25,20 +29,34 @@ export class HeroesRecord { @prop({ required: true, default: 0 }) underDamage: number; // 承伤 - constructor(pvpHero: PvpHeroInfo, damage: number, heal: number, underDamage: number) { + setByPvpHeroInfo(pvpHero: PvpHeroInfo, params: pvpEndParamInter) { this.hid = pvpHero.actorId; this.skinId = pvpHero.skinId; this.quality = pvpHero.quality; this.star = pvpHero.star; this.colorStar = pvpHero.colorStar; this.lv = pvpHero.lv; - this.damage = damage; - this.heal = heal; - this.underDamage = underDamage; + this.setParams(params); + } + + setByHero(hero: HeroType, params: pvpEndParamInter) { + this.hid = hero.hid; + this.skinId = hero.skinId; + this.quality = hero.quality; + this.star = hero.star; + this.colorStar = hero.colorStar; + this.lv = hero.lv; + this.setParams(params); + } + + setParams(params: pvpEndParamInter) { + this.damage = params?.damage||0; + this.heal = params?.heal||0; + this.underDamage = params?.underDamage||0; } } -export class PlayerInfo { +export class PvpRecordPlayerInfo { @prop({ required: true }) roleId: string; // 角色 id @prop({ required: true }) @@ -61,6 +79,34 @@ export class PlayerInfo { score: number; // 获得的总积分 @prop({ required: true, type: HeroesRecord, default: [], _id: false }) heroes: HeroesRecord[]; // 获得的总积分 + + setByRole(role: RoleType, heroes: HeroesRecord[], isSuccess: boolean, score: number, lv: number ) { + this.roleId = role.roleId; + this.roleName = role.roleName; + this.head = role.head; + this.frame = role.frame; + this.spine = role.spine; + this.title = role.title; + this.ce = role.topLineupCe; + this.lv = lv; + this.isSuccess = isSuccess; + this.score = score; + this.heroes = heroes; + } + + setByHistoryOpp(oppRole: PvpHistoryOppType, oppHeroRecords: HeroesRecord[], isSuccess: boolean, score: number) { + this.roleId = robotIdComBack(oppRole.oppRoleId); + this.roleName = oppRole.roleName; + this.lv = oppRole.pLv; + this.head = oppRole.head; + this.frame = oppRole.frame; + this.spine = oppRole.spine; + this.title = oppRole.title; + this.ce = oppRole.defCe; + this.heroes = oppHeroRecords; + this.isSuccess = isSuccess; + this.score = score; + } } @index({ code: 1 }) @@ -77,15 +123,15 @@ export default class PvpRecord extends BaseModel { code: string; // code @prop({ required: true, default: 0 }) warId: number; // 这一关使用的地图 - @prop({ required: true, type: PlayerInfo, default: {}, _id: false }) - attackInfo: PlayerInfo; // 攻方信息 - @prop({ required: true, type: PlayerInfo, default: {}, _id: false }) - defenseInfo: PlayerInfo; // 守方信息 + @prop({ required: true, type: PvpRecordPlayerInfo, default: {}, _id: false }) + attackInfo: PvpRecordPlayerInfo; // 攻方信息 + @prop({ required: true, type: PvpRecordPlayerInfo, default: {}, _id: false }) + defenseInfo: PvpRecordPlayerInfo; // 守方信息 @prop({ required: true, default: 0 }) createTime: number; - public static async createRec(param: { roleId1: string, roleId2: string, warId: number, attackInfo: PlayerInfo, defenseInfo: PlayerInfo, createTime: number }) { + public static async createRec(param: { roleId1: string, roleId2: string, warId: number, attackInfo: PvpRecordPlayerInfo, defenseInfo: PvpRecordPlayerInfo, createTime: number }) { await this.delPvpRecords(); let code = genCode(6); const result = await PvpRecordModel.findOneAndUpdate({ code }, param, { new: true, upsert: true }).lean();