// 存在激战期的内存数据 import { pinus } from "pinus"; import { GVG_CATAPULT, GVG_PERIOD } from "../../consts"; import { GVGTeamModel, GVGTeamType } from "../../db/GVGTeam"; import { GVGTeamMem } from "../../domain/battleField/gvgBattle"; import { dispatch } from "../../pubUtils/dispatcher"; import { getGVGPeriodData } from "./gvgService"; import { redisClient } from "../redisService"; // 积分点占领情况,groupId_serverType_cityId -> GVGBattleData const gvgBattleMap: Map = new Map(); class GVGBattleData { public groupKey: string; // 战区 private teams: Map = new Map(); // 队伍, teamCode => team public rolePoints: Map> = new Map(); // roleId => pointId[],用于更新玩家的积分 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; } public findTeamsByArea(areaId: number, count: number) { let teamCodes = this.areaToTeams.get(areaId)||new Set(); let otherTeams: GVGTeamMem[] = [], robots: GVGTeamMem[] = [], points: GVGTeamMem[] = []; for(let teamCode of teamCodes) { let team = this.teams.get(teamCode); if(team && !team.isBroken) { if(team.pointId > 0) { points.push(team); continue; } if(team.isRobot) { robots.push(team); continue; } otherTeams.push(team); } } let teams = [...points, ...robots, ...otherTeams]; return teams.slice(0, count); } public findCatapultAttackTeam(areaId: number, leagueCode: 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(team); } return teams; } public leaveCity(roleId: string) { let teamCodes = this.roleToTeam.get(roleId)||[]; for(let teamCode of teamCodes) { let team = this.teams.get(teamCode); if(team) team.setCity(0); for(let [_areaId, teamSet] of this.areaToTeams) { if(teamSet.has(teamCode)) teamSet.delete(teamCode); } if(team.leagueCode && this.leagueToTeam.has(team.leagueCode)) this.leagueToTeam.get(team.leagueCode).delete(teamCode); } this.rolePoints.delete(roleId); } public enterCity(...teams: GVGTeamType[]) { for(let team of teams) { let fromAreaId = this.teams.get(team.teamCode)?.areaId||0; if(!this.teams.has(team.teamCode)) { this.teams.set(team.teamCode, new GVGTeamMem(team)) } else { this.teams.get(team.teamCode).updateTeam(team); } 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)||[]; if(teamCodesOfRole.indexOf(team.teamCode) == -1) teamCodesOfRole.push(team.teamCode); this.roleToTeam.set(team.roleId, teamCodesOfRole); if(team.leagueCode) { if(!this.leagueToTeam.has(team.leagueCode)) { this.leagueToTeam.set(team.leagueCode, new Set()); } if(!this.leagueToTeam.get(team.leagueCode).has(team.teamCode)) this.leagueToTeam.get(team.leagueCode).add(team.teamCode); } this.setAreaMap(team.teamCode, fromAreaId, team.areaId, 'enterCity'); } } private setAreaMap(teamCode: string, fromAreaId: number, toAreaId: number, fromFun) { if(fromAreaId == toAreaId) return; // console.log('#### gvgBattleMemory setAreaMap', 'teamCode:', teamCode, 'fromAreaId: ', fromAreaId, 'toAreaId:', toAreaId, 'appid', pinus.app.getServerId(), 'from', fromFun) let fromAreaSet = this.areaToTeams.get(fromAreaId); if(fromAreaSet && fromAreaSet.has(teamCode)) fromAreaSet.delete(teamCode); if(!this.areaToTeams.has(toAreaId)) { this.areaToTeams.set(toAreaId, new Set()); } if(!this.areaToTeams.get(toAreaId).has(teamCode)) { this.areaToTeams.get(toAreaId).add(teamCode); } } private setRolePoints(roleId: string, fromPointId: number, pointId: number, teamCode: string) { if(fromPointId > 0) { // 被打得撤离积分点 if(this.rolePoints.has(roleId) && this.rolePoints.get(roleId).has(fromPointId)) { this.rolePoints.get(roleId).delete(fromPointId); } } if (pointId > 0) { if(!this.rolePoints.has(roleId)) this.rolePoints.set(roleId, new Map()); this.rolePoints.get(roleId).set(pointId, teamCode); } } public move(teamCode: string, areaId: number, fromAreaId: number, startMoveTime: number, stopMoveTime: number) { let team = this.teams.get(teamCode); if(!team) return; team.moveToArea(areaId, fromAreaId, startMoveTime, stopMoveTime); this.setAreaMap(teamCode, fromAreaId, areaId, 'move'); } public setTime(teamCode: string, teamUpdate: GVGTeamType) { let team = this.teams.get(teamCode); if(!team) return; team.attackTime = teamUpdate.attackTime; team.defenseTime = teamUpdate.defenseTime; } // 队伍入驻积分点 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, teamCode); teamMem.pointId = pointId; } // 关卡结算 public battleEnd(teams: GVGTeamType[]) { for(let team of teams) { let teamMem = this.teams.get(team.teamCode); if(!teamMem) { // 基本不会有没有这个内存的情况,有的话就让他重新计算一次吧 this.enterCity(team); continue; } let { curTeamBreak, pointId } = team; let { areaId: fromAreaId, pointId: originPointId } = teamMem; teamMem.updateTeam(team); this.setRolePoints(team.roleId, originPointId, curTeamBreak? 0: pointId, team.teamCode); this.setAreaMap(team.teamCode, fromAreaId, team.areaId, 'battleEnd'); } } // 投石车 public findCatapult() { return this.findTeamsByRole(GVG_CATAPULT); } public findTeamsByRole(roleId: string) { let teamCodes = this.roleToTeam.get(roleId)||[]; return teamCodes.map(teamCode => this.teams.get(teamCode)); } // 积分点情况 public findSettledPoint() { let teams: GVGTeamMem[] = []; for(let [_roleId, pointIds] of this.rolePoints) { for(let [pointId, teamCode] of pointIds) { let team = this.teams.get(teamCode); if(pointId > 0 && team) teams.push(team); } } return teams; } public findSettledPointMapByLeague(cityId: number) { let pointByLeague = new Map(); for(let [_roleId, pointIds] of this.rolePoints) { for(let [pointId, teamCode] of pointIds) { let team = this.teams.get(teamCode); if(pointId > 0 && team && team.leagueCode && team.cityId == cityId) { if(!pointByLeague.has(team.leagueCode)) pointByLeague.set(team.leagueCode, []); pointByLeague.get(team.leagueCode).push(team.pointId); }; } } return pointByLeague; } public findAreas() { return this.areaToTeams.keys(); } public updateLeagueInfo(leagueCode: string, leagueName: string) { let teamCodes = this.leagueToTeam.get(leagueCode)||new Set(); for(let teamCode of teamCodes) { let team = this.teams.get(teamCode); team.leagueName = leagueName; } } public updateRoleInfo(roleId: string, info: { roleName?: string, lv?: number }) { let teamCodes = this.leagueToTeam.get(roleId)||new Set(); for(let teamCode of teamCodes) { let team = this.teams.get(teamCode); if(info.roleName) team.roleName = info.roleName; 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) { if(!gvgBattleMap.has(groupKey)) { gvgBattleMap.set(groupKey, new GVGBattleData(groupKey)); } return gvgBattleMap.get(groupKey); } export function getGVGBattleMap() { return gvgBattleMap; } export async function initTeamToMem() { let sid = pinus.app.getServerId(); let servers = pinus.app.getServersByType('guild'); let { configId, period } = getGVGPeriodData(); if(period != GVG_PERIOD.BATTLE) return; let teams = await GVGTeamModel.findByConfigId(configId); for(let team of teams) { if(team.isBroken) continue; if((await dispatch(redisClient(), team.cityId.toString(), servers, 'guild'))?.id == sid) { let teamObj = getGVGBattleData(team.groupKey); teamObj.enterCity(team); } } } export function clearBattleMemory() { gvgBattleMap.clear(); }