go_dreamfactory/modules/hero/api_drawCard.go

185 lines
5.4 KiB
Go

package hero
import (
"crypto/rand"
"go_dreamfactory/comm"
"go_dreamfactory/pb"
cfg "go_dreamfactory/sys/configure/structs"
"math"
"math/big"
"strconv"
"google.golang.org/protobuf/proto"
)
func (this *apiComp) DrawCardCheck(session comm.IUserSession, req *pb.HeroDrawCardReq) (code pb.ErrorCode) {
if req.DrawType <= 0 { // 只能是单抽或10抽
code = pb.ErrorCode_ReqParameterError
}
return
}
//抽卡
func (this *apiComp) DrawCard(session comm.IUserSession, req *pb.HeroDrawCardReq) (code pb.ErrorCode, data proto.Message) {
var (
szCards []int32 // 最终抽到的卡牌
totalWeight int64 // 总权重
curWeigth int64 // 临时随机获得的权重
drawTimes int32 // 抽卡次数
curStar4Count int32 // 当前4星没抽到的次数
curStar5Count int32 // 当前5星没抽到的次数
config4Count int32 // 配置表中4星保底次数
config5Count int32 // 配置表中5星保底次数
race int32
)
szCards = make([]int32, 0)
rsp := &pb.HeroDrawCardResp{}
this.module.Debugf("当前4星抽卡没中次数:%d, 当前5星抽卡没中次数:%d", curStar4Count, curStar5Count)
rst, _ := this.module.modelHero.GetUserRecord(session.GetUserId())
if req.DrawType%2 == 0 { // 转成对应阵营信息 1~5
race = int32((int(req.DrawType)) / 2)
} else {
race = int32(int(req.DrawType+1) / 2)
}
if race == comm.RacePt { // 普通卡池
curStar4Count = rst.Race0.H4
curStar5Count = rst.Race0.H5
} else if race == comm.RaceZr { // 灼热
curStar4Count = rst.Race1.H4
curStar5Count = rst.Race1.H5
} else if race == comm.RaceYd { // 涌动
curStar4Count = rst.Race2.H4
curStar5Count = rst.Race2.H5
} else if race == comm.RaceHx { // 呼啸
curStar4Count = rst.Race3.H4
curStar5Count = rst.Race3.H5
} else if race == comm.RaceSy { // 闪耀
curStar4Count = rst.Race4.H4
curStar5Count = rst.Race4.H5
}
// 获取配置文件的权重信息
_conf, err := this.module.configure.GetHeroDrawConfig(race)
if err != nil {
code = pb.ErrorCode_DrawCardTypeNotFound // 抽卡类型不匹配
return
}
_costConf, err := this.module.configure.GetDrawCostConfigByID(req.DrawType) // 抽卡消耗
if err != nil {
code = pb.ErrorCode_ConfigNoFound
return
}
config4Count = _costConf.Floor4 // 4星保底次数
config5Count = _costConf.Floor5 // 5星保底次数
if config4Count == 0 { // 数量为0 设置最大
config5Count = math.MaxInt32
}
if config5Count == 0 {
config4Count = math.MaxInt32
}
sz := make([]*cfg.Game_atn, 0)
sz = append(sz, _costConf.Cost)
code = this.module.CheckRes(session, sz) // 消耗校验
if code != pb.ErrorCode_Success {
return
}
drawTimes = _costConf.Count // 抽卡次数
for _, v := range _conf {
totalWeight += int64(v.Weight) // 统计所有权重
}
//this.module.configure.GetDrawUpDrawConfig()
drawTimes = 1
for i := 0; i < int(drawTimes); i++ {
n, _ := rand.Int(rand.Reader, big.NewInt(totalWeight)) // [0,totalWeight)
for _, v := range _conf {
curWeigth += int64(v.Weight)
if curWeigth < n.Int64() { // 命中
// 获取当前星级
_getCardCfg := this.module.configure.GetHero(v.Id) //获取的英雄信息
if _getCardCfg != nil {
continue
}
if _getCardCfg.Star == 4 { // 当抽取到的英雄是4星的时候 清除 该类型的保底次数
curStar4Count = 0
continue
} else if _getCardCfg.Star == 5 { // 当抽取到的英雄是5星的时候 清除 该类型的保底次数
curStar5Count = 0 // 清0
continue
}
curStar4Count++
curStar5Count++
bGet := false
// 达标保底次数
if curStar4Count >= config4Count {
//_costConf.Floor4cards
_bd, err := this.module.configure.GetHeroDrawConfig(_costConf.Floor4cards)
if err != nil && len(_bd) != 0 {
var _totalW int64 // 总权重
var _tmpW int64 // 临时权重
for _, v := range _bd {
_totalW += int64(v.Weight)
}
// 随机权重
n, _ := rand.Int(rand.Reader, big.NewInt(_totalW))
for _, v := range _bd {
_tmpW += int64(v.Weight)
if n.Int64() > _tmpW { // 种族保底卡池命中
szCards = append(szCards, v.Id)
bGet = true
break
}
}
}
} else if curStar5Count >= config5Count {
_bd, err := this.module.configure.GetHeroDrawConfig(_costConf.Floor5cards)
if err != nil && len(_bd) != 0 {
var _totalW int64 // 总权重
var _tmpW int64 // 临时权重
for _, v := range _bd {
_totalW += int64(v.Weight)
}
// 随机权重
n, _ := rand.Int(rand.Reader, big.NewInt(_totalW))
for _, v := range _bd {
_tmpW += int64(v.Weight)
if n.Int64() > _tmpW { // 种族保底卡池命中
szCards = append(szCards, v.Id)
bGet = true
break
}
}
}
}
if !bGet {
szCards = append(szCards, v.Id)
}
}
}
}
raceData := &pb.Floor{
H4: curStar4Count,
H5: curStar5Count,
}
// 更新record 配置信息
update := map[string]interface{}{}
update["race"+strconv.Itoa(int(race)-1)] = raceData
this.module.modelHero.ChangeUserRecord(session.GetUserId(), update)
// 消耗道具
code = this.module.ConsumeRes(session, sz, true)
if code != pb.ErrorCode_Success {
return
}
if err := this.module.modelHero.createMultiHero(session.GetUserId(), szCards...); err != nil {
code = pb.ErrorCode_HeroCreate
return
}
rsp.Heroes = szCards
session.SendMsg(string(this.module.GetType()), DrawCard, rsp)
return
}