diff --git a/game-server/app/servers/guild/handler/gvgBattleHandler.ts b/game-server/app/servers/guild/handler/gvgBattleHandler.ts index 82155ce53..fdea22b21 100644 --- a/game-server/app/servers/guild/handler/gvgBattleHandler.ts +++ b/game-server/app/servers/guild/handler/gvgBattleHandler.ts @@ -8,7 +8,7 @@ import { Application, BackendSession, ChannelService, HandlerService } from "pin import { resResult, genCode } from "../../../pubUtils/util"; import { GVGLeagueModel } from '../../../db/GVGLeague'; import { checkGVGPeriod, getGroupIdOfServer, getGVGConfig, getGVGPeriodData, getGVGServerType } from '../../../services/gvg/gvgService'; -import { calBattleScoreByCe, checkAreaIsInCity, checkMoveStatus, getBirthAreaOfCity, getGVGWarId, getOppHeroes, initRobots, teamBreak } from '../../../services/gvg/gvgBattleService'; +import { calBattleScoreByCe, checkAreaIsInCity, checkGVGBattleStart, checkMoveStatus, getBirthAreaOfCity, getGVGWarId, getOppHeroes, initRobots, teamBreak } from '../../../services/gvg/gvgBattleService'; import { getGVGBattleData } from '../../../services/gvg/gvgBattleMemory'; import { nowSeconds } from '../../../pubUtils/timeUtil'; import { GVGBattleRecModel } from '../../../db/GVGBattleRec'; @@ -347,24 +347,55 @@ export class GVGBattleHandler { let teamObj = getGVGBattleData(groupId, serverType); teamObj.move(teamCode, areaId, 0, team.startMoveTime, team.stopMoveTime); - return resResult(STATUS.SUCCESS, { areaId, cityId, curTeam: team }); + return resResult(STATUS.SUCCESS, { areaId, cityId, curTeam: new MyTeamInfo(team) }); } // 队伍入驻积分点 async teamSettle(msg: { cityId: number, areaId: number, pointId: number, teamCode: string }, session: BackendSession) { + const roleId = session.get('roleId'); const serverId = session.get('serverId'); const { pointId, teamCode } = msg; - const curTeam = await GVGTeamModel.findOneAndUpdate({ teamCode }, { pointId }).lean(); + + let { configId, period } = getGVGPeriodData(); + // if (period != GVG_PERIOD.BATTLE) return resResult(STATUS.GVG_NOT_BATTLE_PERIOD); // TODO 测试临时注 + let groupId = await getGroupIdOfServer(serverId); let serverType = await getGVGServerType(serverId); + + let myTeam = await GVGTeamModel.findByTeamCode(roleId, teamCode); + if(!myTeam) return resResult(STATUS.GVG_TEAM_NOT_FOUND); + + let dicAreaPoint = gameData.gvgAreaPoint.get(pointId); + if(dicAreaPoint.areaId != myTeam.areaId) return resResult(STATUS.GVG_POINT_NOT_AREA); + + let hasOtherTeam = await GVGTeamModel.checkPoint(configId, groupId, serverType, pointId); + if(hasOtherTeam) return resResult(STATUS.GVG_POINT_HAS_SETTLED); + const curTeam = await GVGTeamModel.settlePoint(teamCode, pointId); + let teamObj = getGVGBattleData(groupId, serverType); - teamObj.teamSettle(teamCode, pointId); - return resResult(STATUS.SUCCESS, { curTeam }); + teamObj.teamSettle(roleId, teamCode, pointId); + return resResult(STATUS.SUCCESS, { curTeam: new MyTeamInfo(curTeam) }); } // 队伍离开积分点 - async teamLeave(msg: any, session: BackendSession) { - return resResult(STATUS.SUCCESS); + async teamLeave(msg: { cityId: number, areaId: number, pointId: number, teamCode: string }, session: BackendSession) { + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + const { pointId, teamCode } = msg; + + let groupId = await getGroupIdOfServer(serverId); + let serverType = await getGVGServerType(serverId); + + let myTeam = await GVGTeamModel.findByTeamCode(roleId, teamCode); + if(!myTeam) return resResult(STATUS.GVG_TEAM_NOT_FOUND); + let dicAreaPoint = gameData.gvgAreaPoint.get(pointId); + if(dicAreaPoint.areaId != myTeam.areaId) return resResult(STATUS.GVG_POINT_NOT_AREA); + + const curTeam = await GVGTeamModel.settlePoint(teamCode, 0); + let teamObj = getGVGBattleData(groupId, serverType); + teamObj.teamSettle(roleId, teamCode, pointId); + + return resResult(STATUS.SUCCESS, { curTeam: new MyTeamInfo(curTeam) }); } // 队伍开始攻击 @@ -375,18 +406,18 @@ export class GVGBattleHandler { const serverId = session.get('serverId'); const { teamCode, oppoTeamCode } = msg; + let { configId, period } = getGVGPeriodData(); + // if (period != GVG_PERIOD.BATTLE) return resResult(STATUS.GVG_NOT_BATTLE_PERIOD); // TODO 测试临时注 + let groupId = await getGroupIdOfServer(serverId); let serverType = await getGVGServerType(serverId); let { attackTeam, defenseTeam } = await GVGTeamModel.findBattleTeams(teamCode, oppoTeamCode); - if(!attackTeam || !defenseTeam) return resResult(STATUS.GVG_BATTLE_TEAM_INVALID); - if(attackTeam.attackTime > nowSeconds()) return resResult(STATUS.GVG_TEAM_ATTACKING); - if(defenseTeam.defenseTime > nowSeconds() || defenseTeam.lockTime > nowSeconds()) return resResult(STATUS.GVG_TEAM_DEFENSEING); - if(attackTeam.durability <= 0) return resResult(STATUS.GVG_ATTACK_TEAM_BROKEN); - if(defenseTeam.durability <= 0) return resResult(STATUS.GVG_DEFENSE_TEAM_BROKEN); + let checkStatus = checkGVGBattleStart(roleId, attackTeam, defenseTeam); + if(checkStatus.code != 0) return resResult(checkStatus); const warId = getGVGWarId(defenseTeam); - const battleRecord = await GVGBattleRecModel.createRec(warId, attackTeam, defenseTeam); + const battleRecord = await GVGBattleRecModel.createRec(configId, groupId, serverType, warId, attackTeam, defenseTeam); attackTeam = await GVGTeamModel.battleStartLockAttack(teamCode); defenseTeam = await GVGTeamModel.battleStartLockDefense(oppoTeamCode, teamCode); @@ -396,7 +427,7 @@ export class GVGBattleHandler { teamObj.setTime(defenseTeam.teamCode, defenseTeam); let heroes = getOppHeroes(warId, defenseTeam.isRobot, defenseTeam.lineup) - return resResult(STATUS.SUCCESS, { battleCode: battleRecord.battleCode, warId, isRobot: defenseTeam.isRobot, heroes, curTeam: attackTeam }); + return resResult(STATUS.SUCCESS, { battleCode: battleRecord.battleCode, warId, isRobot: defenseTeam.isRobot, heroes, curTeam: new MyTeamInfo(attackTeam) }); } // 队伍停止攻击 @@ -407,8 +438,9 @@ export class GVGBattleHandler { let { configId, period } = getGVGPeriodData(); const record = await GVGBattleRecModel.findByBattleCode(battleCode); if(!record) return resResult(STATUS.GVG_BATTLEREC_NOT_FOUND); + if(record.battleEndTime > 0) return resResult(STATUS.GVG_BATTLEREC_HAS_SUMMIT); let { attackTeam, defenseTeam } = await GVGTeamModel.findBattleTeams(record.attackTeam.teamCode, record.defenseTeam.teamCode); - if(defenseTeam.attackTeam != attackTeam.teamCode) return resResult(STATUS.GVG_LOCK_TIME_OUT) + if(defenseTeam.lockTeamCode != attackTeam.teamCode) return resResult(STATUS.GVG_LOCK_TIME_OUT) let groupId = await getGroupIdOfServer(serverId); let serverType = await getGVGServerType(serverId); @@ -420,8 +452,16 @@ export class GVGBattleHandler { attackTeam = await GVGTeamModel.battleEndAttack(attackTeam.teamCode, isSuccess? -win: -fail, calBattleScoreByCe(isSuccess, attackTeam.lineupCe)); defenseTeam = await GVGTeamModel.battleEndDefense(defenseTeam.teamCode, isSuccess? -fail: -win, calBattleScoreByCe(isSuccess, defenseTeam.lineupCe)); - if(attackTeam.durability <= 0) attackTeam = await teamBreak(city, attackTeam); - if(defenseTeam.durability <= 0) defenseTeam = await teamBreak(city, defenseTeam); + if(attackTeam.durability <= 0) { + attackTeam = await teamBreak(city, attackTeam); + } + if(defenseTeam.durability <= 0) { + if(defenseTeam.pointId > 0 && attackTeam.durability > 0) { // 打败的对手原来占领着一个位置,现在这个位置是你的了 + attackTeam = await GVGTeamModel.settlePoint(attackTeam.teamCode, defenseTeam.pointId); + } + defenseTeam = await teamBreak(city, defenseTeam); + } + // 更新内存 let teamObj = getGVGBattleData(groupId, serverType); teamObj.battleEnd([attackTeam, defenseTeam]); diff --git a/game-server/app/services/gvg/gvgBattleMemory.ts b/game-server/app/services/gvg/gvgBattleMemory.ts index 90149d2b6..9a35852dc 100644 --- a/game-server/app/services/gvg/gvgBattleMemory.ts +++ b/game-server/app/services/gvg/gvgBattleMemory.ts @@ -75,6 +75,17 @@ class GVGBattleData { } } + private setRolePoints(roleId: string, fromPointId: number, pointId: number) { + if(fromPointId > 0 && pointId == 0) { // 被打得撤离积分点 + if(this.rolePoints.has(roleId) && this.rolePoints.get(roleId).has(pointId)) { + this.rolePoints.get(roleId).delete(pointId); + } + } else if (fromPointId == 0 && pointId > 0) { + if(!this.rolePoints.has(roleId)) this.rolePoints.set(roleId, new Set()); + this.rolePoints.get(roleId).add(pointId); + } + } + public move(teamCode: string, areaId: number, fromAreaId: number, startMoveTime: number, stopMoveTime: number) { let team = this.teams.get(teamCode); if(!team) return; @@ -90,11 +101,13 @@ class GVGBattleData { } // 队伍入驻积分点 - public teamSettle(teamCode: string, pointId: number) { - let team = this.teams.get(teamCode); - if(!team) return; - team.pointId = pointId; - } + public teamSettle(roleId: string, teamCode: string, pointId: number) { + let teamMem = this.teams.get(teamCode); + if(!teamMem) return; + let { pointId: fromPointId } = teamMem; + this.setRolePoints(roleId, fromPointId, pointId); + teamMem.pointId = pointId; +} // 关卡结算 public battleEnd(teams: GVGTeamType[]) { @@ -105,11 +118,7 @@ class GVGBattleData { } let { areaId: fromAreaId, pointId: fromPointId } = teamMem; teamMem.battleEnd(team); - if(fromPointId > 0 && team.pointId == 0) { // 被打得撤离积分点 - if(this.rolePoints.has(team.roleId) && this.rolePoints.get(team.roleId).has(team.pointId)) { - this.rolePoints.get(team.roleId).delete(team.pointId); - } - } + this.setRolePoints(team.roleId, fromPointId, team.pointId); this.setAreaMap(team.teamCode, fromAreaId, team.areaId); } } diff --git a/game-server/app/services/gvg/gvgBattleService.ts b/game-server/app/services/gvg/gvgBattleService.ts index f75e46108..9facc2fa1 100644 --- a/game-server/app/services/gvg/gvgBattleService.ts +++ b/game-server/app/services/gvg/gvgBattleService.ts @@ -67,7 +67,7 @@ export function checkMoveStatus(team: GVGTeamType, cityId: number, areaId: numbe if(!team) return STATUS.GVG_BATTLE_TEAM_NOT_FOUND; if(team.cityId != cityId) return STATUS.GVG_BATTLE_IS_NOT_IN_CITY; if(team.pointId > 0) return STATUS.GVG_BATTLE_TEAM_IS_SELLTED; - if(team.stopMoveTime > 0 && team.stopMoveTime < nowSeconds()) return STATUS.GVG_BATTLE_IS_MOVING; + if(team.stopMoveTime > nowSeconds()) return STATUS.GVG_BATTLE_IS_MOVING; let dicArea = gameData.gvgArea.get(areaId); if(!dicArea) return STATUS.DIC_DATA_NOT_FOUND; if(dicArea.relateArea.indexOf(team.areaId) == -1) return STATUS.GVG_BATTLE_AREA_NOT_RELATE; @@ -145,4 +145,19 @@ export function getOppHeroes(warId: number, isRobot: boolean, lineup: GVGHeroInf } } return heroes +} + +export function checkGVGBattleStart(roleId: string, attackTeam: GVGTeamType, defenseTeam: GVGTeamType) { + + if(!attackTeam || !defenseTeam) return STATUS.GVG_BATTLE_TEAM_INVALID; + if(attackTeam.roleId != roleId) return STATUS.GVG_TEAM_IS_NOT_MINE; + if(attackTeam.leagueCode == defenseTeam.leagueCode) return STATUS.GVG_SAME_LEAGUE_CANNOT_ATTACK; + if(attackTeam.areaId != defenseTeam.areaId) return STATUS.GVG_TEAM_NOT_SAME_AREA; + + if(attackTeam.attackTime > nowSeconds()) return STATUS.GVG_TEAM_ATTACKING; + if(defenseTeam.defenseTime > nowSeconds() || defenseTeam.lockTime > nowSeconds()) return STATUS.GVG_TEAM_DEFENSEING; + if(attackTeam.durability <= 0) return STATUS.GVG_ATTACK_TEAM_BROKEN; + if(defenseTeam.durability <= 0) return STATUS.GVG_DEFENSE_TEAM_BROKEN; + + return STATUS.SUCCESS; } \ No newline at end of file diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 031799b0a..9337d354e 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -372,6 +372,12 @@ export const STATUS = { GVG_LOCK_TIME_OUT: { code: 21410, simStr: '挑战超时' }, GVG_ATTACK_TEAM_BROKEN: { code: 21411, simStr: '挑战队伍已被击破' }, GVG_DEFENSE_TEAM_BROKEN: { code: 21411, simStr: '对方队伍已被击破' }, + GVG_BATTLEREC_HAS_SUMMIT: { code: 21412, simStr: '该记录已结算过' }, + GVG_TEAM_IS_NOT_MINE: { code: 21413, simStr: '您不可操作此队伍' }, + GVG_SAME_LEAGUE_CANNOT_ATTACK: { code: 21414, simStr: '您不可攻击友军' }, + GVG_TEAM_NOT_SAME_AREA: { code: 21415, simStr: '对方不在同一个区域内' }, + GVG_POINT_HAS_SETTLED: { code: 21416, simStr: '该据点已经有其他队伍驻守' }, + GVG_POINT_NOT_AREA: { code: 21417, simStr: '您不在该积分点所在区域' }, // 通用 30000 - 30099 DIC_DATA_NOT_FOUND: { code: 30000, simStr: '数据表未找到' }, diff --git a/shared/db/GVGBattleRec.ts b/shared/db/GVGBattleRec.ts index 7ff1b3a06..f56711ce9 100644 --- a/shared/db/GVGBattleRec.ts +++ b/shared/db/GVGBattleRec.ts @@ -52,6 +52,15 @@ export default class GVGBattleRec extends BaseModel { @prop({ required: true }) battleCode: string; // 战斗记录 + @prop({ required: true }) + configId: number; // 赛季 + + @prop({ required: true }) + groupId: number; // 战区 + + @prop({ required: true }) + serverType: number; // 1-单服 2-跨服 + @prop({ required: true }) warId: number; // 关卡id @@ -67,9 +76,9 @@ export default class GVGBattleRec extends BaseModel { @prop({ required: true }) battleEndTime: number; - public static async createRec(warId: number, attackTeam: GVGTeamType, defenseTeam: GVGTeamType) { + public static async createRec(configId: number, groupId: number, serverType: number, warId: number, attackTeam: GVGTeamType, defenseTeam: GVGTeamType) { const battleCode = genCode(8); - const result: GVGBattleRecType = await GVGBattleRecModel.findOneAndUpdate({ battleCode }, { $set: { warId, attackTeam, defenseTeam, isSuccess: false } }, { new: true, upsert: true }).lean(); + const result: GVGBattleRecType = await GVGBattleRecModel.findOneAndUpdate({ battleCode }, { $set: { configId, groupId, serverType, warId, attackTeam, defenseTeam, isSuccess: false } }, { new: true, upsert: true }).lean(); return result; } diff --git a/shared/db/GVGTeam.ts b/shared/db/GVGTeam.ts index 3bf094494..7c1ac992e 100644 --- a/shared/db/GVGTeam.ts +++ b/shared/db/GVGTeam.ts @@ -74,7 +74,7 @@ export default class GVGTeam extends BaseModel { lockTime: number; // 正在被进攻中 @prop({ required: true, default: 0 }) - attackTeam: string; // 正在被这支队伍进攻中 + lockTeamCode: string; // 正在被这支队伍进攻中 @prop({ required: true, default: 0 }) fromAreaId: number; // 从那个区域移动 @@ -207,8 +207,14 @@ export default class GVGTeam extends BaseModel { } // 防守方锁定cd - public static async battleStartLockDefense(teamCode: string, attackTeam: string) { - const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { lockTime: nowSeconds() + GVG.GVG_DEFAULT_ATTACK_CD, attackTeam } }, { new: true }).lean(); + public static async battleStartLockDefense(teamCode: string, lockTeamCode: string) { + const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { lockTime: nowSeconds() + GVG.GVG_DEFAULT_ATTACK_CD, lockTeamCode } }, { new: true }).lean(); + return team; + } + + // 占领积分点 + public static async settlePoint(teamCode: string, pointId: number) { + const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { pointId } }, { new: true }).lean(); return team; } @@ -220,7 +226,7 @@ export default class GVGTeam extends BaseModel { // 结算防守方 public static async battleEndDefense(teamCode: string, hpInc: number, playerScoreInc: number) { - const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + GVG.GVG_DEFAULT_DEFENSE_CD }, $inc: { durability: hpInc, playerScore: playerScoreInc } }, { new: true }).lean(); + const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + GVG.GVG_DEFAULT_DEFENSE_CD, lockTime: 0, lockTeamCode: '' }, $inc: { durability: hpInc, playerScore: playerScoreInc } }, { new: true }).lean(); return team; } @@ -244,6 +250,12 @@ export default class GVGTeam extends BaseModel { const team: GVGTeamType[] = await GVGTeamModel.find({ configId, cityId: { $gt: 0 } }).lean(); return team; } + + // 这个编队上是否已经有队伍了 + public static async checkPoint(configId: number, groupId: number, serverType: number, pointId: number) { + return await GVGTeamModel.exists({ configId, groupId, serverType, pointId }); + } + } diff --git a/shared/domain/gvgField/gvgDb.ts b/shared/domain/gvgField/gvgDb.ts index 9bf1cac60..1acb0c61b 100644 --- a/shared/domain/gvgField/gvgDb.ts +++ b/shared/domain/gvgField/gvgDb.ts @@ -8,7 +8,7 @@ import { gameData } from "../../pubUtils/data"; import { EXTERIOR, GVG } from "../../pubUtils/dicParam"; import { DicGVGVestige } from "../../pubUtils/dictionary/DicGVGVestige"; import { DicWarJson } from "../../pubUtils/dictionary/DicWarJson"; -import { GVGHeroInfo, PvpHeroInfo } from "../dbGeneral"; +import { GVGHeroInfo } from "../dbGeneral"; import { LineupHero } from "../roleField/hero"; export class OppPlayerHeroInfo { diff --git a/shared/domain/roleField/hero.ts b/shared/domain/roleField/hero.ts index 0e0b76b32..8111f7d29 100644 --- a/shared/domain/roleField/hero.ts +++ b/shared/domain/roleField/hero.ts @@ -1,5 +1,4 @@ - -import { prop } from 'typegoose'; +import { prop } from '@typegoose/typegoose'; import { ArtifactModelType } from '../../db/Artifact'; import { Connect, EPlace, HeroSkin, HeroType, HeroUpdate, Talent } from '../../db/Hero'; import { JewelSe, JewelType, RandSe } from '../../db/Jewel'; diff --git a/shared/pubUtils/data.ts b/shared/pubUtils/data.ts index 6b1c1dab2..82b8552c7 100644 --- a/shared/pubUtils/data.ts +++ b/shared/pubUtils/data.ts @@ -1219,7 +1219,7 @@ export function getGVGBattleRankReward(type: number, rank: number) { function parseGVGDurabilityMinus() { const range = parseNumberList(param.GVG.GVG_DEFAULT_DURABILITY_MINUS); gameData.gvgBattleDurabilityMinus.win = range[0]; - gameData.gvgBattleDurabilityMinus.fail = range[0]; + gameData.gvgBattleDurabilityMinus.fail = range[1]; } function parseGVGTeamDurability() { diff --git a/web-server/app/controller/game.ts b/web-server/app/controller/game.ts index f8de39ed5..bc7bd5070 100644 --- a/web-server/app/controller/game.ts +++ b/web-server/app/controller/game.ts @@ -224,7 +224,7 @@ export default class GameController extends Controller { if (!battleRec) return ctx.body = ctx.service.utils.resResult(STATUS.BATTLE_NOT_FOUND); let { warType, roleId } = battleRec; - if (warType !== WAR_TYPE.PVP && warType !== WAR_TYPE.LADDER) return ctx.body = ctx.service.utils.resResult(STATUS.BATTLE_RPL_NOT_SUPPORT); + if (warType !== WAR_TYPE.PVP && warType !== WAR_TYPE.LADDER && warType !== WAR_TYPE.GVG_VESTIGE) return ctx.body = ctx.service.utils.resResult(STATUS.BATTLE_RPL_NOT_SUPPORT); writePath = getLocalRplUrl(roleId, warType, battleCode); try {