// 存在激战期的内存数据 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"; // 积分点占领情况,groupId_serverType_cityId -> GVGBattleData const gvgBattleMap: Map = new Map(); class GVGBattleData { public groupKey: string; // 战区 private teams: Map = new Map(); // 队伍, teamCode => team private rolePoints: Map> = new Map(); // roleId => pointId[],用于更新玩家的积分 private roleToTeam: Map = new Map(); // roleId => teamCode public areaToTeams: Map> = new Map(); // areaId => teamCode set,用于定时下发地图玩家数据 constructor(groupKey: string) { this.groupKey = groupKey; } public findTeamsByArea(areaId: number) { let teamCodes = this.areaToTeams.get(areaId)||new Set(); let teams: GVGTeamMem[] = []; for(let teamCode of teamCodes) { let team = this.teams.get(teamCode); if(team && !team.isBroken) teams.push(team); } return teams.slice(0, 20); } public findCatapultAttackTeam(areaIds: number[], leagueCode: string) { let teams: string[] = []; for(let areaId of areaIds) { 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); } } 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); } } 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)) } 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()); 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); this.setAreaMap(team.teamCode, fromAreaId, team.areaId); } } private setAreaMap(teamCode: string, fromAreaId: number, toAreaId: number) { if(fromAreaId == toAreaId) return; 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 && pointId == 0) { // 被打得撤离积分点 if(this.rolePoints.has(roleId) && this.rolePoints.get(roleId).has(fromPointId)) { this.rolePoints.get(roleId).delete(fromPointId); } } else if (fromPointId == 0 && 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); } 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); } } // 投石车 public findCatapult() { let teamCodes = this.roleToTeam.get(GVG_CATAPULT)||[]; 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() { 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) { if(!pointByLeague.has(team.leagueCode)) pointByLeague.set(team.leagueCode, []); pointByLeague.get(team.leagueCode).push(team.pointId); }; } } return pointByLeague; } public findAreas() { return this.areaToTeams.keys(); } } 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(dispatch(team.cityId.toString(), servers)?.id == sid) { let teamObj = getGVGBattleData(team.groupKey); teamObj.enterCity(team); } } } export function clearBattleMemory() { gvgBattleMap.clear(); }