Files
ZYZ/shared/db/ComBattleTeam.ts
T
2021-02-25 13:36:10 +08:00

295 lines
12 KiB
TypeScript

import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
export class RoleStatus {
@prop({ required: true })
roleId: string;
@prop({ required: true })
roleName: string;
@prop({ required: true })
isCap: boolean;
@prop({ required: true, default: 0 })
totalDmg: number;
// 战斗状态 0-挑战中 1-挑战成功 2-挑战失败
@prop({ required: true, default: 0 })
battleStatus: number;
// 队伍中每个玩家的战斗编号
@prop({ required: false, default: '' })
battleCode: string;
// 玩家所用阵容
@prop({ required: false, type: Number, default: [] })
heroes: number[];
// 阵亡武将
@prop({ required: false, type: Number, default: [] })
killed: number[];
// 是否情谊助阵
@prop({ required: false, default: false })
isFrd: boolean;
// 头像
@prop({ required: true, default: 19 })
headHid: number;
// 形象
@prop({ required: true, default: 19 })
sHid: number;
// 前五战力
@prop({ required: true, default: 0 })
topLineupCe: number;
// 主公等级
@prop({ required: true, default: 1 })
lv: number;
// 是否机器人
@prop({ required: true, default: false })
isRobot: boolean;
// 是否领奖
@prop({ required: true, default: false })
gotReward: boolean;
// 固定奖励
@prop({ required: true, default: '&' })
fixReward: string;
// 好友间伤害加成
@prop({ required: true, default: 0 })
frdRatio: number = 0;
constructor(roleId: string, roleName: string, isCap: boolean, isFrd: boolean, headHid: number, sHid: number, topLineupCe: number, lv: number, heroes = [], isRobot = false) {
this.roleId = roleId;
this.roleName = roleName;
this.isCap = isCap;
this.totalDmg = 0;
this.isFrd = isFrd;
this.headHid = headHid;
this.sHid = sHid;
this.topLineupCe = topLineupCe;
this.lv = lv;
this.heroes = heroes;
this.killed = [];
this.isRobot = isRobot;
}
addFrdRatio(frdRatio: number) {
if(!this.frdRatio) {
this.frdRatio = frdRatio;
} else {
this.frdRatio += frdRatio;
}
}
}
export class BossHp {
// boss 战场标识
@prop({ required: true, default: 0 })
dataId: number;
// boss 战场标识
@prop({ required: true, default: 0 })
actorId: number;
// 总血量
@prop({ required: true, default: 0 })
hp: number;
// 当前血量
@prop({ required: true, default: 0 })
curHp: number;
}
@index({ teamCode: 1 })
@index({ roleIds: 1 })
@index({ status: 1, blueprtId: 1, pub: 1})
export default class ComBattleTeam extends BaseModel {
// 队伍唯一编号
@prop({ required: true })
teamCode: string;
@prop({ required: true, type: String, default: [], _id: false })
roleIds: string[];
// 队伍是否开放加入
@prop({ required: true, default: true })
pub: boolean;
// 对应藏宝图 Id
@prop({ required: true })
blueprtId: number;
// 藏宝图品质
@prop({ required: true })
quality: number;
// 战斗状态 0:未开始,1:已开始,2:胜利,3:失败
@prop({ required: true, default: 0 })
status: number;
@prop({ required: true, type: RoleStatus, default: [] })
roleStatus: RoleStatus[];
// 队长 roleId
@prop({ required: true })
capId: string;
// 战力限制
@prop({ required: true, default: 0 })
ceLimit: number;
// 队伍中人数
@prop({ required: true, default: 1 })
roleCnt: number;
// 藏宝图等级所处范围,用来匹配
@prop({ required: true, default: 1 })
lvRange: number;
// 单个 boss 血量状态
@prop({ required: false, type: BossHp, default: [] })
bossHpArr: BossHp[];
// 队伍是否开放加入
@prop({ required: true, default: false })
timeout: boolean;
public static async createTeam(teamData: ComBattleTeamParam, lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOneAndUpdate({ teamCode: teamData.teamCode }, {$set :{...teamData, roleCnt: teamData.roleIds.length}}, {upsert: true, new: true}).lean(lean);
return team;
}
public static async addRole(teamCode: string, roleStatus: RoleStatus, lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOneAndUpdate({ teamCode, roleCnt: { $lte: 2 } }, {$push: {roleIds: roleStatus.roleId, roleStatus}, $inc: {roleCnt: 1}}, {new: true}).lean(lean);
return team;
}
public static async removeRole(teamCode: string, roleIdToRm: string, lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOneAndUpdate({ teamCode }, {$pull: {roleIds: roleIdToRm, roleStatus: {roleId: roleIdToRm}}, $inc: {roleCnt: -1}}, {new: true}).lean(lean);
return team;
}
public static async updateRoleStFrd(teamCode: string, roleId: string, isFrd: boolean, lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOneAndUpdate({ teamCode, 'roleStatus.roleId': roleId }, { $set: {'roleStatus.$.isFrd': isFrd}}, {new: true}).lean(lean);
return team;
}
public static async removeTeam(teamCode: string, lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOneAndDelete({ teamCode }).lean(lean);
return team;
}
public static async updateHeroes(teamCode: string, roleId: string, heroes: number[], lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOneAndUpdate({ teamCode, 'roleStatus.roleId': roleId}, {$set: {'roleStatus.$.heroes': heroes}}, {new: true}).lean(lean);
return team;
}
public static async setupBattleInfo(teamCode: string, roleId: string, heroes: number[], battleCode: string, lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOneAndUpdate({ teamCode, 'roleStatus.roleId': roleId}, {$set: {'roleStatus.$.heroes': heroes, 'roleStatus.$.battleCode': battleCode}}, {new: true}).lean(lean);
return team;
}
public static async updateRewardSt(teamCode: string, roleId: string, gotReward: boolean, lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOneAndUpdate({ teamCode, 'roleStatus.roleId': roleId}, {$set: {'roleStatus.$.gotReward': gotReward}}).lean(lean);
return team;
}
public static async syncTeamData(teamData: {teamCode: string, status: number, roleStatus: RoleStatus[], bossHpArr: BossHp[]}, timeout = false, lean = true) {
console.log('syncTeamData bossHpArr: ', teamData.bossHpArr);
const team: ComBattleTeamType = await ComBattleTeamModel.findOneAndUpdate({ teamCode: teamData.teamCode }, {$set :{...teamData, roleCnt: teamData.roleStatus.length, timeout}}, {new: true}).lean(lean);
return team;
}
public static async updateStatusByCode(teamCode: string, status: number, lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOneAndUpdate({ teamCode: teamCode }, {status}, {new: true}).lean(lean);
return team;
}
public static async updateStatusByStatus(preStatus: number, newStatus: number, lean = true) {
const team = await ComBattleTeamModel.updateMany({ status: preStatus }, {status: newStatus}, {new: true}).lean(lean);
return team;
}
public static async updateResult(teamCode: string, roleId: string, isSuccess: boolean, _lean = true) {
let team = await ComBattleTeamModel.findOne({teamCode}).select('status roleStatus');
if(!team) return;
if (isSuccess === true) {
team.status = 2;
team.roleStatus.forEach(st => {
if (st.battleStatus !== 2) {
st.battleStatus = 1;
}
})
} else if (isSuccess === false) {
let loseCnt = 1;
team.roleStatus.forEach(st => {
if (st.battleStatus === 2 && st.roleId !== roleId) {
loseCnt += 1;
} else if (st.roleId === roleId && !st.battleStatus) {
st.battleStatus = 2;
}
});
if (loseCnt === team.roleStatus.length) {
team.status = 3;
}
}
await team.save();
return team;
}
public static async getTeamByCapAndStatus(roleId: string, status: number, lean = true) {
const teams: ComBattleTeamType[] = await ComBattleTeamModel.find({capId: roleId, status}).lean(lean);
return teams;
}
public static async getTeamByBlueprt(blueprtIds: number[], status: number, pub = true, limit = 50, lean = true) {
const teams: ComBattleTeamType[] = await ComBattleTeamModel.find({blueprtId: {$in: blueprtIds}, status, pub}).limit(limit).lean(lean);
return teams;
}
public static async getOneTeamByQualityAndSt(qualityArr: number[], status: number, ce = 0, pub = true, cntLmt = 2, lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOne({quality: {$in: qualityArr}, status, ceLimit: {$lte: ce}, pub, roleCnt: {$lte: cntLmt}}).lean(lean);
return team;
}
public static async getOtherTeamByQualityAndSt(roleId: string, qualityArr: number[], status: number, lvRange: number, ce = 0, pub = true, cntLmt = 2, lean = true) {
const curTime = new Date(Date.now() - 10 * 60 * 1000); // 10分钟之前
const team: ComBattleTeamType[] = await ComBattleTeamModel.find({quality: {$in: qualityArr}, status, lvRange, ceLimit: {$lte: ce}, pub, roleCnt: {$lte: cntLmt}, roleIds: {$nin: [roleId]}, updatedAt: {$gte: curTime}}).lean(lean);
return team;
}
public static async getTeamByRoleAndTime(roleId: string, qualityArr?: number[], time?: Date, isAssist?: boolean, limitCnt = 50, lean = true) {
let query = {roleIds: roleId};
if (qualityArr) {
query = Object.assign(query, {quality: {$in: qualityArr}});
}
if (time) {
query = Object.assign(query, {createdAt: {$gte: time}});
}
if (isAssist) {
query = Object.assign(query, {capId: {$ne: roleId}});
}
const teams: ComBattleTeamType[] = await ComBattleTeamModel.find(query).limit(limitCnt).sort({createdAt: -1}).lean(lean);
return teams;
}
public static async getAssistTeamsByTime(roleId: string, qualityArr?: number[], time?: Date, isAssist?: boolean, lean = true) {
let query = {roleIds: roleId, status: {$in: [0, 1, 2]}}; // 失败不计入助战
if (qualityArr) {
query = Object.assign(query, {quality: {$in: qualityArr}});
}
if (time) {
query = Object.assign(query, {createdAt: {$gte: time}});
}
if (isAssist) {
query = Object.assign(query, {capId: {$ne: roleId}});
}
const teams: ComBattleTeamType[] = await ComBattleTeamModel.find(query).lean(lean);
return teams;
}
public static async getTeamByRoleAndBattleCode(roleId: string, battleCode: string, lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOne({roleIds: roleId, 'roleStatus.battleCode': battleCode}).lean(lean);
return team;
}
public static async getTeamByCode(teamCode: string, lean = true) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOne({teamCode}).lean(lean);
return team;
}
}
export const ComBattleTeamModel = getModelForClass(ComBattleTeam);
export interface ComBattleTeamType extends Pick<DocumentType<ComBattleTeam>, keyof ComBattleTeam>{};
export type ComBattleTeamParam = Partial<ComBattleTeamType>;