修改抽卡的接口
This commit is contained in:
parent
79e8075102
commit
6cf709ff64
91
docs/api.md
91
docs/api.md
@ -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, // 当前的经验值
|
||||
}]
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
28
src/dao/CardGroupDao.ts
Normal 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()
|
||||
}
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user