Files
ZYZ/shared/db/ComBattleTeam.ts
2021-10-19 14:26:21 +08:00

342 lines
13 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 BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { EXTERIOR } from '../pubUtils/dicParam';
import { ItemReward } from '../domain/dbGeneral';
import { HeroType } from './Hero';
export class ComRoleStatusHero {
@prop({ required: true })
id: number;
@prop({ required: true })
skinId: number;
@prop({ required: true })
quality: number;
@prop({ required: true })
star: number;
@prop({ required: true })
colorStar: number;
@prop({ required: true })
lv: number;
constructor(hero: HeroType) {
this.id = hero.hid;
this.skinId = hero.skinId;
this.quality = hero.quality;
this.star = hero.star;
this.colorStar = hero.colorStar;
this.lv = hero.lv;
}
}
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: ComRoleStatusHero, default: [], _id: false })
heroes: ComRoleStatusHero[];
// 阵亡武将
@prop({ required: false, type: Number, default: [] })
killed: number[];
// 是否情谊助阵
@prop({ required: false, default: false })
isFrd: boolean;
// 头像
@prop({ required: true, default: EXTERIOR.EXTERIOR_FACE })
head: number;
// 相框
@prop({ required: true, default: EXTERIOR.EXTERIOR_FACECASE })
frame: number;
// 形象
@prop({ required: true, default: EXTERIOR.EXTERIOR_APPEARANCE })
spine: 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: [], type: ItemReward })
fixReward: ItemReward[];
// 队友奖励
@prop({ required: true, default: [], type: ItemReward })
teammateReward: ItemReward[];
// 好友间伤害加成
@prop({ required: true, default: 0 })
frdRatio: number = 0;
constructor(roleId: string, roleName: string, isCap: boolean, isFrd: boolean, head: number, frame: number, spine: number, topLineupCe: number, lv: number, heroes: ComRoleStatusHero[] = [], isRobot = false) {
this.roleId = roleId;
this.roleName = roleName;
this.isCap = isCap;
this.totalDmg = 0;
this.isFrd = isFrd;
this.head = head;
this.frame = frame;
this.spine = spine;
this.topLineupCe = topLineupCe;
this.lv = lv;
this.heroes = heroes;
this.killed = [];
this.isRobot = isRobot;
this.fixReward = [];
}
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;
// 黑名单
blacklist: string[] = [];
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 findByRoleId(roleId: string) {
const team: ComBattleTeamType = await ComBattleTeamModel.findOne({ roleIds: { $in: [roleId] }}).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: ComRoleStatusHero[], 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: ComRoleStatusHero[], 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 getBlueprtInUse(roleId: string, status: number, blueprtId: number, lean = true) {
const teams: ComBattleTeamType[] = await ComBattleTeamModel.find({capId: roleId, status, blueprtId}).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>;