diff --git a/game-server/app/servers/guild/handler/gvgBattleHandler.ts b/game-server/app/servers/guild/handler/gvgBattleHandler.ts index 5426ac737..1ec790b2a 100644 --- a/game-server/app/servers/guild/handler/gvgBattleHandler.ts +++ b/game-server/app/servers/guild/handler/gvgBattleHandler.ts @@ -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, checkGVGLineupWhenSave } 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, sendWinStreakMessage, getNewLineup, sendAreaPointChange } from '../../../services/gvg/gvgBattleService'; import { getGVGBattleData } from '../../../services/memoryCache/gvgBattleData'; import { GVGBattleRecModel } from '../../../db/GVGBattleRec'; import { getFightTimeByPeriod } from '../../../services/gvg/gvgFightService'; @@ -30,6 +30,7 @@ import { EXTERIOR, GVG } from '../../../pubUtils/dicParam'; import { sendMessageToGuildWithSuc, sendMessageToGVGAreaByTeamWithSuc, sendMessageToUserWithSuc } from '../../../services/pushService'; import { checkLeagueAuth } from '../../../services/gvg/gvgTeamService'; import { GVGLeaguePrepareModel } from '../../../db/GVGLeaguePrepare'; +import { gvgEndParamInter } from '../../../pubUtils/interface'; export default function (app: Application) { new HandlerService(app, {}); @@ -69,7 +70,7 @@ 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); + let checkLineupResult = await checkGVGLineupWhenSave(roleId, index, lineup||[]); if(checkLineupResult.code != 0) return resResult(checkLineupResult); let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode); @@ -307,11 +308,22 @@ export class GVGBattleHandler { result.push(new GVGTeamSpineInMap(team, serverNames)) } } - // 加入频道 + + return resResult(STATUS.SUCCESS, { cityId, spines: result }); + } + + // 加入频道 + async addAreaChannel(msg: { cityId: number, areaIds: number[] }, session: BackendSession) { + const roleId = session.get('roleId'); + const sid = session.get('sid'); + const serverId = session.get('serverId'); + const { areaIds } = msg; + let groupKey = await getGroupKey(serverId); + await leaveGVGAreaChannel(roleId, sid); await addRoleToAreaChannel(roleId, groupKey, areaIds, sid); - return resResult(STATUS.SUCCESS, { cityId, spines: result }); + return resResult(STATUS.SUCCESS); } // 点击自己的编队获取区域列表 @@ -431,10 +443,7 @@ export class GVGBattleHandler { teamObj.teamSettle(roleId, teamCode, pointId); // addTeamSettleRec(curTeam); - - await sendMessageToGVGAreaByTeamWithSuc(groupKey, curTeam.areaId, PUSH_ROUTE.GVG_AREA_POINT_CHANGE, { - cityId: curTeam.cityId, areaId: curTeam.areaId, targetPointId: pointId, originPointId: myTeam.pointId, point: new GVGTeamInListOnPoint(curTeam.pointId, true, curTeam) - }); + await sendAreaPointChange(groupKey, curTeam.areaId, curTeam.cityId, pointId, myTeam.pointId, curTeam); return resResult(STATUS.SUCCESS, { curTeam: new MyTeamInfo(curTeam) }); } @@ -463,9 +472,7 @@ export class GVGBattleHandler { let teamObj = getGVGBattleData(groupKey); teamObj.teamSettle(roleId, teamCode, 0); - await sendMessageToGVGAreaByTeamWithSuc(groupKey, curTeam.areaId, PUSH_ROUTE.GVG_AREA_POINT_CHANGE, { - cityId: curTeam.cityId, areaId: curTeam.areaId, targetPointId: pointId, originPointId: myTeam.pointId, point: new GVGTeamInListOnPoint(curTeam.pointId, true, curTeam) - }); + await sendAreaPointChange(groupKey, curTeam.areaId, curTeam.cityId, pointId, myTeam.pointId, curTeam); return resResult(STATUS.SUCCESS, { curTeam: new MyTeamInfo(curTeam) }); } @@ -504,9 +511,9 @@ export class GVGBattleHandler { } // 队伍停止攻击 - async battleEnd(msg: { cityId: number, battleCode: string, isSuccess: boolean }, session: BackendSession) { + async battleEnd(msg: { cityId: number, battleCode: string, isSuccess: boolean, myHeroes: gvgEndParamInter[], oppHeroes: gvgEndParamInter[] }, session: BackendSession) { const serverId = session.get('serverId'); - const { cityId, battleCode, isSuccess } = msg; + const { cityId, battleCode, isSuccess, myHeroes = [], oppHeroes = [] } = msg; let { configId, period } = getGVGPeriodData(); let { startFightTime, endFightTime } = getFightTimeByPeriod(period); @@ -526,8 +533,8 @@ export class GVGBattleHandler { // 计算并更新两支队伍耐久 let { win, fail } = gameData.gvgBattleDurabilityMinus; - attackTeam = await GVGTeamModel.battleEndAttack(attackTeam.teamCode, isSuccess? -win: -fail, getBirthAreaOfCity(city, attackTeam.leagueCode), await getTechReviveMinus(groupKey, configId, attackTeam.leagueCode)); - defenseTeam = await GVGTeamModel.battleEndDefense(defenseTeam.teamCode, isSuccess? -fail: -win, getBirthAreaOfCity(city, defenseTeam.leagueCode), GVG.GVG_DEFAULT_DEFENSE_CD, await getTechReviveMinus(groupKey, configId, defenseTeam.leagueCode)); + attackTeam = await GVGTeamModel.battleEndAttack(attackTeam.teamCode, isSuccess? -win: -fail, getBirthAreaOfCity(city, attackTeam.leagueCode), await getTechReviveMinus(groupKey, configId, attackTeam.leagueCode), getNewLineup(attackTeam, myHeroes)); + defenseTeam = await GVGTeamModel.battleEndDefense(defenseTeam.teamCode, isSuccess? -fail: -win, getBirthAreaOfCity(city, defenseTeam.leagueCode), GVG.GVG_DEFAULT_DEFENSE_CD, await getTechReviveMinus(groupKey, configId, defenseTeam.leagueCode), getNewLineup(defenseTeam, oppHeroes)); if(defenseTeam.curTeamBreak && defenseTeam.originPointId > 0 && !defenseTeam.isCatapult) { // 打败的对手原来占领着一个位置,现在这个位置是你的了 if(!attackTeam.curTeamBreak) { let settleResult = await GVGCityAreaPointModel.settlePoint(cityId, attackTeam.areaId, defenseTeam.originPointId, attackTeam, defenseTeam.isRobot? '': defenseTeam.teamCode); @@ -554,6 +561,8 @@ export class GVGBattleHandler { let rec = await GVGBattleRecModel.battleEnd(battleCode, isSuccess, attackTeam, defenseTeam); await battleEndSendMessage(groupKey, cityId, defenseTeam, {...attackTeam, originPointId: attackOriginId}, GVG_ATTACK_TYPE.PLAYER); addBattleEndRec(rec); + // 连胜邮件 + sendWinStreakMessage(groupKey, cityId, attackTeam, defenseTeam, isSuccess); return resResult(STATUS.SUCCESS, { curTeam: new MyTeamInfo(attackTeam), oppTeam: new MyTeamInfo(defenseTeam) }); } @@ -821,6 +830,16 @@ export class GVGBattleHandler { }) } + // 获取我的编队信息 + async getOppTeam(msg: { cityId: number, teamCode: string }, session: BackendSession) { + let { teamCode } = msg; + const team = await GVGTeamModel.findByCode(teamCode) + if (!team) return resResult(STATUS.GVG_TEAM_NOT_FOUND); + const warId = getGVGWarId(team); + + return resResult(STATUS.SUCCESS, { warId, oppTeam: new MyTeamInfo(team) }); + } + async debugStartSchedule() { let { countdownTime } = getGVGPeriodData(); pinus.app.rpc.guild.guildRemote.setPeriodTime.broadcast(nowSeconds(), countdownTime); @@ -845,7 +864,7 @@ export class GVGBattleHandler { const areaIds = gameData.gvgCity.get(cityId)?.areaIds||[]; for(let i = 0; i < teamCnt; i++) { let areaId = getRandSingleEelm(areaIds); - teams.push({ configId, groupKey, roleId: 'test', roleName: 'test' + i, serverId, lv: 100, teamCode: genCode(8), index: 3, leagueCode: 'test', leagueName: 'test' + i, guildCode: 'test', areaId, cityId, pointId: 0, head: EXTERIOR.EXTERIOR_FACE, frame: EXTERIOR.EXTERIOR_FACECASE, spine: EXTERIOR.EXTERIOR_APPEARANCE, durability: 100, maxDurability: 100, restartTime: nowSeconds(), attackTime: nowSeconds(), lockTime: nowSeconds(), startMoveTime: nowSeconds(), stopMoveTime: nowSeconds(), moveCdTime: nowSeconds(), defenseTime: nowSeconds(), lineupCe: 100000 }) + teams.push({ configId, confirmConfigId: configId, title: 1, groupKey, roleId: 'test', roleName: 'test' + i, serverId, lv: 100, teamCode: genCode(8), index: 3, leagueCode: 'test', leagueName: 'test' + i, guildCode: 'test', areaId, cityId, pointId: 0, head: EXTERIOR.EXTERIOR_FACE, frame: EXTERIOR.EXTERIOR_FACECASE, spine: EXTERIOR.EXTERIOR_APPEARANCE, durability: 100, maxDurability: 100, restartTime: nowSeconds(), attackTime: nowSeconds(), lockTime: nowSeconds(), startMoveTime: nowSeconds(), stopMoveTime: nowSeconds(), moveCdTime: nowSeconds(), defenseTime: nowSeconds(), lineupCe: 100000 }) } await GVGTeamModel.insertMany(teams); teamObj.enterCity(...teams); diff --git a/game-server/app/services/checkParam.ts b/game-server/app/services/checkParam.ts index 5a67faadc..f27e4f19e 100644 --- a/game-server/app/services/checkParam.ts +++ b/game-server/app/services/checkParam.ts @@ -1,6 +1,6 @@ import { isArray, isBoolean, isNumber, isString } from "underscore"; import { BLOCK_OPEATE, DEBUG_MAGIC_WORD, GM_MAIL_TYPE, GUILD_AUTH, GUILD_STRUCTURE, GVG_RESOURCE_TYPE, GVG_SEED_TYPE, LEAGUE_JOB, LINEUP_NUM, MSG_TYPE } from "../consts"; -import { pvpEndParamInter } from "../pubUtils/interface"; +import { gvgEndParamInter, pvpEndParamInter } from "../pubUtils/interface"; import { isDevelopEnv } from "./utilService"; export function checkRouteParam(route: string, msg: any) { @@ -1779,6 +1779,8 @@ export function checkRouteParam(route: string, msg: any) { { if (!checkNaturalStrings(msg.battleCode)) return false; if (!checkBoolean(msg.isSuccess)) return false; + if (!checkGvgEndHeroFormat(msg.myHeroes)) return false; + if (!checkGvgEndHeroFormat(msg.oppHeroes)) return false; break; } case "guild.gvgBattleHandler.useItem": @@ -1818,6 +1820,12 @@ export function checkRouteParam(route: string, msg: any) { if (!checkStringIfExist(msg.notice)) return false; break; } + case "guild.gvgBattleHandler.getOppTeam": + { + if (!checkNaturalNumbers(msg.cityId)) return false; + if (!checkNaturalStrings(msg.teamCode)) return false; + break; + } case "order.orderHandler.applyOrder": { let { productID, payType, activityId, paramStr, useVoucher } = msg; @@ -2619,6 +2627,17 @@ function checkPvpEndHeroFormat(...params: pvpEndParamInter[][]) { return true; } +function checkGvgEndHeroFormat(...params: gvgEndParamInter[][]) { + for (let param of params) { + if (!checkArrayCanEmpty(param)) return false; + for (let { actorId, hp, others } of param) { + if (!checkNaturalNumbers(actorId, hp)) return false; + if (!checkStringIfExist(others)) return false; + } + } + return true; +} + function checkIsInEnum(someEnum: T, value: T) { return Object.values(someEnum).includes(value) } diff --git a/game-server/app/services/gvg/gvgBattleService.ts b/game-server/app/services/gvg/gvgBattleService.ts index 1f5a51204..b06f50b8c 100644 --- a/game-server/app/services/gvg/gvgBattleService.ts +++ b/game-server/app/services/gvg/gvgBattleService.ts @@ -7,7 +7,7 @@ import { COUNTER, GVG_AREA_TYPE, GVG_ATTACK_TYPE, GVG_BATTLE_RANK_TYPE, GVG_PERI import { getTimeFun, nowSeconds } from "../../pubUtils/timeUtil"; import { DicGVGAreaPoint } from "../../pubUtils/dictionary/DicGVGAreaPoint"; import { getGVGBattleData, getGVGBattleMap } from "../memoryCache/gvgBattleData"; -import { GVGAttackSpine, GVGCityMapInfo, GVGTeamInList, GVGTeamInListOnPoint, GVGTeamSpineInMap } from "../../domain/gvgField/returnData"; +import { GVGAttackSpine, GVGCityMapInfo, GVGEnemies, GVGTeamInList, GVGTeamInListOnPoint, GVGTeamSpineInMap, GVGTeamSpineInfo, GVGWinStreakInfo } from "../../domain/gvgField/returnData"; import { GVG } from "../../pubUtils/dicParam"; import { GVGHeroInfo, PvpEnemies, PvpHeroInfo } from "../../domain/dbGeneral"; import { getGroupKey, getGVGConfig, getGVGConfigFromRemote, getGVGPeriodData, getGVGServerType } from "./gvgService"; @@ -16,7 +16,7 @@ import { pinus } from "pinus"; import { dispatch } from "../../pubUtils/dispatcher"; import { Rank } from "../rankService"; import { KeyNameParam, LeagueRankInfo, myIdInter, RoleRankInfo } from "../../domain/rank"; -import { findKeys, getAllServerName, redisClient } from "../redisService"; +import { findKeys, getAllServerName, getServerName, redisClient } from "../redisService"; import { sendMessageToGVGAreaByTeamWithSuc, sendMessageToGVGAreaWithSuc, sendMessageToGVGCityWithSuc, sendMessageToUserWithSuc } from "../pushService"; import { sendMailByContent, sendMailToLeagueByContent } from "../mailService"; import { GVGCityAreaPointModel } from "../../db/GVGCityAreaPoint"; @@ -24,13 +24,14 @@ import { addCityGuardMessage } from "./gvgRecService"; import { GVGUserDataModel } from "../../db/GVGUserData"; import { RoleModel } from "../../db/Role"; import { getFightTimeByPeriod } from "./gvgFightService"; -import { getRandSingleEelm } from "../../pubUtils/util"; +import { getRandSingleEelm, parseNumberList } from "../../pubUtils/util"; import { HeroModel, HeroType } from "../../db/Hero"; import { ArtifactModel } from "../../db/Artifact"; import { getHeroesAttributes } from "../playerCeService"; import { CounterModel } from "../../db/Counter"; import { getGroupIdOfServer } from "../serverService"; import { LineupHero } from "../../domain/roleField/hero"; +import { gvgEndParamInter } from "../../pubUtils/interface"; /** * 获取本联军上周占领的城池 @@ -253,9 +254,7 @@ export async function leaveCity(isForce: boolean, roleId: string, serverId: numb await pinus.app.rpc.guild.guildRemote.leaveCityMem.broadcast(groupKey, roleId); for(let team of teams) { if(team.cityId > 0 && team.areaId > 0) { - await sendMessageToGVGAreaByTeamWithSuc(groupKey, team.areaId, PUSH_ROUTE.GVG_PLAYER_LEAVE_AREA, { - cityId: team.cityId, areaId: team.areaId, teamCode: team.teamCode - }); + await sendAreaLeaveMsg(groupKey, team.areaId, team.cityId, team.teamCode); } } } @@ -310,7 +309,7 @@ export function getGVGWarId(defenseTeam: GVGTeamType) { // guild.gvgBattleHandler.battleStart 里的heroes返回 export function getOppHeroes(warId: number, isRobot: boolean, lineup: GVGHeroInfo[]) { - let heroes: PvpEnemies[] = []; + let heroes: GVGEnemies[] = []; const dicWar = gameData.war.get(warId); if(!dicWar) { console.error(`warId ${warId} not found`); return [] } const dicWarJson = gameData.warJson.get(dicWar.dispatchJsonId)||[]; @@ -318,15 +317,15 @@ export function getOppHeroes(warId: number, isRobot: boolean, lineup: GVGHeroInf if(!isRobot) { let heroInfo = lineup.find(cur => cur.dataId == warJson.dataId); if(!heroInfo) continue; - let hero = new PvpEnemies(warJson, heroInfo); + let hero = new GVGEnemies(warJson, heroInfo); heroes.push(hero); } else { if(warJson.relation == 2) { let dicHero = gameData.hero.get(warJson.actorId); if(!dicHero) continue; - let heroInfo = new PvpHeroInfo(); + let heroInfo = new GVGHeroInfo(); heroInfo.setRobotInfo(dicHero, warJson.lv); - let hero = new PvpEnemies(warJson, heroInfo); + let hero = new GVGEnemies(warJson, heroInfo); heroes.push(hero); } } @@ -354,6 +353,38 @@ export function checkGVGBattleStart(roleId: string, attackTeam: GVGTeamType, def return STATUS.SUCCESS; } +export function getNewLineup(team: GVGTeamType, newInfo: gvgEndParamInter[]) { + if (team.isRobot) return { isAllDead: false, newLineup: team.lineup}; + let isAllDead = team.curTeamBreak || checkAllDead(team.lineup, newInfo); + let newLineup: GVGHeroInfo[] = []; + for(let hero of team.lineup) { + if (isAllDead) { + hero.hp = "max"; + hero.maxHp = "max"; + hero.others = ''; + } else { + let info = newInfo.find(cur => cur.actorId == hero.actorId); + if (info) { + hero.hp = info.hp; + hero.maxHp = info.maxHp; + hero.others = info.others; + } + } + + newLineup.push(hero); + } + return { isAllDead, newLineup }; +} + +// 检查本场战斗武将是否死光了 +export function checkAllDead(oldLineup: GVGHeroInfo[], newInfo: gvgEndParamInter[]) { + for(let hero of oldLineup) { + let curInfo = newInfo.find(cur => cur.actorId == hero.actorId); + if (!curInfo || curInfo.hp > 0) return false; + } + return true; +} + // —————————— 定时器相关 —————————— // // gvg激战期开始定时器 export async function gvgBattleStart() { @@ -553,9 +584,9 @@ export async function getPlayerRanksByCity(configId: number, groupKey: string, c export async function gvgBattleSeconds() { const { configId, period } = getGVGPeriodData(); let { startFightTime, endFightTime } = getFightTimeByPeriod(period); - const serverNames = await getAllServerName(); + // const serverNames = await getAllServerName(); - let spineCnt = await getSpineCnt(); + // let spineCnt = await getSpineCnt(); let keys: { groupKey: string, cityId: number }[] = [] for(let [_key, teamObj] of getGVGBattleMap()) { // console.log('#### gvgBattleSeconds groupKey: ', _key, 'areas', teamObj.findAreas(), 'appid', pinus.app.getServerId()); @@ -571,19 +602,19 @@ export async function gvgBattleSeconds() { } // 向下推送区域数据 - let spinesByCity = new Map(); + // let spinesByCity = new Map(); for(let areaId of teamObj.findAreas()) { let dicArea = gameData.gvgArea.get(areaId); - let teams = teamObj.findTeamsByArea(areaId, spineCnt); - let spines = teams.map(team => new GVGTeamSpineInMap(team, serverNames)); - if(!spinesByCity.has(dicArea.cityId)) spinesByCity.set(dicArea.cityId, []); - spinesByCity.get(dicArea.cityId).push(...spines); + // let teams = teamObj.findTeamsByArea(areaId, spineCnt); + // let spines = teams.map(team => new GVGTeamSpineInMap(team, serverNames)); + // if(!spinesByCity.has(dicArea.cityId)) spinesByCity.set(dicArea.cityId, []); + // spinesByCity.get(dicArea.cityId).push(...spines); let index = keys.findIndex(cur => cur.cityId == dicArea.cityId && cur.groupKey == teamObj.groupKey); if(index == -1) keys.push({ groupKey: teamObj.groupKey, cityId: dicArea.cityId }); } - for(let [cityId, spines] of spinesByCity) { - if(spines.length > 0) await sendMessageToGVGCityWithSuc(teamObj.groupKey, cityId, PUSH_ROUTE.GVG_AREA_SPINE_CHANGE, { cityId, spines }); - } + // for(let [cityId, spines] of spinesByCity) { + // if(spines.length > 0) await sendMessageToGVGCityWithSuc(teamObj.groupKey, cityId, PUSH_ROUTE.GVG_AREA_SPINE_CHANGE, { cityId, spines }); + // } } @@ -768,23 +799,39 @@ export async function battleEndSendMessage(groupKey: string, cityId: number, def }); if(!defenseTeam.isRobot) { await sendMessageToUserWithSuc(defenseTeam.roleId, PUSH_ROUTE.GVG_MY_TEAM_ATTACKED, { - cityId, areaId, attackType, teams: [new GVGTeamInList(defenseTeam)] + cityId, areaId, attackType, teams: [new GVGTeamInList(defenseTeam, true)] }); } await pushTeamBeHurtMessage(defenseTeam, attackTeam); await pushTeamBeHurtMessage(attackTeam); } +export async function sendWinStreakMessage(groupKey: string, cityId: number, attackTeam: GVGTeamType, defenseTeam: GVGTeamType, isSuccess: boolean) { + if (attackTeam && !attackTeam.isRobot) { + let result = await GVGUserDataModel.setWinStreak(attackTeam.configId, attackTeam.leagueCode, attackTeam.roleId, isSuccess); + if (needSendMsg(result.winStreak)) { + await sendMessageToGVGCityWithSuc(groupKey, cityId, PUSH_ROUTE.GVG_WIN_STREAK, new GVGWinStreakInfo(attackTeam, result.winStreak)); + } + } + if (defenseTeam && !defenseTeam.isRobot) { + let result = await GVGUserDataModel.setWinStreak(defenseTeam.configId, defenseTeam.leagueCode, defenseTeam.roleId, !isSuccess); + if (needSendMsg(result.winStreak)) { + await sendMessageToGVGCityWithSuc(groupKey, cityId, PUSH_ROUTE.GVG_WIN_STREAK, new GVGWinStreakInfo(defenseTeam, result.winStreak)); + } + } +} + +function needSendMsg(winStreak: number) { + let arr = parseNumberList(GVG.WIN_STREAK_REPORT_LIMIT); + return arr.includes(winStreak); +} + // 队伍移动 export async function pushTeamBeHurtMessage(team: GVGTeamType, replaceTeam?: GVGTeamType) { if(team.curTeamBreak && team.originPointId > 0) { - await sendMessageToGVGAreaByTeamWithSuc(team.groupKey, team.fromAreaId, PUSH_ROUTE.GVG_AREA_POINT_CHANGE, { - cityId: team.cityId, areaId: team.fromAreaId, targetPointId: team.originPointId, originPointId: replaceTeam?.originPointId??0, point: new GVGTeamInListOnPoint(replaceTeam?.pointId||team.pointId, true, replaceTeam||team) - }); + await sendAreaPointChange(team.groupKey, team.fromAreaId, team.cityId, team.originPointId, replaceTeam?.originPointId??0, replaceTeam||team); if(replaceTeam && !replaceTeam.curTeamBreak && replaceTeam.originPointId > 0) { - await sendMessageToGVGAreaByTeamWithSuc(replaceTeam.groupKey, replaceTeam.fromAreaId, PUSH_ROUTE.GVG_AREA_POINT_CHANGE, { - cityId: replaceTeam.cityId, areaId: replaceTeam.fromAreaId, targetPointId: replaceTeam.originPointId, originPointId: 0, point: new GVGTeamInListOnPoint(replaceTeam.pointId, true, replaceTeam) - }); + await sendAreaPointChange(replaceTeam.groupKey, replaceTeam.fromAreaId, replaceTeam.cityId, replaceTeam.originPointId, 0, replaceTeam); } } @@ -792,28 +839,45 @@ export async function pushTeamBeHurtMessage(team: GVGTeamType, replaceTeam?: GVG await pushTeamMoveMessage(team); } if(team.isRobot && team.isBroken) { - await sendMessageToGVGAreaByTeamWithSuc(team.groupKey, team.fromAreaId, PUSH_ROUTE.GVG_PLAYER_LEAVE_AREA, { - cityId: team.cityId, areaId: team.fromAreaId, teamCode: team.teamCode - }); + await sendAreaLeaveMsg(team.groupKey, team.fromAreaId, team.cityId, team.teamCode); } } export async function pushTeamMoveMessage(team: GVGTeamType) { if(team.fromAreaId != team.areaId) { - if(team.fromAreaId > 0) { - await sendMessageToGVGAreaByTeamWithSuc(team.groupKey, team.fromAreaId, PUSH_ROUTE.GVG_PLAYER_LEAVE_AREA, { - cityId: team.cityId, areaId: team.fromAreaId, teamCode: team.teamCode - }); - } - if(team.areaId > 0) { - await sendMessageToGVGAreaByTeamWithSuc(team.groupKey, team.areaId, PUSH_ROUTE.GVG_PLAYER_AREA_ADD, { - cityId: team.cityId, areaId: team.areaId, fromAreaId: team.fromAreaId, player: new GVGTeamInList(team) - }); - } + if(team.fromAreaId > 0) await sendAreaLeaveMsg(team.groupKey, team.fromAreaId, team.cityId, team.teamCode); + if(team.areaId > 0) await sendAreaAddMsg(team.groupKey, team.areaId, team.fromAreaId, team.cityId, team); } } // —————————— 推送相关 end —————————— // +export async function sendAreaLeaveMsg(groupKey: string, areaId: number, cityId: number, teamCode: string) { + await sendMessageToGVGAreaByTeamWithSuc(groupKey, areaId, PUSH_ROUTE.GVG_PLAYER_LEAVE_AREA, { + cityId, areaId, teamCode + }); + await sendMessageToGVGAreaWithSuc(groupKey, areaId, PUSH_ROUTE.GVG_SPINE_AREA_LEAVE, { + cityId, areaId, teamCode + }); +} + +export async function sendAreaAddMsg(groupKey: string, areaId: number, fromAreaId: number, cityId: number, team: GVGTeamType) { + await sendMessageToGVGAreaByTeamWithSuc(groupKey, areaId, PUSH_ROUTE.GVG_PLAYER_AREA_ADD, { + cityId, areaId, fromAreaId, player: new GVGTeamInList(team) + }); + await sendMessageToGVGAreaWithSuc(groupKey, areaId, PUSH_ROUTE.GVG_SPINE_AREA_ADD, { + cityId, areaId, fromAreaId, spine: new GVGTeamSpineInfo(team, await getServerName(team.serverId)) + }); +} + +export async function sendAreaPointChange(groupKey: string, areaId: number, cityId: number, targetPointId: number, originPointId: number, team: GVGTeamType) { + await sendMessageToGVGAreaByTeamWithSuc(groupKey, areaId, PUSH_ROUTE.GVG_AREA_POINT_CHANGE, { + cityId, areaId, targetPointId, originPointId, point: new GVGTeamInListOnPoint(team.pointId, true, team) + }); + await sendMessageToGVGAreaWithSuc(groupKey, areaId, PUSH_ROUTE.GVG_SPINE_POINT_CHANGE, { + cityId, areaId, targetPointId, originPointId, spine: new GVGTeamSpineInfo(team, await getServerName(team.serverId)) + }) +} + // 外面页面上的排行榜 export async function getBattleRank(redisKey: REDIS_KEY, keyParam: KeyNameParam, myId: myIdInter) { let r = new Rank(redisKey, keyParam); diff --git a/game-server/app/services/gvg/gvgFightService.ts b/game-server/app/services/gvg/gvgFightService.ts index c0c0135e5..8d0dc9f65 100644 --- a/game-server/app/services/gvg/gvgFightService.ts +++ b/game-server/app/services/gvg/gvgFightService.ts @@ -20,7 +20,7 @@ import { KeyNameParam, LeagueRankInfo, myIdInter, RoleRankInfo } from "../../dom import { gameData, getGVGVestigeLeagueRank, getGVGVestigePlayerRank, getGVGVestigeRange } from "../../pubUtils/data"; import { GVG } from "../../pubUtils/dicParam"; import { RewardInter } from "../../pubUtils/interface"; -import { getTimeFun, nowSeconds } from "../../pubUtils/timeUtil"; +import { getCurDay, getTimeFun, nowSeconds } from "../../pubUtils/timeUtil"; import { getRandEelm } from "../../pubUtils/util"; import { getNumberArr, uniqueArr } from "../ladderService"; import { sendMailByContent } from "../mailService"; @@ -77,8 +77,11 @@ export async function getVestiges(serverId: number) { let vestige = await GVGVestigeModel.getVestige(groupKey); if(!vestige) { let dicGVGVestige = gameData.gvgVestigeByServerType.get(serverType)||[]; + let day = getCurDay(true); + let pool = dicGVGVestige.filter(cur => cur.openday.includes(day)); + let cnt = gameData.gvgVestigeCntByServerType.get(serverType)||0; - let randResult = getRandEelm(dicGVGVestige, cnt); + let randResult = getRandEelm(pool, cnt); vestige = await GVGVestigeModel.initTodayVestige(groupKey, randResult); } return vestige.vestiges||[]; diff --git a/game-server/app/services/pushService.ts b/game-server/app/services/pushService.ts index 09d8a075a..b685dff88 100644 --- a/game-server/app/services/pushService.ts +++ b/game-server/app/services/pushService.ts @@ -10,9 +10,7 @@ import { isDevelopEnv } from "./utilService"; import { gameData } from "../pubUtils/data"; import { pushMsg37 } from "./sdkService"; import { RoleModel, RoleType } from "../db/Role"; -import { nowSeconds } from "../pubUtils/timeUtil"; import { GVGLeagueModel } from "../db/GVGLeague"; -import { resolve } from "bluebird"; export async function sendMessageToAllWithSuc(route: string, data: any, filterCb?: ({ lv, topLineupCe }) => boolean) { await sendMessageToAll(route, resResult(STATUS.SUCCESS, data), filterCb); @@ -262,12 +260,15 @@ function checkNotEncryptRoute(event: string) { PUSH_ROUTE.GUILD_BOSS_ENCOURAGE, // onGuildBossEncourage 鼓舞 PUSH_ROUTE.GVG_TEAM_ATTACKED, // onTeamAttacked 当队伍受到攻击 PUSH_ROUTE.GVG_MY_TEAM_ATTACKED, // onMyTeamAttacked 当队伍受到攻击 - PUSH_ROUTE.GVG_AREA_SPINE_CHANGE, // onAreaSpinesChange 可见区域内spine的变动,每隔5秒会下发 + // PUSH_ROUTE.GVG_AREA_SPINE_CHANGE, // onAreaSpinesChange 可见区域内spine的变动,每隔5秒会下发 PUSH_ROUTE.GVG_AREA_POINT_CHANGE, // onMyAreaPointChange 积分点上的驻守人变更 PUSH_ROUTE.GVG_PLAYER_AREA_ADD, // onPlayerAddToArea 积分点上的驻守人变更 PUSH_ROUTE.GVG_PLAYER_LEAVE_AREA, // onPlayerLeaveArea 积分点上的驻守人变更 PUSH_ROUTE.GVG_CITY_RANK_UPDATE, // onGVGCityRankUpdate 城池积分排名 PUSH_ROUTE.GVG_SPINE_ATTACKED, // onSpinesAttacked 队伍在地图上受到攻击 + PUSH_ROUTE.GVG_SPINE_AREA_ADD, + PUSH_ROUTE.GVG_SPINE_AREA_LEAVE, + PUSH_ROUTE.GVG_SPINE_POINT_CHANGE, ].indexOf(event) != -1 } diff --git a/game-server/app/util/routeUtil.ts b/game-server/app/util/routeUtil.ts index f9a329fbb..dde731f72 100644 --- a/game-server/app/util/routeUtil.ts +++ b/game-server/app/util/routeUtil.ts @@ -128,6 +128,7 @@ export async function guild(session: Session, msg: any, app: Application, cb: (e 'guild.gvgBattleHandler.leaveCity', 'guild.gvgBattleHandler.getRankByCity', 'guild.gvgBattleHandler.getAreaOfMyTeam', + 'guild.gvgBattleHandler.getOppTeam', 'guild.gvgBattleHandler.debugAddRobots', 'guild.gvgBattleHandler.debugMoveRobots', 'guild.gvgBattleHandler.debugStopMoveRobot', diff --git a/shared/consts/constModules/chatConst.ts b/shared/consts/constModules/chatConst.ts index d59b52b61..9446f6ce7 100644 --- a/shared/consts/constModules/chatConst.ts +++ b/shared/consts/constModules/chatConst.ts @@ -201,7 +201,7 @@ export const PUSH_ROUTE = { GVG_TASK_UPDATE: 'onGVGTaskUpdate', // GVG任务更新 GVG_TEAM_ATTACKED: 'onTeamAttacked', // 当队伍受到攻击 GVG_MY_TEAM_ATTACKED: 'onMyTeamAttacked', // 当队伍受到攻击 - GVG_AREA_SPINE_CHANGE: 'onAreaSpinesChange', // 可见区域内spine的变动,每隔5秒会下发 + // GVG_AREA_SPINE_CHANGE: 'onAreaSpinesChange', // 可见区域内spine的变动,每隔5秒会下发 GVG_AREA_POINT_CHANGE: 'onMyAreaPointChange', // 积分点上的驻守人变更 GVG_PLAYER_AREA_ADD: 'onPlayerAddToArea', // 积分点上的驻守人变更 GVG_PLAYER_LEAVE_AREA: 'onPlayerLeaveArea', // 积分点上的驻守人变更 @@ -216,4 +216,8 @@ export const PUSH_ROUTE = { ROUGE_CHALLENGE_UPDATE: 'onRougeChallengeUpdate', //更新学宫挑战进度 ROUGE_PASSIVE_CARD_UP_LV:'onRougePassiveCardUpLv', // 升级特性卡 LADDER_OR_GVG_ICON_SHOW: 'onLadderOrGvgIconShow', //名将擂台icon提示 + GVG_WIN_STREAK: 'onGVGWinStreak', // 连胜次数 + GVG_SPINE_AREA_ADD: 'onSpineAddArea', // 积分点上的驻守人变更 + GVG_SPINE_AREA_LEAVE: 'onSpineLeaveArea', // 积分点上的驻守人变更 + GVG_SPINE_POINT_CHANGE: 'onSpinePointChange', // 积分点上的驻守人变更 } \ No newline at end of file diff --git a/shared/db/GVGTeam.ts b/shared/db/GVGTeam.ts index 3b5b0db70..763bd484f 100644 --- a/shared/db/GVGTeam.ts +++ b/shared/db/GVGTeam.ts @@ -273,31 +273,51 @@ export default class GVGTeam extends BaseModel { } // 结算挑战方 - public static async battleEndAttack(teamCode: string, hpInc: number, rebirthAreaId: number, reviveCd: number) { - let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $inc: { durability: hpInc }, $set: { lockTime: 0, lockTeamCode: '' } }, { new: true }).lean(); + public static async battleEndAttack(teamCode: string, hpInc: number, rebirthAreaId: number, reviveCd: number, lineupParam?: { isAllDead: boolean, newLineup: GVGHeroInfo[] }) { + let team: GVGTeamType; + if (lineupParam) { + if (lineupParam.isAllDead) { + team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { durability: 0, lockTime: 0, lockTeamCode: '', lineup: lineupParam.newLineup } }, { new: true }).lean(); + } else { + team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $inc: { durability: hpInc }, $set: { lockTime: 0, lockTeamCode: '', lineup: lineupParam.newLineup } }, { new: true }).lean(); + } + } else { + team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $inc: { durability: hpInc }, $set: { lockTime: 0, lockTeamCode: '' } }, { new: true }).lean(); + } if(team.durability <= 0) { let originPointId = team.pointId; - team = await GVGTeamModel.teamBreak(teamCode, team.isRobot, team.maxDurability, rebirthAreaId, team.areaId, reviveCd); + team = await GVGTeamModel.teamBreak(teamCode, team.isRobot, team.maxDurability, rebirthAreaId, team.areaId, reviveCd, team.lineup); team.originPointId = originPointId; } return team; } // 结算防守方 - public static async battleEndDefense(teamCode: string, hpInc: number, rebirthAreaId: number, defenseCd: number, reviveCd: number) { - let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + defenseCd, lockTime: 0, lockTeamCode: '' }, $inc: { durability: hpInc } }, { new: true }).lean(); + public static async battleEndDefense(teamCode: string, hpInc: number, rebirthAreaId: number, defenseCd: number, reviveCd: number, lineupParam?: { isAllDead: boolean, newLineup: GVGHeroInfo[] }) { + let team: GVGTeamType; + if (lineupParam) { + if (lineupParam.isAllDead) { + team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + defenseCd, lockTime: 0, lockTeamCode: '', lineup: lineupParam.newLineup, durability: 0 } }, { new: true }).lean(); + } else { + team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + defenseCd, lockTime: 0, lockTeamCode: '', lineup: lineupParam.newLineup }, $inc: { durability: hpInc } }, { new: true }).lean(); + } + } else { + team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + defenseCd, lockTime: 0, lockTeamCode: '' }, $inc: { durability: hpInc } }, { new: true }).lean(); + } + if(team.durability <= 0) { let originPointId = team.pointId; - team = await GVGTeamModel.teamBreak(teamCode, team.isRobot, team.maxDurability, rebirthAreaId, team.areaId, reviveCd); + team = await GVGTeamModel.teamBreak(teamCode, team.isRobot, team.maxDurability, rebirthAreaId, team.areaId, reviveCd, team.lineup); team.originPointId = originPointId; } return team; } // 队伍进入修整器 - public static async teamBreak(teamCode: string, isRobot: boolean, maxDurability: number, areaId: number, fromAreaId: number, reviveCd: number) { + public static async teamBreak(teamCode: string, isRobot: boolean, maxDurability: number, areaId: number, fromAreaId: number, reviveCd: number, lineup: GVGHeroInfo[]) { if(!isRobot) { - const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { restartTime: nowSeconds() + reviveCd, stopMoveTime: nowSeconds(), areaId, fromAreaId, durability: maxDurability, pointId: 0 } }, { new: true }).lean(); + lineup.forEach(hero => { hero.hp = 'max'; hero.others = ''; }) + const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { restartTime: nowSeconds() + reviveCd, stopMoveTime: nowSeconds(), areaId, fromAreaId, durability: maxDurability, pointId: 0, lineup } }, { new: true }).lean(); team.curTeamBreak = true; return team; } else { @@ -327,7 +347,10 @@ export default class GVGTeam extends BaseModel { let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $inc: { durability: -inc } }, { new: true }).lean(); let originPointId = team.pointId; if(team.durability <= 0) { - team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { fromAreaId: team.areaId, areaId: rebirthAreaId, pointId: 0, durability: team.maxDurability, restartTime: nowSeconds() + reviveCd } }, { new: true }).lean(); + let lineup = team.lineup||[]; + lineup.forEach(hero => { hero.hp = 'max'; hero.others = ''; }) + + team = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { fromAreaId: team.areaId, areaId: rebirthAreaId, pointId: 0, durability: team.maxDurability, restartTime: nowSeconds() + reviveCd, lineup } }, { new: true }).lean(); team.originPointId = originPointId; team.curTeamBreak = true; } diff --git a/shared/db/GVGUserData.ts b/shared/db/GVGUserData.ts index 54e16ca6b..c37ccb085 100644 --- a/shared/db/GVGUserData.ts +++ b/shared/db/GVGUserData.ts @@ -82,6 +82,9 @@ export default class GVGUserData extends BaseModel { @prop({ required: false }) reviveCnt: number; // 城池id + @prop({ required: false }) + winStreak: number; // 连胜 + public static async findByRole(configId: number, leagueCode: string, roleId: string) { const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId }, {}, { new: true, upsert: true}).lean(); return result; @@ -145,6 +148,16 @@ export default class GVGUserData extends BaseModel { const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId, hasCheckBox: { $exists: false }}, { $set: { hasCheckBox: true } }).lean(); return result; } + + public static async setWinStreak(configId: number, leagueCode: string, roleId: string, isSuccess: boolean) { + if (isSuccess) { + const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId }, { $inc: { winStreak: 1 } }, { new: true }).lean(); + return result; + } else { + const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId }, { $set: { winStreak: 0 } }, { new: true }).lean(); + return result; + } + } } export const GVGUserDataModel = getModelForClass(GVGUserData); diff --git a/shared/domain/dbGeneral.ts b/shared/domain/dbGeneral.ts index eae53bec6..c7f99f1ad 100644 --- a/shared/domain/dbGeneral.ts +++ b/shared/domain/dbGeneral.ts @@ -168,6 +168,12 @@ export class GVGHeroInfo extends PvpHeroInfo { outIndex?: number = 0; // 程序将信息存入数组顺序 @prop({ required: false }) dataId?: number = 0; // 对应出兵表dataId + @prop({ required: false }) + hp?: number|"max" = "max"; // 当前血量 + @prop({ required: false }) + maxHp?: number|"max" = "max"; // 当前血量 + @prop({ required: false }) + others?: string = ''; // 当前血量 setDataId(dataId: number, order: number) { this.dataId = dataId; diff --git a/shared/domain/gvgField/returnData.ts b/shared/domain/gvgField/returnData.ts index b63e52eee..626e6fca8 100644 --- a/shared/domain/gvgField/returnData.ts +++ b/shared/domain/gvgField/returnData.ts @@ -16,6 +16,7 @@ import { GVGTeamMem } from "../battleField/gvgBattle"; import { GVGTeamType } from "../../db/GVGTeam"; import { GVGRoleDataType } from "../../db/GVGRoleData"; import { Combo } from "../battleField/pvp"; +import { GVGHeroInfo, PvpEnemies } from "../dbGeneral"; class LeagueLeaderInfo { name: string; // 盟主名 @@ -653,6 +654,41 @@ export class GVGCityMapInfo { } } +export class GVGTeamSpineInfo { + spine: number = 0; + roleId: string = ''; + roleName: string = ''; + serverName: string = ''; + startMoveTime: number = 0; + stopMoveTime: number = 0; + moveCdTime: number = 0; + isMoving: boolean = false; + pointId: number = 0; + areaId: number = 0; + fromAreaId: number = 0; + teamCode: string = ''; + leagueCode: string = ''; + leagueName: string = ''; + + + constructor(obj: GVGTeamType, serverName: string) { + this.spine = obj.spine; + this.roleId = obj.roleId; + this.roleName = obj.roleName; + this.serverName = serverName; + this.startMoveTime = obj.startMoveTime; + this.stopMoveTime = obj.stopMoveTime; + this.moveCdTime = obj.moveCdTime; + this.isMoving = nowSeconds() < this.stopMoveTime; + this.areaId = obj.areaId; + this.pointId = obj.pointId; + this.fromAreaId = obj.fromAreaId; + this.teamCode = obj.teamCode; + this.leagueCode = obj.leagueCode; + this.leagueName = obj.leagueName; + } +} + export class GVGTeamSpineInMap { spine: number = 0; roleId: string = ''; @@ -674,7 +710,7 @@ export class GVGTeamSpineInMap { this.spine = obj.spine; this.roleId = obj.roleId; this.roleName = obj.roleName; - if(obj.serverId) this.serverName = serverNames[obj.serverId]; + if (obj.serverId) this.serverName = serverNames[obj.serverId]; this.startMoveTime = obj.startMoveTime; this.stopMoveTime = obj.stopMoveTime; this.moveCdTime = obj.moveCdTime; @@ -711,8 +747,10 @@ export class GVGTeamInList { restartTime: number; defenseTime: number; curTeamBreak: boolean; + hpPercent: number; + lineup: GVGLineupInfo[]; - constructor(team: GVGTeamType) { + constructor(team: GVGTeamType, needLineup = false) { if(!team) return; this.areaId = team.areaId; this.pointId = team.pointId; @@ -730,6 +768,22 @@ export class GVGTeamInList { this.restartTime = team.restartTime; this.defenseTime = team.defenseTime; this.curTeamBreak = !!team.curTeamBreak; + this.calHpPercent(team.isRobot, team.lineup); + if(needLineup && team.lineup) + this.lineup = team.lineup.map(cur => new GVGLineupInfo(cur)); + } + + calHpPercent(isRobot: boolean, lineup: GVGHeroInfo[]) { + if (isRobot) { + this.hpPercent = 100; + return + } + let hpSum = 0, hpNum = 0; + for (let { hp = 'max', maxHp = 'max' } of lineup) { + hpSum += ((hp == 'max'|| maxHp == 'max')? 100: (hp / maxHp * 100)); + hpNum ++; + } + this.hpPercent = Math.ceil(hpSum / hpNum); } } @@ -766,18 +820,35 @@ export class GVGTeamInListOnPoint extends GVGTeamInList { } } +class GVGLineupInfo { + actorId: number; // 武将 + dataId: number; // 出兵表上的位置 + order: number; // 行动 + subHid: number; + quality: number; // 品质 + hp: number|"max" = 'max'; // 血量, 当max时表示满血量,由客户端来算他的血条 + maxHp: number|"max" = 'max'; // 血量, 当max时表示满血量,由客户端来算他的血条 + others: string = ''; // 护盾相关 + + constructor(info: GVGHeroInfo) { + this.actorId = info.actorId; + this.dataId = info.dataId; + this.order = info.outIndex; + this.subHid = info.subActorId; + this.quality = info.quality; + this.hp = info.hp == undefined? 'max': info.hp; + this.maxHp = info.maxHp == undefined? 'max': info.maxHp; + this.others = info.others||''; + } +} + export class MyTeamSimpleInfo { teamCode: string; // 队伍唯一id index: number; // 队伍位置 head: number; // 保存头像 frame: number; // 保存相框 spine: number; // 保存形象 - lineup: { - actorId: number; // 武将 - dataId: number; // 出兵表上的位置 - order: number; // 行动 - subHid: number; - }[]; + lineup: GVGLineupInfo[]; combo: Combo[]; hasConfirm: boolean; @@ -787,7 +858,7 @@ export class MyTeamSimpleInfo { this.head = team.head; this.frame = team.frame; this.spine = team.spine; - this.lineup = team.lineup.map(({ actorId, dataId, outIndex, subActorId }) => ({ actorId, dataId, order: outIndex, subHid: subActorId })); + this.lineup = team.lineup.map(cur => new GVGLineupInfo(cur)); this.hasConfirm = team.confirmConfigId == configId; this.combo = team.combo; } @@ -802,11 +873,7 @@ export class MyTeamInfo { spine: number; // 保存形象 title: number; // 爵位 lv: number; - lineup: { - actorId: number; // 武将 - dataId: number; // 出兵表上的位置 - order: number; // 行动 - }[]; + lineup: GVGLineupInfo[]; lineupCe: number; durability: number; // 耐久 maxDurability: number; // 最大耐久 @@ -827,7 +894,7 @@ export class MyTeamInfo { this.spine = team.spine; this.title = team.title; this.lv = team.lv; - if(team.lineup) this.lineup = team.lineup.map(({ actorId, dataId, outIndex }) => ({ actorId, dataId, order: outIndex })); + if(team.lineup) this.lineup = team.lineup.map(cur => new GVGLineupInfo(cur)); this.durability = team.durability; this.maxDurability = team.maxDurability; this.restartTime = team.restartTime; @@ -841,6 +908,26 @@ export class MyTeamInfo { } } +export class GVGWinStreakInfo { + roleId: string; + roleName: string; + head: number; + frame: number; + lv: number; + leagueName: string; + winStreak: number; + + constructor(team: GVGTeamType, winStreak: number) { + this.roleId = team.roleId; + this.roleName = team.roleName; + this.head = team.head; + this.frame = team.frame; + this.lv = team.lv; + this.leagueName = team.leagueName; + this.winStreak = winStreak; + } +} + // 情报 // 联军排名 export class LeagueRankInInfoPage { @@ -890,4 +977,16 @@ export class GuardCityInfoPage { } this.leagueCe = ce; } +} + +export class GVGEnemies extends PvpEnemies { + hp: number|'max' = 'max'; + others: string = ''; + + // score: 这个武将的军功 + constructor(warjson: DicWarJson, heroInfo: GVGHeroInfo) { + super(warjson, heroInfo); + if(heroInfo.hp != undefined) this.hp = heroInfo.hp; + if(heroInfo.others != undefined) this.others = heroInfo.others; + } } \ No newline at end of file diff --git a/shared/pubUtils/dictionary/DicGVGVestigeType.ts b/shared/pubUtils/dictionary/DicGVGVestigeType.ts index 981caea01..aa49d8b97 100644 --- a/shared/pubUtils/dictionary/DicGVGVestigeType.ts +++ b/shared/pubUtils/dictionary/DicGVGVestigeType.ts @@ -11,6 +11,8 @@ export interface DicGVGVestigeType { readonly mapType: number[]; // 位置 readonly position: string; + // 哪天 + readonly openday: number[]; } export const dicGVGVestigeByType = new Map(); // 地图类型 => 遗迹id @@ -21,6 +23,7 @@ export function loadGVGVestigeType() { let arr = readFileAndParse(FILENAME.DIC_GVG_VESTIGE_TYPE); arr.forEach(o => { o.mapType = parseNumberList(o.mapType); + o.openday = parseNumberList(o.openday); for(let type of o.mapType) { if(!dicGVGVestigeByType.has(type)) { dicGVGVestigeByType.set(type, []); diff --git a/shared/pubUtils/interface.ts b/shared/pubUtils/interface.ts index 01fb3fbc0..8199643f4 100644 --- a/shared/pubUtils/interface.ts +++ b/shared/pubUtils/interface.ts @@ -45,6 +45,13 @@ export interface pvpEndParamInter { subHid?: number; } +export interface gvgEndParamInter { + actorId: number; + hp: number; + maxHp: number; + others: string; +} + export interface RougeDamageInter { charaCode: string; hp: number; diff --git a/shared/resource/jsons/dic_zyz_GVGVestigeType.json b/shared/resource/jsons/dic_zyz_GVGVestigeType.json index a8dc8bf03..7fb2b3a77 100644 --- a/shared/resource/jsons/dic_zyz_GVGVestigeType.json +++ b/shared/resource/jsons/dic_zyz_GVGVestigeType.json @@ -11,7 +11,8 @@ "additionValue": "2&", "content": "枪兵", "seid": 51102, - "position": "&" + "position": "&", + "openday": "1&2&3&4&5&6&7" }, { "id": 2, @@ -25,7 +26,8 @@ "additionValue": "6&", "content": "策士", "seid": 51106, - "position": "&" + "position": "&", + "openday": "1&2&3&4&5&6&7" }, { "id": 3, @@ -39,7 +41,8 @@ "additionValue": "5&", "content": "游侠", "seid": 51105, - "position": "&" + "position": "&", + "openday": "1&2&3&4&5&6&7" }, { "id": 4, @@ -53,7 +56,8 @@ "additionValue": "4&", "content": "弓兵", "seid": 51104, - "position": "&" + "position": "&", + "openday": "1&2&3&4&5&6&7" }, { "id": 5, @@ -67,7 +71,8 @@ "additionValue": "3&", "content": "骑兵", "seid": 51103, - "position": "&" + "position": "&", + "openday": "1&2&3&4&5&6&7" }, { "id": 6, @@ -81,7 +86,8 @@ "additionValue": "1&", "content": "步兵", "seid": 51101, - "position": "&" + "position": "&", + "openday": "1&2&3&4&5&6&7" }, { "id": 7, @@ -95,7 +101,8 @@ "additionValue": "1&", "content": "魏国", "seid": 51107, - "position": "&" + "position": "&", + "openday": "1&2&3&4&5&6&7" }, { "id": 8, @@ -109,7 +116,8 @@ "additionValue": "2&", "content": "吴国", "seid": 51109, - "position": "&" + "position": "&", + "openday": "1&2&3&4&5&6&7" }, { "id": 9, @@ -123,7 +131,8 @@ "additionValue": "3&", "content": "蜀国", "seid": 51108, - "position": "&" + "position": "&", + "openday": "1&2&3&4&5&6&7" }, { "id": 10, @@ -137,7 +146,8 @@ "additionValue": "4&", "content": "群雄", "seid": 51110, - "position": "&" + "position": "&", + "openday": "1&2&3&4&5&6&7" }, { "id": 11, @@ -151,6 +161,7 @@ "additionValue": "2&", "content": "女性", "seid": 51111, - "position": "&" + "position": "&", + "openday": "1&2&3&4&5&6&7" } ] \ No newline at end of file