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'; 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: PvpDef, type: mongoose.Schema.Types.ObjectId }) oppDef: Ref; @prop({ required: true }) pos: number; @prop({ required: true }) isRobot: boolean; @prop({ required: true, type: Robot, default: [], _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({ required: true, default: 0 }) map: number; @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 }, ce: { $lte: max, $gte: min } }).sort({ updatedAt: -1 }).limit(100).lean(lean); return result; } public static async createPvpDefense(params: { roleId: string, roleName: string, heroes: Array, ce: 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, ce: number, lean = true) { const defense: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId: roleId }, { $inc: { ce }, $push: { heroes: heroInfo } }, { upsert: true, new: true }).lean(lean); return defense; } public static async removeHeroFromDefense(roleId: string, hid: number, ce: number, lean = true) { const defense: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId: roleId }, { $inc: { ce: -1 * ce }, $pull: { heroes: { actorId: hid } } }, { upsert: true, new: true }).lean(lean); return defense; } public static async updateCe(roleId: string, hid: number, ce: number, lean = true) { const rec: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({ roleId, 'heroes.actorId': hid }, { $set: { ce } }).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> { };