修改抽卡的接口

This commit is contained in:
zhl 2021-01-22 18:47:16 +08:00
parent 79e8075102
commit 6cf709ff64
8 changed files with 240 additions and 177 deletions

View File

@ -178,64 +178,33 @@
根据errcode判断成功or失败
### ~~7. 解锁英雄~~
### 8. 抽卡
1. Method: POST
2. URI: /api/:accountid/hero/unlock/:heroid
2. URI: /api/:accountid/card/draw
| 字段 | 说明 |
| -------- | -------------------------------------- |
| accountid | 帐号id |
| heroid | 英雄id |
> POST参数
| 字段 | 说明 |
| -------- | -------------------------------------- |
| type | 类型 0: 碎片, 1: 试用 |
3. Response: JSON
> 说明: 解锁成功的话, 会返回当前解锁英雄的数据
```js
[{
heroid: 1022, // 英雄id
owned: true, // 是否已拥有
ban: false, // 是否被禁用
usetype: 1, // 赛季专属, 0: 通用, 1: 赛季排位专用, 2: 匹配专用
free: false, // 是否免费
trial: false, // 是否是试用
trial_expire: 1609919293 // 试用到期时间, 0: 说明是永久
level: 1, // 等级
exp: 0, // 当前的经验值
}]
```
### 8. 抽卡
1. Method: POST
2. URI: /api/:accountid/card/draw/:count
| 字段 | 说明 |
| -------- | -------------------------------------- |
| accountid | 帐号id |
| count | 抽卡数量 |
| count | 类型 1 或 10 |
|itemid| 抽卡使用的物品id |
3. Response: JSON
```js
[{
cardid: 1022, // 卡牌id
isnew: true, // 是否是新获得的卡
expdust: '', // 分解可获得的英雄经验的item id
dustcount: 100 // 可获得数量
id: 11022, // 卡牌id
used: 1, // 是否已经自动激活卡或英雄, 1: 已自动激活 0: 未激活
heroid: 111, // 激活的英雄id, 可能为空
cardid: 100 // 激活的卡id, 可能为空
}]
```
@ -521,6 +490,44 @@
```
### 3. 解锁英雄
1. Method: POST
2. URI: /svr/:accountid/hero/unlock/:heroid
| 字段 | 说明 |
| -------- | -------------------------------------- |
| accountid | 帐号id |
| heroid | 英雄id |
> POST参数
| 字段 | 说明 |
| -------- | -------------------------------------- |
| type | 类型 0: 碎片, 1: 试用 |
3. Response: JSON
> 说明: 解锁成功的话, 会返回当前解锁英雄的数据
```js
[{
heroid: 1022, // 英雄id
owned: true, // 是否已拥有
ban: false, // 是否被禁用
usetype: 1, // 赛季专属, 0: 通用, 1: 赛季排位专用, 2: 匹配专用
free: false, // 是否免费
trial: false, // 是否是试用
trial_expire: 1609919293 // 试用到期时间, 0: 说明是永久
level: 1, // 等级
exp: 0, // 当前的经验值
}]
```

View File

@ -7,6 +7,7 @@ import { BaseConst } from '../constants/BaseConst'
import { Hero } from '../models/subdoc/Hero'
import { CardGroup } from '../models/CardGroup'
import { BagItem, ItemType } from '../models/BagItem'
import { addHeroDefaultCardGroup } from '../dao/CardGroupDao'
export default class AccountController extends BaseController {
@role('anon')
@ -48,27 +49,7 @@ export default class AccountController extends BaseController {
hero.exp = 0
if (!account.heros.has(cfg.id + '')) {
account.heros.set(cfg.id + '', hero)
let cardgroup = new CardGroup({})
let cards: Card[] = []
for (let i = 1; i <= 4; i++) {
const cardid = cfg[`follower${ i }id`]
const owned = cardMap.has(cardid)
const card = new Card()
card.cardid = cardid
card.owned = owned
card.ban = false
card.usetype = 0
card.free = !owned
card.free_expire = 0
card.time = Date.now()
cards.push(card)
}
cardgroup.accountid = account.id
cardgroup.heroid = cfg.id
cardgroup.selected = false
cardgroup.isdefault = true
cardgroup.cards = cards
await cardgroup.save()
await addHeroDefaultCardGroup(accountid, hero.heroid, cardMap)
}
}
}

View File

@ -7,6 +7,10 @@ import { MoneyTypeConst } from '../constants/MoneyTypeConst'
import { BaseConst } from '../constants/BaseConst'
import { BagItem, ItemType } from '../models/BagItem'
import ItemCtrl from '../logic/ItemCtrl'
import { error } from '../common/Debug'
import { ItemFuncCfg } from '../cfg/parsers/ItemFuncCfg'
import { addHeroDefaultCardGroup } from '../dao/CardGroupDao'
import { ItemInfo } from '../logic/ItemDef'
export default class CardController extends BaseController {
@router('post /api/:accountid/card_group/:heroid')
@ -123,56 +127,102 @@ export default class CardController extends BaseController {
return {}
}
@router('post /api/:accountid/card/draw/:count')
@router('post /api/:accountid/card/draw')
async drawCard(req: any) {
let { count } = req.params
if (count < 10) {
count = 1
let { count, accountid, itemid } = req.params
count = count << 0
itemid = itemid << 0
if (count != 10 && count != 1) {
throw new ZError(101, '参数不正确')
}
if (count > 10) {
count = 10
let cfg: ItemFuncCfg = count == 10 ?
global.$cfg.get(BaseConst.ITEMFUNC).get(90002):
global.$cfg.get(BaseConst.ITEMFUNC).get(90001)
if (!cfg) {
error(`抽卡 ${accountid} : [${count}, 无法找到抽卡配置`)
throw new ZError(102, '无法找到对应的配置')
}
let itemInfo = ItemCtrl.getItemsByInfo(cfg.consume1)
if (count == 1 && itemInfo.length == 0) {
throw new ZError(103, '无法找到对应的配置')
}
if (count == 1 && itemInfo[0].id !== itemid) {
throw new ZError(104, '解锁物品与配置不符')
}
if (count == 10) {
if (itemid != itemInfo[0].id) {
itemInfo = ItemCtrl.getItemsByInfo(cfg.consume2)
if (itemInfo.length == 0 || itemInfo[0].id != itemid) {
throw new ZError(104, '解锁物品与配置不符')
}
}
}
let record = await BagItem.findOne({accountid, itemid})
if (!record || record.count < count) {
throw new ZError(105, '解锁物品数量不足')
}
const items: ItemInfo[] = []
for (let z = 0 ; z < count; z ++) {
items.push(ItemCtrl.getItemsByInfo(cfg.get)[0])
}
let account = req.user
if (!account.moneys.has(MoneyTypeConst.CARD_SCROLL)) {
throw new ZError(101, '卷轴不足')
}
let money = account.moneys.get(MoneyTypeConst.CARD_SCROLL)
if (money < count) {
throw new ZError(101, '卷轴不足')
}
account.moneys.set(MoneyTypeConst.CARD_SCROLL, money - count)
// TODO: 根据配置的概率获取卡
let cardMap = global.$cfg.get(BaseConst.UNIT)
let cards: any[] = []
for (let [id, card] of cardMap) {
if (card.unittypei_id == 2) {
cards.push(card)
}
}
let cardsgetd: number[] = cards.randomGet(count).map((o: any) => o.id)
let totalCards = account.cards.union(cardsgetd)
let dulpSet = new Set(account.cards.intersect(cardsgetd))
const cfgMap = global.$cfg.get(BaseConst.ITEMCARD)
let results: any = []
let expHero = account.moneys.get(MoneyTypeConst.HERO_EXP) || 0
//TODO: 根据配置设置每张卡分解后得到的经验
const expPreCard = 10
for (let id of cardsgetd) {
let data: any = { id }
if (dulpSet.has(id)) {
data.isnew = false
data.expdust = MoneyTypeConst.HERO_EXP
data.dustcount = expPreCard
expHero += expPreCard
} else {
data.isnew = true
const cardMap = account.cardMap
for (let item of items) {
if (item.type != ItemType.CARD) {
results.push({
id: item.id,
used: 0,
count: item.count
});
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,
heroid: data.unlocking
})
} else {
results.push({
id: item.id,
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,
cardid: data.unlocking
})
} else {
results.push({
id: item.id,
used: 0,
})
}
}
}
results.push(data)
}
account.moneys.set(MoneyTypeConst.HERO_EXP, expHero)
account.cards = totalCards
await account.save()
record.count -= count
await record.save()
return results
}

View File

@ -7,6 +7,7 @@ import { Card } from '../models/subdoc/Card'
import { HeroCfg } from '../cfg/parsers/HeroCfg'
import { Hero } from '../models/subdoc/Hero'
import { BagItem, ItemType } from '../models/BagItem'
import { addHeroDefaultCardGroup } from '../dao/CardGroupDao'
export default class HeroController extends BaseController {
@router('post /api/:accountid/heros')
@ -20,7 +21,6 @@ export default class HeroController extends BaseController {
return heros
}
@router('post /api/:accountid/hero/unlock/:heroid')
@router('post /svr/:accountid/hero/unlock/:heroid')
async unlockHero(req: any) {
let account = req.user
@ -30,36 +30,11 @@ export default class HeroController extends BaseController {
}
let hero
if (!type) {
let userMoney = !req.url.startsWith('/svr')
hero = await account.unlockHero(heroid, userMoney)
hero = await account.unlockHero(heroid, 1)
// 将该英雄的默认卡组添加到玩家的卡组中,
// 将默认卡组里的卡添加到玩家可用卡牌中
let cardMap = account.cardMap
let cfg = global.$cfg.get(BaseConst.HERO).get(parseInt(hero.heroid))
let cardgroup = new CardGroup({})
let cards: Card[] = []
for (let i = 1; i < 10; i++) {
if (!cfg[`follower${ i }id`]) {
break
}
const cardid = cfg[`follower${ i }id`]
const owned = cardMap.has(cardid)
const card = new Card()
card.cardid = cardid
card.owned = owned
card.ban = false
card.usetype = 0
card.free = !owned
card.free_expire = 0
card.time = Date.now()
cards.push(card)
}
cardgroup.accountid = account.id
cardgroup.heroid = hero.heroid
cardgroup.selected = false
cardgroup.isdefault = true
cardgroup.cards = cards
await cardgroup.save()
await addHeroDefaultCardGroup(account.id, hero.heroid, cardMap)
await account.save()
} else {
hero = await account.tryHero(heroid)

28
src/dao/CardGroupDao.ts Normal file
View File

@ -0,0 +1,28 @@
import { BaseConst } from '../constants/BaseConst'
import { CardGroup } from '../models/CardGroup'
import { Card } from '../models/subdoc/Card'
export async function addHeroDefaultCardGroup(accountid: string, heroid: number, cardMap: Map<string, Card>) {
const heroCfg = global.$cfg.get(BaseConst.HERO).get(heroid)
let cardgroup = new CardGroup({})
let cards: Card[] = []
for (let i = 1; i <= 4; i++) {
const cardid = heroCfg[`follower${ i }id`]
const owned = cardMap.has(cardid)
const card = new Card()
card.cardid = cardid
card.owned = owned
card.ban = false
card.usetype = 0
card.free = !owned
card.free_expire = 0
card.time = Date.now()
cards.push(card)
}
cardgroup.accountid = accountid
cardgroup.heroid = heroCfg.id
cardgroup.selected = false
cardgroup.isdefault = true
cardgroup.cards = cards
await cardgroup.save()
}

View File

@ -148,61 +148,64 @@ class UserClass extends FindOrCreate {
return fc.get(70021).number + this.season_score * (fc.get(70020).number / 100 + twp)
}
public async unlockHero(heroid: number, useMoney: boolean) {
if (this.heros.has(heroid + '')) {
if (!this.heros.get(heroid + '').trial) {
throw new ZError(102, '你已经解锁了该英雄')
}
public unlockHero(heroid: number, maxCount: number) {
let hero = this.heros.get(heroid + '')
let result = 0
if (hero && !hero.trial && hero.count >= maxCount) {
return result
}
if (useMoney) {
let money0 = MoneyTypeConst.getHeroShard(heroid)
let money1 = MoneyTypeConst.HERO_SHARD
let count0 = this.moneys.has(money0) ? this.moneys.get(money0) : 0
let count1 = this.moneys.has(money1) ? this.moneys.get(money1) : 0
// TODO:: 根据配置获取解锁英雄需要的碎片数量
let needCount = 30
if (count0 + count1 < needCount) {
throw new ZError(102, '碎片数量不足')
}
if (count0 > 0) {
let rest = needCount - count0
if (rest >= 0) {
needCount = rest
this.moneys.set(money0, 0)
} else {
needCount = 0
this.moneys.set(money0, Math.abs(rest))
}
}
// 上面已经过滤了 count0 + count1 > needcount, 所以这里不需要判断碎片是否足够
if (needCount > 0) {
count1 = count1 - needCount
this.moneys.set(money1, count1)
}
if (!hero) {
hero = new Hero()
hero.heroid = heroid
hero.free = false
hero.trial = false
hero.level = 1
hero.trial_expire = 0
hero.exp = 0
hero.slot = 1
hero.count = 1
hero.time = Date.now()
} else {
hero.count += 1
}
let hero = new Hero()
hero.heroid = heroid
hero.free = false
hero.trial = false
hero.level = 1
hero.trial_expire = 0
hero.exp = 0
hero.slot = 1
hero.time = Date.now()
result = hero.count
this.heros.set(heroid + '', hero)
return hero
return result
}
public async unlockCard(cardid: number, maxCount: number) {
let card = this.cardMap.get(cardid + '')
let result = 0
if (card && card.count >= maxCount) {
return result
}
if (!card) {
const card = new Card()
card.cardid = cardid
card.owned = true
card.ban = false
card.usetype = 0
card.free = false
card.count = 0
card.free_expire = 0
card.time = Date.now()
} else {
card.count += 1
}
this.cardMap.set(card.cardid + '', card)
return card.count
}
public async tryHero(heroid: number) {
if (this.heros.has(heroid + '')) {
throw new ZError(102, '你已经解锁了该英雄')
}
//TODO:: 根据配置查看该英雄是否可使用
let hero = new Hero()
hero.heroid = heroid
hero.free = false
hero.trial = true
hero.level = 1
hero.count = 0
hero.trial_expire = 0
hero.exp = 0
this.heros.set(heroid + '', hero)

View File

@ -32,6 +32,13 @@ export class Card {
*/
@prop()
public free_expire: number
/**
*
* @type {number}
*/
@prop({default: 1})
public count: number
/**
*
* @type {number}
@ -47,7 +54,8 @@ export class Card {
usetype: this.usetype,
free: this.free,
free_expire: this.free_expire,
time: this.time
time: this.time,
count: this.count
}
}
}

View File

@ -31,10 +31,20 @@ export class Hero {
*/
@prop({default: 1})
public slot: number
/**
*
* @type {number}
*/
@prop()
public time: number
/**
*
* @type {number}
*/
@prop({default: 1})
public count: number
public toJson() {
let data: any = {
heroid: this.heroid,
@ -46,7 +56,8 @@ export class Hero {
trial_expire: this.trial_expire,
slot: this.slot,
time: this.time,
ban: false
ban: false,
count: this.count
}
data.owned = !this.trial
return data