import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, Ref, mongoose } from '@typegoose/typegoose'; import Hero, { } from './Hero'; import Role, { } from './Role'; import PvpDef, { } from './PvpDefense'; import { PVP_PLAYER_POS, PVP_POS } from '../consts'; import SystemConfig, { } from './SystemConfig'; class Heroes { @prop({ required: true }) actorId: number; // 武将id @prop({ ref: Hero, type: mongoose.Schema.Types.ObjectId }) hero: Ref; @prop({ required: true }) ce: number; // 战斗力 @prop({ required: true }) pos: number; @prop({ required: true }) order: number; } // 初始化 function getInitialOppPlayers() { let players = new Array(); for(let i = PVP_PLAYER_POS.START; i <= PVP_PLAYER_POS.END; i++) { let p = new OppPlayers(); p.pos = i; players.push(p); } return players; } // 初始化 function getInitialOppHeros() { let players = new Array(); for(let i = PVP_POS.START; i <= PVP_POS.END; i++) { let p = new OppPlayers(); p.pos = i; players.push(p); } return players; } class Robot { @prop({ required: true }) roleId: string; // 角色 id @prop({ required: true }) roleName: string; // 角色名称 @prop({ required: true }) headHid: number; @prop({ required: true }) sHid: number; @prop({ required: true }) topFiveCe: number; } class OppPlayers { @prop({ ref: 'PvpDefense', type: mongoose.Schema.Types.ObjectId }) oppDef: Ref; @prop({ required: true }) pos: number; @prop({ required: true }) isRobot: boolean; @prop({ required: true, type: Robot, default: null, _id: false }) robot: Robot } class HidScores { @prop({ required: true }) hid: number; @prop({ required: true }) score: number; } @index({ roleId: 1 }) export default class PvpDefense extends BaseModel { @prop({ required: true }) roleId: string; // 角色 id @prop({ required: true }) roleName: string; // 角色名称 @prop({ ref: 'Role', type: mongoose.Schema.Types.ObjectId }) role: Ref; @prop({ required: true, type: Heroes, default: getInitialOppHeros(), _id: false }) heroes: Array; @prop({ required: true, default: 0 }) score: number; @prop({ required: true, default: 0 }) hisScore: number; //历史最高积分 @prop({ required: true, default: 0 }) winStreakNum: number; //连胜次数 @prop({ required: true, default: 0 }) defCe: number; //防守ce @prop({ required: true, type: OppPlayers, default: getInitialOppPlayers(), _id: false }) oppPlayers: Array; @prop({ ref: 'SystemConfig', type: mongoose.Schema.Types.ObjectId }) map: Ref; @prop({ required: true, type: HidScores, default: [] }) hidScores: Array; public static async findByRoleId(roleId: string, lean = true) { const result: PvpDefenseType = await PvpDefenseModel.findOne({ roleId }).lean(lean); return result; } public static async findByScale(roleId: string, min: number, max: number, lean = true) { const result: PvpDefenseType[] = await PvpDefenseModel.find({ roleId: { $ne: roleId }, defCe: { $lte: max, $gte: min } }).sort({ updatedAt: -1 }).limit(100).lean(lean); return result; } public static async createPvpDefense(params: { roleId: string, roleName: string, heroes: Array, defCe: number }, lean = true) { const doc = new PvpDefenseModel(); const update = Object.assign(doc.toJSON(), params); const defense: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId: params.roleId }, update, { upsert: true, new: true }).lean(lean); return defense; } public static async addHeroToDefense(roleId: string, heroInfo: any, defCe: number, lean = true) { const defense: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId: roleId }, { $inc: { defCe }, $push: { heroes: heroInfo } }, { upsert: true, new: true }).lean(lean); return defense; } public static async removeHeroFromDefense(roleId: string, hid: number, defCe: number, lean = true) { const defense: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId: roleId }, { $inc: { defCe: -1 * defCe }, $pull: { heroes: { actorId: hid } } }, { upsert: true, new: true }).lean(lean); return defense; } public static async updateCe(roleId: string, hid: number, defCe: number, lean = true) { const rec: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId, 'heroes.actorId': hid }, { $set: { defCe } }).lean(lean); return rec } public static async deleteAccount(roleId: string) { let result = await PvpDefenseModel.deleteMany({ roleId }); return result; } } export const PvpDefenseModel = getModelForClass(PvpDefense); export interface PvpDefenseType extends Pick, keyof PvpDefense> { };