diff --git a/game-server/app/servers/guild/handler/gvgBattleHandler.ts b/game-server/app/servers/guild/handler/gvgBattleHandler.ts index 61bf48044..a857e6df2 100644 --- a/game-server/app/servers/guild/handler/gvgBattleHandler.ts +++ b/game-server/app/servers/guild/handler/gvgBattleHandler.ts @@ -16,9 +16,6 @@ import { getAllServerName } from '../../../services/redisService'; import { checkBattleHeroesByHid } from '../../../services/normalBattleService'; import { SaveTeamParam, SaveTeamUpdateParam } from '../../../domain/gvgField/gvgDb'; import { GVG_AREA_TYPE, GVG_ATTACK_TYPE, GVG_ITEM, GVG_PERIOD, GVG_REC_TYPE, ITEM_CHANGE_REASON, PUSH_ROUTE, REDIS_KEY, STATUS } from '../../../consts'; -import { GVGHeroInfo } from '../../../domain/dbGeneral'; -import { ArtifactModel } from '../../../db/Artifact'; -import { getHeroesAttributes } from '../../../services/playerCeService'; import { addRoleToAreaChannel, addRoleToAreaTeamChannel, addRoleToGVGCityChannel, leaveGVGAreaChannel, leaveGVGAreaTeamChannel, leaveGVGCityTeamChannel } from '../../../services/chatChannelService'; import { nowSeconds } from '../../../pubUtils/timeUtil'; import { GVGUserItemModel } from '../../../db/GVGUserItem'; @@ -182,7 +179,7 @@ export class GVGBattleHandler { if (originCityId != cityId) { let gvgUserData = await GVGUserDataModel.findByRole(configId, myLeague.leagueCode, roleId); if(gvgUserData?.cityId > 0) { // 如果leaveCity没有退出成功,玩家还遗留在上一座城中,做一下处理 - city = await GVGCityModel.decreasePlayerByCity(configId, groupKey, gvgUserData.cityId, roleId); + await leaveCity(true, roleId, serverId, guildCode, myLeague); } const roleTeamCnt = await GVGTeamModel.getTeamCntByRole(roleId); city = await GVGCityModel.increasePlayer(configId, groupKey, cityId, roleId, myLeague.leagueCode, roleTeamCnt); @@ -465,9 +462,9 @@ export class GVGBattleHandler { // 计算并更新两支队伍耐久 let { win, fail } = gameData.gvgBattleDurabilityMinus; - attackTeam = await GVGTeamModel.battleEndAttack(attackTeam.teamCode, isSuccess? -win: -fail, getBirthAreaOfCity(city, attackTeam.leagueCode), await getTechReviveMinus(configId, attackTeam.leagueCode)); - defenseTeam = await GVGTeamModel.battleEndDefense(defenseTeam.teamCode, isSuccess? -fail: -win, getBirthAreaOfCity(city, defenseTeam.leagueCode), await getTechReviveMinus(configId, defenseTeam.leagueCode)); - if(defenseTeam.curTeamBreak && defenseTeam.originPointId > 0) { // 打败的对手原来占领着一个位置,现在这个位置是你的了 + 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), await getTechReviveMinus(groupKey, configId, defenseTeam.leagueCode)); + if(defenseTeam.curTeamBreak && defenseTeam.originPointId > 0 && !defenseTeam.isCatapult) { // 打败的对手原来占领着一个位置,现在这个位置是你的了 if(!attackTeam.curTeamBreak) { attackTeam = await GVGTeamModel.settlePoint(attackTeam.teamCode, defenseTeam.originPointId); await GVGCityAreaPointModel.settlePoint(cityId, attackTeam.areaId, defenseTeam.originPointId, attackTeam); @@ -486,7 +483,7 @@ export class GVGBattleHandler { teamObj.battleEnd([attackTeam, defenseTeam]); // 更新rec let rec = await GVGBattleRecModel.battleEnd(battleCode, isSuccess, attackTeam, defenseTeam); - await battleEndSendMessage(groupKey, cityId, defenseTeam, attackTeam); + await battleEndSendMessage(groupKey, cityId, defenseTeam, attackTeam, GVG_ATTACK_TYPE.PLAYER); addBattleEndRec(rec); return resResult(STATUS.SUCCESS, { curTeam: new MyTeamInfo(attackTeam), oppTeam: new MyTeamInfo(defenseTeam) }); @@ -522,8 +519,8 @@ export class GVGBattleHandler { if (!city) return resResult(STATUS.GVG_CITY_NOT_FOUND); let hurt = await getTechKnifeHurt(configId, attackTeam.leagueCode); - defenseTeam = await GVGTeamModel.battleEndDefense(oppoTeamCode, -hurt, getBirthAreaOfCity(city, defenseTeam.leagueCode), await getTechReviveMinus(configId, defenseTeam.leagueCode)); - if(defenseTeam.curTeamBreak && defenseTeam.originPointId > 0) { // 打败的对手原来占领着一个位置,现在这个位置是你的了 + defenseTeam = await GVGTeamModel.battleEndDefense(oppoTeamCode, -hurt, getBirthAreaOfCity(city, defenseTeam.leagueCode), await getTechReviveMinus(groupKey, configId, defenseTeam.leagueCode)); + if(defenseTeam.curTeamBreak && defenseTeam.originPointId > 0 && !defenseTeam.isCatapult) { // 打败的对手原来占领着一个位置,现在这个位置是你的了 if(!attackTeam.curTeamBreak) { attackTeam = await GVGTeamModel.settlePoint(attackTeam.teamCode, defenseTeam.originPointId); await GVGCityAreaPointModel.settlePoint(cityId, attackTeam.areaId, defenseTeam.originPointId, attackTeam); @@ -541,10 +538,7 @@ export class GVGBattleHandler { let teamObj = getGVGBattleData(groupKey); teamObj.battleEnd([attackTeam, defenseTeam]); - await battleEndSendMessage(groupKey, cityId, defenseTeam, attackTeam); - await sendMessageToGVGAreaByTeamWithSuc(groupKey, defenseTeam.areaId, PUSH_ROUTE.GVG_TEAM_ATTACKED, { - cityId, areaId: defenseTeam.areaId, attackType: GVG_ATTACK_TYPE.KNIFE, teams: [new GVGTeamInList(defenseTeam)] - }); + await battleEndSendMessage(groupKey, cityId, defenseTeam, attackTeam, GVG_ATTACK_TYPE.KNIFE); return resResult(STATUS.SUCCESS, { curTeam: new MyTeamInfo(attackTeam), oppTeam: new MyTeamInfo(defenseTeam) }); } diff --git a/game-server/app/services/gvg/gvgBattleMemory.ts b/game-server/app/services/gvg/gvgBattleMemory.ts index c50d06458..042b78306 100644 --- a/game-server/app/services/gvg/gvgBattleMemory.ts +++ b/game-server/app/services/gvg/gvgBattleMemory.ts @@ -18,6 +18,7 @@ class GVGBattleData { private roleToTeam: Map = new Map(); // roleId => teamCode private leagueToTeam: Map> = new Map(); // leagueCode => teamCode public areaToTeams: Map> = new Map(); // areaId => teamCode set,用于定时下发地图玩家数据 + private leagueActiveTech: Map = new Map(); // 千机阁状态 leagueCode => activeTech constructor(groupKey: string) { this.groupKey = groupKey; @@ -34,11 +35,11 @@ class GVGBattleData { } public findCatapultAttackTeam(areaId: number, leagueCode: string) { - let teams: string[] = []; + let teams: GVGTeamMem[] = []; let teamCodes = this.areaToTeams.get(areaId)||new Set(); for(let teamCode of teamCodes) { let team = this.teams.get(teamCode); - if(team && team.leagueCode != leagueCode && !team.isRobot) teams.push(teamCode); + if(team && team.leagueCode != leagueCode && !team.isRobot) teams.push(team); } return teams; } @@ -69,6 +70,9 @@ class GVGBattleData { this.teams.get(team.teamCode).setCity(team.cityId, team.areaId, team.pointId); if(team.pointId > 0 && !team.isRobot) { if(!this.rolePoints.has(team.roleId)) this.rolePoints.set(team.roleId, new Map()); + for(let [pointId, teamCode] of this.rolePoints.get(team.roleId)) { + if(teamCode == team.teamCode) this.rolePoints.get(team.roleId).delete(pointId); + } this.rolePoints.get(team.roleId).set(team.pointId, team.teamCode); } let teamCodesOfRole = this.roleToTeam.get(team.roleId)||[]; @@ -200,6 +204,14 @@ class GVGBattleData { if(info.lv) team.lv = info.lv; } } + + public getLeagueTech(leagueCode: string) { + return this.leagueActiveTech.get(leagueCode); + } + + public setLeagueTech(leagueCode: string, activeTech: number[]) { + this.leagueActiveTech.set(leagueCode, activeTech); + } } export function getGVGBattleData(groupKey: string) { diff --git a/game-server/app/services/gvg/gvgBattleService.ts b/game-server/app/services/gvg/gvgBattleService.ts index 488d7b163..5b879ee8f 100644 --- a/game-server/app/services/gvg/gvgBattleService.ts +++ b/game-server/app/services/gvg/gvgBattleService.ts @@ -233,10 +233,15 @@ export async function leaveCity(isForce: boolean, roleId: string, serverId: numb } // 复活cd -export async function getTechReviveMinus(configId: number, leagueCode: string) { - let leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, leagueCode); +export async function getTechReviveMinus(groupKey: string, configId: number, leagueCode: string) { + let teamObj = getGVGBattleData(groupKey); + let activeTech = teamObj.getLeagueTech(leagueCode); + if(!activeTech) { + let leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, leagueCode); + activeTech = leaguePrepare?.activeTech||[]; + teamObj.setLeagueTech(leagueCode, activeTech); + } let minusCd = 0; - let activeTech = leaguePrepare?.activeTech||[]; for(let techId of activeTech) { let dicTech = gameData.gvgTech.get(techId); if(dicTech && dicTech.type == GVG_TECH_TYPE.BATTLE_REVIVE_GAP) { @@ -245,6 +250,7 @@ export async function getTechReviveMinus(configId: number, leagueCode: string) { } let cd = GVG.GVG_DEFAULT_REVIVE_CD - minusCd; if(cd < 0) cd = 0; + return cd; } @@ -366,16 +372,20 @@ export async function catapultHurt() { let battleAreaIds = dicGVGCity?.battleAreaIds||[] if(!catapult || catapult.isBroken || !dicGVGCity || battleAreaIds.length <= 0) continue; let areaId = getRandSingleEelm(battleAreaIds); - let teamCodes = teamObj.findCatapultAttackTeam(areaId, catapult.leagueCode); - - let teams = await GVGTeamModel.attackByCatapult(teamCodes, catapult.captapultAtk, dicGVGCity.attackBirth); + // let areaId = catapult.cityId * 100 + 2; + let teamMems = teamObj.findCatapultAttackTeam(areaId, catapult.leagueCode); + let teams: GVGTeamType[] = []; + for(let { teamCode, leagueCode } of teamMems) { + let team = await GVGTeamModel.attackByCatapult(teamCode, catapult.captapultAtk, dicGVGCity.attackBirth, await getTechReviveMinus(teamObj.groupKey, configId, leagueCode)); + teams.push(team); + } teamObj.battleEnd(teams); if(teams.length > 0) { await sendMessageToGVGAreaByTeamWithSuc(teamObj.groupKey, areaId, PUSH_ROUTE.GVG_TEAM_ATTACKED, { cityId: catapult.cityId, areaId, attackType: GVG_ATTACK_TYPE.CATAPULT, teams: teams.map(team => new GVGTeamInList(team)) }); await sendMessageToGVGCityWithSuc(teamObj.groupKey, catapult.cityId, PUSH_ROUTE.GVG_SPINE_ATTACKED, { - cityId: catapult.cityId, areaId, attackType: GVG_ATTACK_TYPE.CATAPULT, teams: teams.map(team => new GVGAttackSpine(team, catapult.captapultAtk)) + cityId: catapult.cityId, areaId, teamCode: catapult.teamCode, attackType: GVG_ATTACK_TYPE.CATAPULT, spines: teams.map(team => new GVGAttackSpine(team, catapult.captapultAtk)) }); for(let team of teams) { await pushTeamBeHurtMessage(team); @@ -486,7 +496,12 @@ export async function gvgBattleEnd() { let rankKeys = keys.map(key => { let [,, groupKey, _cityId] = key.split(':'); return { groupKey, cityId: parseInt(_cityId) }; - }).sort((a, b) => b.cityId - a.cityId); + }).sort((a, b) => { + let dicCityA = gameData.gvgCity.get(a.cityId); + let dicCityB = gameData.gvgCity.get(b.cityId); + if(dicCityA.cityType == dicCityB.cityType) return a.cityId - b.cityId; + return dicCityA.cityType - dicCityB.cityType; + }); let lastCities = await GVGCityModel.findByConfig(configId); for(let { cityId, groupKey } of lastCities) { let hasKey = rankKeys.find(cur => cur.cityId == cityId && cur.groupKey == groupKey); @@ -500,30 +515,28 @@ export async function gvgBattleEnd() { let r = new Rank(REDIS_KEY.GVG_BATTLE_LEAGUE_RANK_BY_CITY, { configId, groupKey, cityId }); let ranks = await r.getRankByRange(); // 排名最高占领城池 + let hasGuard = false; for(let obj of ranks) { let rankInfo = obj; let cnt = guardLeagueCnt.get(rankInfo.code)||0; if(cnt < GVG.GVG_CITY_OCCUPIED_NUMBER) { await addGuardCity(configId, groupKey, cityId, rankInfo.code); guardLeagueCnt.set(rankInfo.code, cnt + 1); + hasGuard = true; break; } } - - let guardCity = lastCities.find(city => city.cityId == cityId && city.groupKey == groupKey); - if(guardCity) { - let cnt = guardLeagueCnt.get(guardCity.guardLeague)||0; - if(cnt < GVG.GVG_CITY_OCCUPIED_NUMBER) { - await addGuardCity(configId, groupKey, cityId, guardCity.guardLeague); - guardLeagueCnt.set(guardCity.guardLeague, cnt + 1); + if(!hasGuard) { + let guardCity = lastCities.find(city => city.cityId == cityId && city.groupKey == groupKey); + if(guardCity) { + let cnt = guardLeagueCnt.get(guardCity.guardLeague)||0; + if(cnt < GVG.GVG_CITY_OCCUPIED_NUMBER) { + await addGuardCity(configId, groupKey, cityId, guardCity.guardLeague); + guardLeagueCnt.set(guardCity.guardLeague, cnt + 1); + } } } } - for(let { cityId, groupKey, guardLeague } of lastCities) { - let hasKey = rankKeys.find(cur => cur.cityId == cityId && cur.groupKey == groupKey); - if(hasKey) continue; - await addGuardCity(configId, groupKey, cityId, guardLeague); - } // 联军排行榜发放奖励 let leagueKeys = await findKeys(`${REDIS_KEY.GVG_BATTLE_LEAGUE_RANK}:${configId}:`); @@ -569,11 +582,11 @@ async function addGuardCity(configId: number, groupKey: string, cityId: number, // —————————— 推送相关 —————————— // // 推送 -export async function battleEndSendMessage(groupKey: string, cityId: number, defenseTeam: GVGTeamType, attackTeam: GVGTeamType) { +export async function battleEndSendMessage(groupKey: string, cityId: number, defenseTeam: GVGTeamType, attackTeam: GVGTeamType, attackType: GVG_ATTACK_TYPE) { let areaId = defenseTeam.curTeamBreak? defenseTeam.fromAreaId: defenseTeam.areaId; // 推送伤害 await sendMessageToGVGAreaByTeamWithSuc(groupKey, areaId, PUSH_ROUTE.GVG_TEAM_ATTACKED, { - cityId, areaId, attackType: GVG_ATTACK_TYPE.PLAYER, teams: [new GVGTeamInList(defenseTeam), new GVGTeamInList(attackTeam)] + cityId, areaId, attackType, teams: [new GVGTeamInList(defenseTeam), new GVGTeamInList(attackTeam)] }); await pushTeamBeHurtMessage(defenseTeam, attackTeam); await pushTeamBeHurtMessage(attackTeam); diff --git a/shared/db/GVGTeam.ts b/shared/db/GVGTeam.ts index b7573566b..2cc99b4d1 100644 --- a/shared/db/GVGTeam.ts +++ b/shared/db/GVGTeam.ts @@ -312,20 +312,15 @@ export default class GVGTeam extends BaseModel { } // 投石车伤害 - public static async attackByCatapult(teamCodes: string[], inc: number, rebirthAreaId: number) { - let teams: GVGTeamType[] = []; - for(let teamCode of teamCodes) { - 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: { areaId: rebirthAreaId, pointId: 0, durability: team.maxDurability } }, { new: true }).lean(); - team.originPointId = originPointId; - team.curTeamBreak = true; - } - teams.push(team); + public static async attackByCatapult(teamCode: string, inc: number, rebirthAreaId: number, reviveCd: number) { + 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(); + team.originPointId = originPointId; + team.curTeamBreak = true; } - return teams - + return team; } // 加积分 diff --git a/shared/domain/gvgField/returnData.ts b/shared/domain/gvgField/returnData.ts index a1aa99630..296b87282 100644 --- a/shared/domain/gvgField/returnData.ts +++ b/shared/domain/gvgField/returnData.ts @@ -648,6 +648,7 @@ export class GVGCityMapInfo { export class GVGTeamSpineInMap { spine: number = 0; + roleId: string = ''; roleName: string = ''; serverName: string = ''; startMoveTime: number = 0; @@ -664,6 +665,7 @@ export class GVGTeamSpineInMap { constructor(obj: GVGTeamMem, serverNames: {[serverId: string]: string}) { this.spine = obj.spine; + this.roleId = obj.roleId; this.roleName = obj.roleName; if(obj.serverId) this.serverName = serverNames[obj.serverId]; this.startMoveTime = obj.startMoveTime; @@ -697,6 +699,8 @@ export class GVGTeamInList { leagueName: string; durability: number; // 耐久 maxDurability: number; // 最大耐久 + restartTime: number; + curTeamBreak: boolean; constructor(team: GVGTeamType) { if(!team) return; @@ -711,6 +715,8 @@ export class GVGTeamInList { this.leagueName = team.leagueName; this.durability = team.durability; this.maxDurability = team.maxDurability; + this.restartTime = team.restartTime; + this.curTeamBreak = !!team.curTeamBreak; } }