import { dbconn } from '../decorators/dbconn' import { getModelForClass, index, modelOptions, plugin, prop, Severity } from '@typegoose/typegoose' import { Base, FindOrCreate, TimeStamps } from '@typegoose/typegoose/lib/defaultClasses' // @ts-ignore import findOrCreate from 'mongoose-findorcreate' import { BaseConst } from '../constants/BaseConst' import { DropItemCfg } from '../cfg/parsers/DropItemCfg' import { ItemCardCfg } from '../cfg/parsers/ItemCardCfg' import { ItemInfo } from '../logic/ItemDef' import { error } from '../common/Debug' import { addHeroDefaultCardGroup } from '../dao/CardGroupDao' import { ItemRecord } from './ItemRecord' export enum ItemType { UNKNOW = 0, // 未知 NORMAL = 1, // 杂物 BAG = 2, // 礼包 CARD = 3, // 卡 MONEY = 7 // 代币 } /** * 根据itemid确定物品的类型 * @param {number} itemid * @return {ItemType.UNKNOW | number} */ export function getItemType(itemid: number) { let dmap: Map = global.$cfg.get(BaseConst.DROPITEM) if (dmap.has(itemid)) { return dmap.get(itemid).itemtypeid } let imap: Map = global.$cfg.get(BaseConst.ITEMCARD) if (imap.has(itemid)) { return imap.get(itemid).typeid } return ItemType.UNKNOW } interface BagItemClass extends Base, TimeStamps { } @dbconn() @index({ accountid: 1, itemid: 1, itemtype: 1 }, { unique: true }) @index({ accountid: 1, itemid: 1 }, { unique: true }) @plugin(findOrCreate) @modelOptions({ schemaOptions: { collection: 'bag_items', timestamps: true }, options: { allowMixed: Severity.ALLOW } }) class BagItemClass extends FindOrCreate { @prop() public accountid: string @prop() public itemid: number @prop({ enum: ItemType }) public itemtype: ItemType @prop({ default: 0 }) public count: number @prop({ default: 0 }) public position: number @prop() public source?: string public static async addItems(accountid: string, items: ItemInfo[], reason?: string, more?: any) { let results: any = [] for (const item of items) { let record = (await BagItem.findOrCreate({ accountid, itemid: item.id, itemtype: item.type })).doc record.count += item.count await record.save() results.push(record.toJson()) setImmediate(function (){ ItemRecord.log(accountid, item.id, item.count, reason, more) .then(()=>{}).catch(err=>{ error('error add item log', err) }) }) } return results } /** * 该方法只更新物品数量, 不检查 * 使用该方法前须检查物品数量是否大于使用数量 * @param {string} accountid * @param {ItemInfo} items * @param reason * @param more * @return {Promise} */ public static async useItems(accountid: string, items: ItemInfo[], reason?: string, more?: any) { for (let item of items) { const conditions = {accountid, itemid: item.id} const update = {$inc: {count: -item.count}} await BagItem.updateOne(conditions, update) setImmediate(function (){ ItemRecord.log(accountid, item.id, -item.count, reason, more) .then(()=>{}).catch(err=>{ error('error add item log', err) }) }) } } public static async useItem(accountid: string, itemid: number, count: number, reason?: string, more?: any) { return BagItem.useItems(accountid, [new ItemInfo(itemid, count)], reason, more) } public toJson() { return { id: this.itemid, count: this.count, type: this.itemtype } } /** * 处理10连抽的物品列表 * @param account * @param {ItemInfo[]} items * @return {Promise} */ public static async parseCardItems(account: any, items: ItemInfo[], more: any) { const cardMap = account.cardMap const cfgMap = global.$cfg.get(BaseConst.ITEMCARD) let itemToSave: ItemInfo[] = [] const accountid = account._id let results: any = [] for (let item of items) { if (item.type != ItemType.CARD) { results.push({ id: item.id, used: 0, count: item.count }); itemToSave.push(item) continue } if (item.type == ItemType.CARD &&!cfgMap.has(item.id)) { error(`抽卡 ${item.id} 的配置不存在`) continue } const data = cfgMap.get(item.id) if (data.unlocking >= 30000 ) { // 英雄 for (let i = 0; i < item.count; i ++) { let result = account.unlockHero(data.unlocking, data.unlockingtimes) if (result == 1) { await addHeroDefaultCardGroup(accountid, data.unlocking, cardMap) } if (result > 0) { results.push({ id: item.id, used: 1, count: 1, heroid: data.unlocking }) } else { let saveItem = new ItemInfo(item.id, 1, item.weight) saveItem.type = item.type itemToSave.push(saveItem) results.push({ id: item.id, count: 1, used: 0 }) } } } else { // 随从卡 for (let i = 0; i < item.count; i ++) { const result = account.unlockCard(data.unlocking, data.unlockingtimes) if (result > 0) { results.push({ id: item.id, used: 1, count: 1, cardid: data.unlocking }) } else { let saveItem = new ItemInfo(item.id, 1, item.weight) saveItem.type = item.type itemToSave.push(saveItem) results.push({ id: item.id, count: 1, used: 0, }) } } } } await BagItem.addItems(accountid, itemToSave, 'draw_card', more) return results } } export const BagItem = getModelForClass(BagItemClass, // @ts-ignore { existingConnection: BagItemClass['db'] })