feat(副将): pvp相关副将设置

This commit is contained in:
luying
2023-07-18 20:28:35 +08:00
parent a726681d25
commit c6455de8e4
17 changed files with 157 additions and 44 deletions
@@ -275,7 +275,7 @@ export class LadderHandler {
}
// 9. 设置防守阵容
async saveDefense(msg: { warId: number, heroes: { actorId: number, ai: number, dataId: number, order: number }[] }, session: BackendSession) {
async saveDefense(msg: { warId: number, heroes: { actorId: number, ai: number, dataId: number, order: number, subHid?: number }[] }, session: BackendSession) {
let { warId, heroes } = msg;
let roleId = session.get('roleId');
@@ -284,6 +284,12 @@ export class LadderHandler {
let hids: number[] = heroes.map(cur => cur.actorId);
if(isHeroHidden(...hids)) return resResult(STATUS.HERO_IS_HIDDEN);
for(let { actorId, subHid } of heroes) {
let dicHero = gameData.hero.get(actorId);
if(!dicHero || dicHero.urType != 1) return resResult(STATUS.HERO_CAN_NOT_SET_SUB);
if(subHid && hids.indexOf(subHid) != -1) return resResult(STATUS.HERO_SUB_DUPLICATE);
}
let dbHeroes = await HeroModel.findByHidRange(hids, roleId, '_id hid ce', true);
let defenseHeroes = heroes.map(cur => {
@@ -449,7 +449,7 @@ export class PvpHandler {
}
//3. 保存防守阵容
async saveDefense(msg: { heroes: { actorId: number, dataId: number, order: number, ai: number }[], warId: number, buff: number }, session: BackendSession) {
async saveDefense(msg: { heroes: { actorId: number, dataId: number, order: number, ai: number, subHid?: 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) {
@@ -467,8 +467,11 @@ export class PvpHandler {
let refChallengeObj = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId, session.get('vipStartTime'));
// 更新防守阵容
let scores: number[] = [], heroIdMap = new Map<number, string>(), hids: number[] = [];
for(let { actorId } of heroes) {
for(let { actorId, subHid } of heroes) {
if(isHeroHidden(actorId)) return resResult(STATUS.HERO_IS_HIDDEN);
let dicHero = gameData.hero.get(actorId);
if(!dicHero || dicHero.urType != 1) return resResult(STATUS.HERO_CAN_NOT_SET_SUB);
if(subHid && heroes.findIndex(hero => hero.actorId == subHid) != -1) return resResult(STATUS.HERO_SUB_DUPLICATE);
let heroScore = pvpDefense.heroScores.find(cur => cur.hid == actorId);
if(heroScore) {
@@ -486,6 +489,7 @@ export class PvpHandler {
hids.push(actorId);
}
}
let dbHeroes = await HeroModel.findByHidRange(hids, roleId, '_id hid ce', true);
for(let hero of dbHeroes) {
heroIdMap.set(hero.hid, hero._id);
@@ -7,7 +7,7 @@ import { Application, BackendSession, ChannelService, HandlerService, pinus } fr
import { resResult, genCode, getRandSingleEelm } from "../../../pubUtils/util";
import { GVGLeagueModel } from '../../../db/GVGLeague';
import { getGroupKey, getGVGConfig, getGVGPeriodData, getGVGServerType } from '../../../services/gvg/gvgService';
import { redisAddBattleScore, battleEndSendMessage, calBattleScoreByCe, checkAreaIsInCity, checkGVGBattleStart, checkMoveStatus, getBattleRanksByCity, getBirthAreaOfCity, getGVGWarId, getOppHeroes, getTechKnifeHurt, getTechReviveMinus, initRobots, pushTeamMoveMessage, getAllGVGCitiesInfo, leaveCity, refreshTeams, checkEnterCityTime, generNewLineup, getBattleRank, checkSettleStatus, getSpineCnt, getPlayerRanksByCity, getPlayerSettleRanksByCity } from '../../../services/gvg/gvgBattleService';
import { redisAddBattleScore, battleEndSendMessage, calBattleScoreByCe, checkAreaIsInCity, checkGVGBattleStart, checkMoveStatus, getBattleRanksByCity, getBirthAreaOfCity, getGVGWarId, getOppHeroes, getTechKnifeHurt, getTechReviveMinus, initRobots, pushTeamMoveMessage, getAllGVGCitiesInfo, leaveCity, refreshTeams, checkEnterCityTime, generNewLineup, getBattleRank, checkSettleStatus, getSpineCnt, getPlayerRanksByCity, getPlayerSettleRanksByCity, checkGVGLineupWhenSave } from '../../../services/gvg/gvgBattleService';
import { getGVGBattleData } from '../../../services/memoryCache/gvgBattleData';
import { GVGBattleRecModel } from '../../../db/GVGBattleRec';
import { getFightTimeByPeriod } from '../../../services/gvg/gvgFightService';
@@ -69,6 +69,9 @@ export class GVGBattleHandler {
let { configId, period } = getGVGPeriodData();
if (period != GVG_PERIOD.BATTLE) return resResult(STATUS.GVG_NOT_BATTLE_PERIOD);
let checkLineupResult = await checkGVGLineupWhenSave(roleId, index, lineup);
if(checkLineupResult.code != 0) return resResult(checkLineupResult);
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
let { leagueCode, name: leagueName } = myLeague;
@@ -78,7 +81,12 @@ export class GVGBattleHandler {
let role = await RoleModel.findByRoleId(roleId, 'lv title');
let updateParam: SaveTeamUpdateParam = { index, head, spine, frame, roleName, serverId, leagueCode, leagueName, lv: role.lv, title: role.title }
if(lineup) {
let { isOK, heroes } = await checkBattleHeroesByHid(roleId, lineup.map(cur => cur.actorId));
let hids: number[] = [];
for(let { actorId, subHid } of lineup) {
hids.push(actorId);
if(subHid) hids.push(subHid);
}
let { isOK, heroes } = await checkBattleHeroesByHid(roleId, hids);
if(!isOK) return resResult(STATUS.BATTLE_HERO_NOT_FOUND);
let { newLineup, newLineupCe } = await generNewLineup(roleId, heroes, lineup);
updateParam.lineup = newLineup;
@@ -87,7 +87,7 @@ export class GVGProduceHandler {
}
// 编辑阵容
async saveLineup(msg: { vestigeId: number, lineup: [{ actorId: number, dataId: number, order: number, correspondingVar: number }] }, session: BackendSession) {
async saveLineup(msg: { vestigeId: number, lineup: [{ actorId: number, dataId: number, order: number, correspondingVar: number, subHid: number }] }, session: BackendSession) {
const roleId = session.get('roleId');
const serverId = session.get('serverId');
@@ -113,7 +113,7 @@ export class GVGProduceHandler {
let lineup = heroes.map(hero => {
let curHero = dbHeroes.find(cur => cur.hid == hero.actorId);
return { actorId: curHero.hid, dataId: hero.dataId, order: hero.order, correspondingVar: hero.correspondingVar, ce: curHero.ce }
return { actorId: curHero.hid, dataId: hero.dataId, order: hero.order, subHid: hero.subHid, correspondingVar: hero.correspondingVar, ce: curHero.ce }
});
let vestigeRank = await GVGVestigeRankModel.updateByRoleId(vestigeId, roleId, { lineup, hasDefense: true });
@@ -296,7 +296,7 @@ export class GVGProduceHandler {
}
// 布完阵开始挑战
async checkBattle(msg: { battleCode: string, heroes: [{ actorId: number, dataId: number, order: number }] }, session: BackendSession) {
async checkBattle(msg: { battleCode: string, heroes: { actorId: number, dataId: number, order: number, subHid: number }[] }, session: BackendSession) {
const roleId = session.get('roleId');
const roleName = session.get('roleName');
@@ -778,11 +778,11 @@ export class HeroHandler {
let subHero = await HeroModel.findByHidAndRole(subHid, roleId);
if(!subHero) return resResult(STATUS.HERO_NOT_FIND);
await LadderMatchModel.removeBySub(roleId, subHid);
await PvpSaveDataModel.removeBySub(roleId, subHid);
await PvpDefenseModel.removeBySub(roleId, subHid);
await GVGVestigeRankModel.removeBySub(roleId, subHid);
await GVGTeamModel.removeBySub(roleId, subHid, subHero.ce);
// await LadderMatchModel.removeBySub(roleId, subHid);
// await PvpSaveDataModel.removeBySub(roleId, subHid);
// await PvpDefenseModel.removeBySub(roleId, subHid);
// await GVGVestigeRankModel.removeBySub(roleId, subHid);
// await GVGTeamModel.removeBySub(roleId, subHid, subHero.ce);
} else { // 卸下
if(!hero.subHid) return resResult(STATUS.HERO_CAN_NOT_REMOVE_SUB);
@@ -30,6 +30,7 @@ import { ArtifactModel } from "../../db/Artifact";
import { getHeroesAttributes } from "../playerCeService";
import { CounterModel } from "../../db/Counter";
import { getGroupIdOfServer } from "../serverService";
import { LineupHero } from "../../domain/roleField/hero";
/**
* 获取本联军上周占领的城池
@@ -200,16 +201,18 @@ export async function refreshTeams(configId: number, groupKey: string, roleId: s
return teams
}
export async function generNewLineup(roleId: string, heroes: HeroType[], lineup: { actorId: number, dataId: number, order: number }[]) {
export async function generNewLineup(roleId: string, heroes: HeroType[], lineup: { actorId: number, dataId: number, order: number, subHid?: number }[]) {
let attrByHid = await getHeroesAttributes(roleId);
let newLineup: GVGHeroInfo[] = [], newLineupCe = 0;
for(let { actorId, dataId, order } of lineup) {
for(let { actorId, dataId, order, subHid } of lineup) {
let hero = heroes.find(cur => cur.hid == actorId);
if(hero) {
let artifact = hero.artifact? await ArtifactModel.findbySeqId(roleId, hero.artifact): null;
let heroInfo = new GVGHeroInfo();
heroInfo.setHeroInfo(hero, artifact, []);
heroInfo.setDataId(dataId, order);
let subHero = heroes.find(cur => cur.hid == subHid);
if(subHero) heroInfo.setSubHero(subHero);
let attr = attrByHid.get(actorId);
if(!attr) continue;
@@ -860,4 +863,36 @@ async function dispatchTeam(groupKey: string, cityId: number) {
let servers = pinus.app.getServersByType('guild');
let sid = (await dispatch(redisClient(), `${groupId}_${cityId}`, servers, 'guild'))?.id;
return sid;
}
/**
* 查询队伍中的武将是否可以使用
* @param roleId
* @param index
* @param lineup
* @returns
*/
export async function checkGVGLineupWhenSave(roleId: string, index: number, lineup: LineupHero[]) {
const teams = await GVGTeamModel.findByRole(roleId, '-_id index lineup');
for(let { actorId, subHid } of lineup) {
let dicHero = gameData.hero.get(actorId);
if(!dicHero || dicHero.urType != 1) return STATUS.HERO_CAN_NOT_SET_SUB;
for(let team of teams) {
// 查actorId没有在其他队伍中使用
if(team.index != index) {
let hasActor = team.lineup.find(hero => hero.actorId == actorId);
if(hasActor) return STATUS.GVG_TEAM_HERO_DUPLICATE;
}
// 查actorId没有在其他队伍作为副将
let hasActorIsSubHero = team.lineup.find(hero => hero.subHid == actorId);
if(hasActorIsSubHero) return STATUS.GVG_TEAM_HERO_USED_AS_SUB_HERO;
// 查副将
if(subHid) {
let hasSubHero = team.lineup.find(hero => hero.actorId == subHid);
if(hasSubHero) return STATUS.GVG_TEAM_SUB_HERO_DUPLICATE;
}
}
}
return STATUS.SUCCESS
}
@@ -156,10 +156,14 @@ export async function getVestigeUsedHeroes(roleId: string, curVestigeId: number)
}
// 是否在其他遗迹中使用过这个武将
export async function checkHeroIsUsedInOtherVestige(roleId: string, curVestigeId: number, heroes: { actorId: number }[]) {
export async function checkHeroIsUsedInOtherVestige(roleId: string, curVestigeId: number, heroes: { actorId: number, subHid: number }[]) {
let usedHeroes = await getVestigeUsedHeroes(roleId, curVestigeId);
for(let { actorId } of heroes) {
for(let { actorId, subHid } of heroes) {
if(usedHeroes.indexOf(actorId) != -1) return true;
// 查副将
if(subHid) {
if(usedHeroes.indexOf(subHid) != -1) return true;
}
}
return false;
}
@@ -251,7 +255,7 @@ export async function generateAttackInfo(roleId: string, league: GVGLeagueType,
return info;
}
export async function generateAttackHeroInfo(lineup: { actorId: number, dataId: number, order: number }[], dbHeroes: HeroType[]) {
export async function generateAttackHeroInfo(lineup: { actorId: number, dataId: number, order: number, subHid: number }[], dbHeroes: HeroType[]) {
let info = new OppPlayerInfo();
info.setPlayerHeroes(dbHeroes, lineup);
return info;
@@ -265,7 +269,11 @@ export async function getOppDetailData(rec: GVGVestigeRecType) {
const dicWar = gameData.war.get(dicLadderDifficultRatio.gkId);
const dicWarJson = gameData.warJson.get(dicWar.dispatchJsonId);
const defenseInfo = rec.defenseInfo.heroes||[];
const hids = defenseInfo.map(cur => cur.hid);
const hids: number[] = [];
for(let { hid, subHid } of defenseInfo) {
hids.push(hid);
if(subHid) hids.push(subHid);
}
const heroes = await HeroModel.findByHidRange(hids, rec.defenseRoleId, 'hid lv quality star colorStar skins ce skinId');
const artifactSeids = heroes.map(hero => hero.artifact);
const artifacts = await ArtifactModel.findbySeqIds(rec.defenseRoleId, artifactSeids);
@@ -299,7 +307,7 @@ export async function updateMyVestigeRank(isChange: boolean, atkData: GVGVestige
if(isChange) {
if(atkData && !atkData.hasDefense) { // 只有第一次挑战且自己没有主动保存过阵容的时候才会这么保存
let heroes = rec.attackInfo.heroes||[];
let lineup = heroes.map(hero => ({ actorId: hero.hid, dataId: hero.dataId, order: hero.order, ce: hero.ce }));
let lineup = heroes.map(hero => ({ actorId: hero.hid, dataId: hero.dataId, order: hero.order, ce: hero.ce, subHid: hero.subHid }));
update.lineup = lineup;
update.hasDefense = true;
needUpdate = true;
+14 -3
View File
@@ -1,6 +1,6 @@
import { ITEM_CHANGE_REASON, LADDER_OPP_STATUS, LADDER_SERVER_GAP_TIME, LADDER_STATUS, MAIL_TYPE, PUSH_ROUTE, REDIS_KEY, TA_USERSET_TYPE } from "../consts";
import { ArtifactModel } from "../db/Artifact";
import { HeroType } from "../db/Hero";
import { HeroModel, HeroType } from "../db/Hero";
import { LadderMatchModel, LadderMatchType, LadderUpdateInter } from "../db/LadderMatch";
import { LadderMatchRecModel, LadderMatchRecType } from "../db/LadderMatchRec";
import { RoleModel, RoleType } from "../db/Role";
@@ -270,6 +270,10 @@ export async function generateInitRecInfo(isRobot: boolean, isDefense: boolean,
let artifact = await ArtifactModel.findbySeqId(role.roleId, dbHero.artifact);
hero.setArtifact(artifact);
}
if(defenseHero.subHid) {
let subHero = await HeroModel.findByHidAndRole(defenseHero.subHid, role.roleId, 'hid skinId');
hero.setSubHero(subHero)
}
heroes.push(hero);
}
}
@@ -419,9 +423,16 @@ export async function getLadderOppDetailData(rec: LadderMatchRecType) {
let hisLadderData = await LadderMatchModel.findByRoleIdAndInclude(rec.roleId2);
let dicWar = gameData.war.get(dicLadderDifficultRatio.gkId);
let dicWarJson = gameData.warJson.get(dicWar.dispatchJsonId);
let artifactSeids = hisLadderData.defense.heroes.map(cur => (<HeroType>cur.hero).artifact);
let artifactSeids = [], subHids: number[] = [];
for(let { hero, subHid } of hisLadderData.defense.heroes) {
let dbHero = <HeroType>hero;
if(dbHero) artifactSeids.push(dbHero.artifact);
if(subHid) subHids.push(subHid);
}
let artifacts = await ArtifactModel.findbySeqIds(rec.roleId2, artifactSeids);
result.setByPlayer(hisLadderData, dicWarJson, artifacts);
let subHeroes = await HeroModel.findByHidRange(subHids, rec.roleId2, 'hid skinId');
result.setByPlayer(hisLadderData, dicWarJson, artifacts, subHeroes);
let attrByHid = await getHeroesAttributes(rec.roleId2);
for(let [hid, attribute] of attrByHid) {
result.setAttribute(hid, attribute.getAttributesToString());
+2 -1
View File
@@ -256,7 +256,8 @@ async function generPlayerOppHis(pvpdefense: PvpDefenseType, roleId: string, pos
let ce = attr.calCe();
if(isNaN(ce)) ce = 0;
heroInfo.setAttribute(attribute);
let enemy = new PvpEnemies(warJson, heroInfo, hs ? hs.score : 0, ce);
let subHero = h.subHid? dbHeroes.find(hero => hero.hid == h.subHid): null;
let enemy = new PvpEnemies(warJson, heroInfo, hs ? hs.score : 0, ce, subHero);
enemy.setOutIndex(h.order);
enemy.initial_ai = h.ai;
heroes.push(enemy);