Files
ZYZ/game-server/app/services/gvg/gvgBattleMemory.ts
2023-03-10 13:30:03 +08:00

256 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 存在激战期的内存数据
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<string, GVGBattleData> = new Map();
class GVGBattleData {
public groupKey: string; // 战区
private teams: Map<string, GVGTeamMem> = new Map(); // 队伍, teamCode => team
public rolePoints: Map<string, Map<number, string>> = new Map(); // roleId => pointId[],用于更新玩家的积分
private roleToTeam: Map<string, string[]> = new Map(); // roleId => teamCode
private leagueToTeam: Map<string, Set<string>> = new Map(); // leagueCode => teamCode
public areaToTeams: Map<number, Set<string>> = new Map(); // areaId => teamCode set用于定时下发地图玩家数据
private leagueActiveTech: Map<string, number[]> = 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<string, number[]>();
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(dispatch(team.cityId.toString(), servers)?.id == sid) {
let teamObj = getGVGBattleData(team.groupKey);
teamObj.enterCity(team);
}
}
}
export function clearBattleMemory() {
gvgBattleMap.clear();
}