// GVGTeam 数据库表,存储 GVG 队伍信息 import BaseModel from "./BaseModel"; import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; import { genCode } from "../pubUtils/util"; import { LineupHero } from './../domain/roleField/hero'; import { nowSeconds } from "../pubUtils/timeUtil"; import { GVG } from "../pubUtils/dicParam"; import { DicGVGAreaPoint } from "../pubUtils/dictionary/DicGVGAreaPoint"; @index({ roleId: 1, teamId: 1 }) @index({ teamCode: 1 }) @index({ cityId: 1, leagueId: 1 }) export default class GVGTeam extends BaseModel { @prop({ required: true }) roleId: string; // 玩家id @prop({ required: true }) teamCode: string; // 玩家队伍唯一标识 @prop({ required: true }) teamId: number; // 队伍id,1-3,玩家的第几个队伍 @prop({ required: true }) leagueCode: string; // 联军 @prop({ required: true }) guildCode: string; // 军团 @prop({ required: false }) areaId: number; @prop({ required: false }) cityId: number; @prop({ required: false }) pointId: number; @prop({ required: true }) head: number; // 头像 @prop({ required: true }) spine: number; // 形象 @prop({ required: true }) frame: number; // 相框 @prop({ required: true, default: 0 }) durability: number; // 耐久 @prop({ required: true, default: 0 }) restartTime: number; // 修整期倒计时 @prop({ required: true, default: 0 }) attackTime: number; // 进攻冷却时间 @prop({ required: true, default: 0 }) startMoveTime: number; @prop({ required: true, default: 0 }) stopMoveTime: number; // 移动冷却时间 @prop({ required: true, default: 0 }) defenseTime: number; // 防守保护时间 @prop({ required: true, default: 0 }) point: number; // 积分 @prop({ required: true, type: () => LineupHero, _id: false }) lineup: LineupHero[]; @prop({ required: true }) lineupCe: number; @prop({ required: true }) groupId: number; // 战区 @prop({ required: true }) serverType: number; // 单服还是跨服 @prop({ required: true, default: false }) isRobot: boolean; // 是否是机器人 // 创建队伍 public static async createTeam(roleId: string, leagueCode: string, teamId: number, head: number, spine: number, frame: number, lineup: [LineupHero]) { const doc = new GVGTeamModel(); const teamCode = genCode(8); const update = Object.assign(doc.toJSON(), { roleId, leagueCode, teamId, teamCode, head, spine, frame, lineup }); const team: GVGTeamType | null = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $setOnInsert: update }, { upsert: true, new: true }).lean(); return team; } // 保存队伍 public static async saveTeam(roleId: string, leagueCode: string, teamId: number, head: number, spine: number, frame: number, lineup: [LineupHero]) { let team: GVGTeamType = await GVGTeamModel.findOne({ roleId, teamId }).lean(); if (!team) { team = await this.createTeam(roleId, leagueCode, teamId, head, spine, frame, lineup); return team; } const update = { head, spine, frame }; if (lineup && lineup.length > 0) { update['lineup'] = lineup; } team = await GVGTeamModel.findOneAndUpdate({ roleId, teamId }, { update }, { new: true }).lean(); return team; } // 查找角色队伍数 public static async getTeamCntByRole(roleId: string) { const teams: GVGTeamType[] = await GVGTeamModel.find({ roleId }).select('teamCode').lean(); return teams.length; } // 通过城池ID获取队伍数 public static async getTeamCntByCity(cityId: number, leagueCode?: string) { const query = { cityId }; if (leagueCode) { query['leagueCode'] = leagueCode; } const teams: GVGTeamType[] = await GVGTeamModel.find(query).select('').lean(); return teams.length; } // 玩家切换城池更新队伍信息 public static async enterCity(roleId: string, cityId: number, areaId: number, groupId: number, serverType: number) { const res = await GVGTeamModel.updateMany({ roleId }, { cityId, areaId, pointId: 0, groupId, serverType }).lean(); return !!res['ok']; } // 获取我的编队 public static async findByRole(roleId: string, select = '') { const teams: GVGTeamType[] = await GVGTeamModel.find({ roleId }).select(select).lean(); return teams; } // 获取我的编队 public static async findByTeamCode(roleId: string, teamCode: string, select = '') { const res: GVGTeamType = await GVGTeamModel.findOne({ roleId, teamCode }).select(select).lean(); return res; } // 移动 public static async startMove(teamCode: string, areaId: number) { const res: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { areaId, stopMoveTime: nowSeconds() + GVG.GVG_DEFAULT_MOVE_CD } }).lean(); return res; } public static async stopMove(teamCode: string, areaId: number) { const res: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { areaId, stopMoveTime: nowSeconds() } }).lean(); return res; } // 查询挑战和防守的编队 public static async findBattleTeams(teamCode: string, oppoTeamCode: string) { const teams: GVGTeamType[] = await GVGTeamModel.find({ teamCode: { $in: [ teamCode, oppoTeamCode ] } }).lean(); let attackTeam: GVGTeamType = null, defenseTeam: GVGTeamType = null; for(let team of teams) { if(team.teamCode == teamCode) attackTeam = team; if(team.teamCode == oppoTeamCode) defenseTeam = team; } return { attackTeam, defenseTeam } } public static async checkRobot(groupId: number, serverType: number, cityId: number) { return await GVGTeamModel.exists({ groupId, serverType, cityId, isRobot: true }); } public static async initRobots(groupId: number, serverType: number, cityId: number, dicPoints: DicGVGAreaPoint[]) { await GVGTeamModel.bulkWrite(dicPoints.map(dic => { return { updateOne: { filter: { groupId, serverType, cityId, pointId: dic.pointId }, update: { $setOnInsert: { teamCode: `robot${dic.pointId}`, ...dic, isRobot: true } }, upsert: true } } })); } // 攻击方攻击cd public static async lockAttack(teamCode: string, groupId: number, serverType: number) { const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { attackTime: nowSeconds() + GVG.GVG_DEFAULT_ATTACK_CD, groupId, serverType } }, { new: true }).lean(); return team; } // 防守方防守cd public static async lockDefense(teamCode: string, groupId: number, serverType: number) { const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { attackTime: nowSeconds() + GVG.GVG_DEFAULT_DEFENSE_CD, groupId, serverType } }, { new: true }).lean(); return team; } } export const GVGTeamModel = getModelForClass(GVGTeam); export interface GVGTeamType extends Pick, keyof GVGTeam> { id: number; }; export type GVGTeamUpdate = Partial; // 将所有字段变成可选项