274 lines
10 KiB
TypeScript
274 lines
10 KiB
TypeScript
import BaseModel from './BaseModel';
|
||
import { getModelForClass, prop, DocumentType, index } from '@typegoose/typegoose';
|
||
|
||
|
||
export class RewardInter {
|
||
@prop({ required: true })
|
||
id: number;
|
||
@prop({ required: true })
|
||
count: number;
|
||
@prop({ required: true })
|
||
expireTime?: number;
|
||
}
|
||
|
||
export class Quest {
|
||
@prop({ required: true, default: 0 })
|
||
randomEventId: number; //问号点:随机事件id
|
||
|
||
@prop({ required: true, type: Number, default: [], _id: false })
|
||
EventOptions: number[]; // 问号点用:随机事件的选项
|
||
}
|
||
|
||
export class RecoveryChara {
|
||
@prop({ required: true, default: '' })
|
||
charaCode: string
|
||
@prop({ required: true, default: 0 })
|
||
charaId: number; // 恢复的武将
|
||
@prop({ required: true, default: 0 })
|
||
beforeHp: number; // 恢复前的hp
|
||
@prop({ required: true, default: 0 })
|
||
afterHp: number; // 恢复后的hp
|
||
}
|
||
|
||
export class Recruit {
|
||
@prop({ required: true, default: 0 })
|
||
index: number; // 索引
|
||
|
||
@prop({ required: true, default: 0 })
|
||
charaId: number; // 角色卡id
|
||
|
||
@prop({ required: true, default: 0 })
|
||
status: number; // 0-未领取 1-已领取
|
||
};
|
||
|
||
|
||
export class TrainCard {
|
||
@prop({ required: true, default: '' })
|
||
cardCode: string;
|
||
@prop({ required: true, default: 0 })
|
||
cardId: number; // 特训的卡牌
|
||
@prop({ required: true, default: 0 })
|
||
beforeLv: number; // 特训前等级
|
||
@prop({ required: true, default: 0 })
|
||
afterLv: number; // 特训后等级
|
||
};
|
||
|
||
export class RestPoint {
|
||
@prop({ required: true })
|
||
restType: number; // 休整点用:玩家选择的类型
|
||
|
||
@prop({ required: false })
|
||
recoveryCnt?: number; // 恢复的次数
|
||
|
||
@prop({ required: false, type: RecoveryChara, _id: false })
|
||
recoveryCharas?: RecoveryChara[];//恢复的数据
|
||
|
||
// @prop({ required: false, type: Recruit })
|
||
// recruits: Recruit[]; // 休整点:提供的随机可供招募的武将
|
||
|
||
@prop({ required: false })
|
||
trainCardCnt?: number; //休整点:特训 特训次数
|
||
|
||
@prop({ required: false, type: TrainCard, _id: false })
|
||
trainCards?: TrainCard[]; //特训卡
|
||
}
|
||
|
||
export class Challenge {
|
||
@prop({ required: true, default: 0 })
|
||
challengeId: number; // 挑战id
|
||
@prop({ required: true, default: 0 })
|
||
status: number; // 0-未选择 1-已选择 2-已达成 3-已领取
|
||
@prop({ required: true, default: 0 })
|
||
progress: number; // 挑战进度
|
||
};
|
||
|
||
export class Shop {
|
||
@prop({ required: true, default: 0 })
|
||
optionIndex: number; //商店物品索引
|
||
@prop({ required: true, default: 0 })
|
||
rewardType: number; //特性卡、圣物类型
|
||
@prop({ required: true, default: 0 })
|
||
rewardId: number; // 特性卡、圣物id
|
||
@prop({ required: true, default: 0 })
|
||
optionStatus: number; // 0-未领取 1-已领取
|
||
@prop({ required: true, default: 0 })
|
||
price: number; // 原价
|
||
@prop({ required: true, default: 0 })
|
||
discountPrice: number; //购买时折扣价格
|
||
}
|
||
|
||
export class WeightRecord {
|
||
@prop({ required: false, default: 0 })
|
||
originalWight?: number;
|
||
@prop({ required: false, default: 0 })
|
||
passiveRedWight?: number;
|
||
@prop({ required: false, default: 0 })
|
||
holyRedWight?: number;
|
||
@prop({ required: false, default: 0 })
|
||
authorAddWeight?: number;
|
||
@prop({ required: false, default: 0 })
|
||
passiveLableNum?: number;
|
||
@prop({ required: false, default: 0 })
|
||
passiveLableNumAddWeight?: number;
|
||
@prop({ required: false, default: 0 })
|
||
holyLableNum?: number;
|
||
@prop({ required: false, default: 0 })
|
||
holyLableNumAddWeight?: number;
|
||
@prop({ required: false, default: 0 })
|
||
finalWeight?: number;
|
||
@prop({ required: false, default: 0 })
|
||
holyAddWeight?: number;
|
||
}
|
||
export class RandomRec {
|
||
@prop({ required: false, default: 0 })
|
||
id?: number;
|
||
@prop({ required: false, default: 0 })
|
||
planId?: number; // 方案编号
|
||
@prop({ required: false, default: 0 })
|
||
cardId?: number; // 角色卡id
|
||
@prop({ required: false, default: 0 })
|
||
weight?: number; // 权重
|
||
@prop({ required: false, type: WeightRecord, default: {}, _id: false })
|
||
weightRecord?: WeightRecord;
|
||
}
|
||
|
||
export class Option {
|
||
@prop({ required: true, default: 0 })
|
||
optionIndex: number;
|
||
@prop({ required: true, default: 0 })
|
||
rewardId: number; // 角色卡、特性卡、圣物id
|
||
@prop({ required: true, default: 0 })
|
||
optionStatus: number; // 0-未领取 1-已领取
|
||
|
||
@prop({ required: false, type: Number, default: [], _id: false })
|
||
passiveCardIds?: number[]; //高级学员自带特性卡
|
||
|
||
// @prop({ required: false, type: WeightRecord, default: {} })
|
||
// weightRecord?: WeightRecord //用于测试权重记录
|
||
}
|
||
export class RewardIn {
|
||
@prop({ required: true, default: 0 })
|
||
groupIndex: number; // 组index
|
||
@prop({ required: true, default: 0 })
|
||
rewardType: number; // 奖励类型
|
||
@prop({ required: false, type: Option, _id: false })
|
||
options?: Option[]; // 组内随机的奖励
|
||
@prop({ required: true, default: 0 })
|
||
groupStatus: number; // 组选择 0-未选择 1-已选择
|
||
@prop({ required: true, default: 0 })
|
||
chooseNum: number; // 这一组总共能选的数量3选2
|
||
@prop({ required: false, default: 0 })
|
||
reRandRewardCnt: number; // 重新随机奖励
|
||
}
|
||
|
||
/**
|
||
* 每场的每层选择的关卡的数据
|
||
*/
|
||
@index({ roleId: 1 })
|
||
@index({ gameCode: 1 })
|
||
@index({ gameCode: 1, detailCode: 1 })
|
||
@index({ gameCode: 1, layer: 1, nodeId: 1 })
|
||
|
||
|
||
|
||
export default class RougelikeRecordDetail extends BaseModel {
|
||
@prop({ required: true })
|
||
roleId: string; //角色id
|
||
|
||
@prop({ required: true, default: '' })
|
||
gameCode: string; // 每场唯一code
|
||
|
||
@prop({ required: true, default: '' })
|
||
detailCode: string; // 层+关卡id唯一code
|
||
|
||
@prop({ required: true, default: 0 })
|
||
layer: number; // 层
|
||
|
||
@prop({ required: true, default: 0 })
|
||
nodeId: number; // 关卡id
|
||
|
||
@prop({ required: true, default: 0 })
|
||
nodeType: number; // 关卡类型 普通关、精英关、挑战关、试炼商店、休整点、问号点、boss
|
||
|
||
|
||
@prop({ required: false })
|
||
warId?: number; // 关卡id //【普通关、精英关、boss关】
|
||
|
||
@prop({ required: false })
|
||
battleCode?: string; // battleRecord的code
|
||
|
||
@prop({ required: true, default: 0 })
|
||
status: number; // 关卡状态 0-默认值 1-成功 2-失败
|
||
|
||
@prop({ required: false, type: Quest, default: [], _id: false })
|
||
question?: Quest; // 问好点随机事件
|
||
|
||
@prop({ required: false, default: 0 })
|
||
questType?: number; // 问好点随机type
|
||
|
||
@prop({ required: false, type: RestPoint, default: [], _id: false })
|
||
restPoints?: RestPoint[];
|
||
|
||
@prop({ required: false, type: Challenge, default: {}, _id: false })
|
||
challenge?: Challenge; // 【挑战点】
|
||
|
||
@prop({ required: false, type: Shop, default: [], _id: false })
|
||
shops?: Shop[]; // 商店内的随机商品
|
||
|
||
@prop({ required: false, type: RewardIn, default: [], _id: false })
|
||
rewards?: RewardIn[]; // 通用过关后的奖励,挑战后的奖励
|
||
|
||
@prop({ required: false, type: RandomRec, default: [], _id: false })
|
||
weightRecords?: RandomRec[];
|
||
|
||
public static async updateByCode(gameCode: string, detailCode: string, params: { $set: RougelikeRecordDetailPara, $inc?: { reRandRewardCnt: 1 } }, lean = true) {
|
||
const result: RougelikeRecordDetailType = await RougelikeRecordDetailModel.findOneAndUpdate({ gameCode, detailCode }, params, { new: true, upsert: true }).lean(lean);
|
||
return result;
|
||
}
|
||
|
||
public static async updateRewardByGroupIndex(gameCode: string, detailCode: string, groupIndex: number, groupStatus: number, options: Option[], params?: { $set: RougelikeRecordDetailPara }, lean = true) {
|
||
const result: RougelikeRecordDetailType = await RougelikeRecordDetailModel.findOneAndUpdate({ gameCode, detailCode, 'rewards.groupIndex': groupIndex }, { ...params, 'rewards.$.options': options, 'rewards.$.groupStatus': groupStatus, }, { new: true, upsert: true }).lean(lean);
|
||
return result;
|
||
}
|
||
public static async updateShopByCode(gameCode: string, detailCode: string, optionIndex: number, optionStatus: number, params?: { $set: RougelikeRecordDetailPara }, lean = true) {
|
||
const result: RougelikeRecordDetailType = await RougelikeRecordDetailModel.findOneAndUpdate({ gameCode, detailCode, 'shops.optionIndex': optionIndex }, { ...params, 'shops.$.optionStatus': optionStatus }, { new: true, upsert: true }).lean(lean);
|
||
return result;
|
||
}
|
||
|
||
public static async findByGameCode(gameCode: string, lean = true) {
|
||
const result: RougelikeRecordDetailType[] = await RougelikeRecordDetailModel.find({ gameCode }).lean(lean);
|
||
return result;
|
||
}
|
||
|
||
public static async findByCode(gameCode: string, detailCode: string, lean = true) {
|
||
const result: RougelikeRecordDetailType = await RougelikeRecordDetailModel.findOne({ gameCode, detailCode }).lean(lean);
|
||
return result;
|
||
}
|
||
|
||
public static async findByDetailCode(detailCode: string, lean = true) {
|
||
const result: RougelikeRecordDetailType = await RougelikeRecordDetailModel.findOne({ detailCode }).lean(lean);
|
||
return result;
|
||
}
|
||
|
||
public static async findByGameCodeAndLtLayer(gameCode: string, layer: number, lean = true) {
|
||
const result: RougelikeRecordDetailType[] = await RougelikeRecordDetailModel.find({ gameCode, layer: { $lt: layer } }).lean(lean);
|
||
return result;
|
||
}
|
||
|
||
public static async findByGameCodeAndLayer(gameCode: string, layer: number, lean = true) {
|
||
const result: RougelikeRecordDetailType = await RougelikeRecordDetailModel.findOne({ gameCode, layer }).lean(lean);
|
||
return result;
|
||
}
|
||
|
||
|
||
public static async bulkWriteUpdate(updateArr: RougelikeRecordDetailPara[]) {
|
||
if (updateArr.length == 0) return;
|
||
await RougelikeRecordDetailModel.bulkWrite(updateArr.map((param) => {
|
||
const { gameCode, detailCode } = param
|
||
return { updateOne: { filter: { gameCode, detailCode }, update: { $set: { ...param } }, upsert: true } }
|
||
}))
|
||
}
|
||
};
|
||
export const RougelikeRecordDetailModel = getModelForClass(RougelikeRecordDetail);
|
||
export interface RougelikeRecordDetailType extends Pick<DocumentType<RougelikeRecordDetail>, keyof RougelikeRecordDetail> { };
|
||
export type RougelikeRecordDetailPara = Partial<RougelikeRecordDetailType>; // 将所有字段变成可选项
|