card_info_svr/src/models/BagItem.ts

219 lines
5.9 KiB
TypeScript

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<number, DropItemCfg> = global.$cfg.get(BaseConst.DROPITEM)
if (dmap.has(itemid)) {
return dmap.get(itemid).itemtypeid
}
let imap: Map<number, ItemCardCfg> = global.$cfg.get(BaseConst.ITEMCARD)
if (imap.has(itemid)) {
return imap.get(itemid).typeid
}
return ItemType.UNKNOW
}
interface BagItemClass extends Base<string>, 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<void>}
*/
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<any>}
*/
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'] })