go_dreamfactory/modules/hero/api_drawCardv2.go
2023-06-21 17:21:41 +08:00

370 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package hero
import (
"crypto/rand"
"go_dreamfactory/comm"
"go_dreamfactory/pb"
cfg "go_dreamfactory/sys/configure/structs"
"math/big"
)
func (this *apiComp) DrawCardV2Check(session comm.IUserSession, req *pb.HeroDrawCardReq) (errdata *pb.ErrorData) {
if req.DrawType < 0 && (req.DrawCount == 1 || req.DrawCount == 10) { // 只能是单抽或10抽
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ReqParameterError,
Title: pb.ErrorCode_ReqParameterError.ToString(),
}
}
return
}
//抽卡
func (this *apiComp) DrawCardV2(session comm.IUserSession, req *pb.HeroDrawCardReq) (errdata *pb.ErrorData) {
var (
szCards []string // 最终抽到的卡牌
drawCount int32 // 抽卡次数
szStar []int32 //星级
costRes []*cfg.Gameatn // 消耗
star4Max int32 // 10连抽最大4星数量
star5Max int32 // 10连抽最大5星数量
cfgDraw *cfg.GameGlobalData
heroRecord *pb.DBHeroRecord
pool string // 当前抽对应的卡池
atno []*pb.UserAtno // 最终获得的资源
strPool []string // 10连跨多个卡池情况
update map[string]interface{}
normalDraw bool // 是否是普通抽
drawConf *cfg.GameDrawPoolData
err error
appointmap map[int32]string // 指定次数抽卡到指定卡池
)
appointmap = make(map[int32]string)
szCards = make([]string, 0)
heroRecord, _ = this.module.modelRecord.GetHeroRecord(session.GetUserId())
if heroRecord.Baodi4 == nil {
heroRecord.Baodi4 = make(map[int32]int32)
}
if heroRecord.Baodi5 == nil {
heroRecord.Baodi5 = make(map[int32]int32)
}
if heroRecord.Count == nil {
heroRecord.Count = make(map[int32]int32)
}
// 准备数据
/////////////////////////////////////
drawConf, err = this.module.configure.GetHeroDrawConfigByType(req.DrawType) // 获取新的抽卡配置
if err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ReqParameterError,
Title: pb.ErrorCode_ReqParameterError.ToString(),
Message: err.Error(),
}
return
}
for _, v := range drawConf.RecruitmentType {
appointmap[v.K] = v.S // 指定次抽数据
}
////////////////////////////////////////////////////////
update = make(map[string]interface{})
cfgDraw = this.module.ModuleTools.GetGlobalConf() // 读取抽卡配置文件
if cfgDraw == nil {
return
}
if errdata = this.DrawCardV2Check(session, req); errdata != nil {
return
}
drawCount = heroRecord.Count[req.DrawType] // 获取当前阵容抽卡次数
if req.DrawType == 0 { // 普通卡池抽卡
////// 获取消耗 star
if req.DrawCount == 1 {
costRes = drawConf.ConsumeA // 单抽消耗
} else {
costRes = drawConf.ConsumeB // 十连消耗
}
if errdata = this.module.CheckRes(session, costRes); errdata != nil { // 消耗数量不足直接返回
return
}
///// 获取消耗 end
for i := 1; i <= int(req.DrawCount); i++ { // 一张一张的抽
drawCount++
if v, ok := appointmap[drawCount]; ok { // 优先校验是否是指定抽
strPool = append(strPool, v) //找到了
continue
}
// 随机获取三星
}
} else {
}
if req.DrawType == 0 { // 普通卡池抽卡
normalDraw = true
// 获取普通抽卡池
// if req.DrawCount == 1 {
// costAtn = cfgDraw.BasePoolCost
// } else {
// costAtn = cfgDraw.BasePool10cost
// }
// if errdata = this.module.CheckRes(session, costRes); errdata != nil { // 消耗数量不足直接返回
// return
// }
for i := 0; i < int(req.DrawCount); i++ {
drawCount += 1
pool = this.module.modelHero.CheckPool(drawCount, cfgDraw)
strPool = append(strPool, pool)
ret := this.module.CheckCondition(session.GetUserId())
if ret == true { // 命中插入5星英雄
szStar = append(szStar, 5)
heroRecord.Star5 = 0 // 重置保底
star5Max++ // 记录当前 5星数量
continue
}
// 3,4,5 星权重
starWeight := []int32{cfgDraw.BasePoolStar3, cfgDraw.BasePoolStar4, cfgDraw.BasePoolStar5}
starIndex := comm.GetRandW(starWeight) // 3 4 5 星索引
// 特殊规则 DrawCard_5StarsInRange 第2-30次抽奖必出一个5星英雄普通卡池
inRangeConf := this.module.ModuleTools.GetGlobalConf().DrawCard5StarsInRange
if len(inRangeConf) == 3 {
iStart := inRangeConf[0] // 抽卡开始
iEnd := inRangeConf[1] // 抽卡结束
star := inRangeConf[2]
if star >= 3 { // 保底必须三星+
if heroRecord.Inevitable == 0 && heroRecord.Drawcount > iStart && heroRecord.Drawcount < iEnd && iEnd >= iStart {
n, _ := rand.Int(rand.Reader, big.NewInt(int64(iEnd-iStart)))
if n.Int64() < 1 { // 抽中
starIndex = star - 3
heroRecord.Inevitable = heroRecord.Drawcount
update["inevitable"] = heroRecord.Drawcount
szStar = append(szStar, star)
if star == 4 {
heroRecord.Star4 = 0
star4Max++
} else if star == 5 {
star5Max++
heroRecord.Star5 = 0
}
continue
}
}
// 保底情况
if heroRecord.Drawcount == iEnd && heroRecord.Inevitable == 0 {
starIndex = star - 3
heroRecord.Inevitable = heroRecord.Drawcount
update["inevitable"] = heroRecord.Drawcount
szStar = append(szStar, star)
if star == 4 {
heroRecord.Star4 = 0
star4Max++
} else if star == 5 {
star5Max++
heroRecord.Star5 = 0
}
continue
}
}
}
inRangeConf1 := this.module.ModuleTools.GetGlobalConf().DrawCard5StarsInRange1
if len(inRangeConf1) == 3 {
iStart := inRangeConf1[0] // 抽卡开始
iEnd := inRangeConf1[1] // 抽卡结束
star := inRangeConf1[2]
if star >= 3 { // 保底必须三星+
if heroRecord.Inevitable == 0 && heroRecord.Drawcount > iStart && heroRecord.Drawcount < iEnd && iEnd >= iStart {
n, _ := rand.Int(rand.Reader, big.NewInt(int64(iEnd-iStart)))
if n.Int64() < 1 { // 抽中
starIndex = star - 3
heroRecord.Inevitable = heroRecord.Drawcount
update["inevitable1"] = heroRecord.Drawcount
szStar = append(szStar, star)
if star == 4 {
heroRecord.Star4 = 0
star4Max++
} else if star == 5 {
star5Max++
heroRecord.Star5 = 0
}
// 修改卡池
newPoll := this.module.ModuleTools.GetGlobalConf().DrawCard5StarsInRange1Pool
if newPoll != "" {
strPool[len(strPool)-1] = newPoll
}
continue
}
}
// 保底情况
if heroRecord.Drawcount == iEnd && heroRecord.Inevitable == 0 {
starIndex = star - 3
heroRecord.Inevitable1 = heroRecord.Drawcount
update["inevitable1"] = heroRecord.Drawcount
szStar = append(szStar, star)
if star == 4 {
heroRecord.Star4 = 0
star4Max++
} else if star == 5 {
star5Max++
heroRecord.Star5 = 0
}
// 修改卡池
newPoll := this.module.ModuleTools.GetGlobalConf().DrawCard5StarsInRange1Pool
if newPoll != "" {
strPool[len(strPool)-1] = newPoll
}
continue
}
}
}
heroRecord.Star4++ // 4星保底数量+1
heroRecord.Star5++ // 5星保底数量+1
if starIndex == 1 {
heroRecord.Star4 = 0
star4Max++
} else if starIndex == 2 {
star5Max++
heroRecord.Star5 = 0
}
if star4Max >= cfgDraw.Draw10Star4Max || star5Max >= cfgDraw.Draw10Star5Max { // 达到10连抽最大(4,5星)数量 直接给三星
starIndex = 0
} else {
// 普通卡池保底
if cfgDraw.DrawFloorStar4 <= heroRecord.Star4 {
heroRecord.Star4 = 0
starIndex = 1
}
if cfgDraw.DrawFloorStar5 <= heroRecord.Star5 {
heroRecord.Star5 = 0
starIndex = 2
}
}
szStar = append(szStar, starIndex+3)
if len(szStar) >= int(req.DrawCount) {
break
}
}
} else { // 所有阵营抽卡都走这里
drawCount += req.DrawCount
if req.DrawCount == 1 {
strPool = append(strPool, pool)
} else {
for i := 0; i < int(req.DrawCount); i++ {
strPool = append(strPool, pool)
}
}
//阵营消耗
if errdata = this.module.CheckRes(session, costRes); errdata != nil { // 消耗数量不足直接返回
return
}
for {
starWeight := []int32{cfgDraw.CampPoolStar3, cfgDraw.CampPoolStar4, cfgDraw.CampPoolStar5}
starIndex := comm.GetRandW(starWeight)
if starIndex == 1 {
star4Max++
} else if starIndex == 2 {
star5Max++
}
if star4Max >= cfgDraw.Draw10Star4Max || star5Max >= cfgDraw.Draw10Star5Max {
starIndex = 0
}
szStar = append(szStar, starIndex)
if len(szStar) >= int(req.DrawCount) {
break
}
}
}
for index, star := range szStar {
_data, err := this.module.configure.GetPollByType(strPool[index])
if err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ConfigNoFound,
Title: pb.ErrorCode_ConfigNoFound.ToString(),
Message: err.Error(),
}
return
}
sz := make([]int32, 0)
for _, v := range _data[int32(star)] {
sz = append(sz, v.Weight)
}
randomIndex := comm.GetRandW(sz)
if v, ok := _data[int32(star)]; ok {
if int32(len(v)) > randomIndex {
cardId := v[randomIndex].Id
if star == 5 { // 抽出5星英雄后A次抽奖内不会再抽到5星英雄普通卡池+阵营卡池)
curDrawCount := drawCount - req.DrawCount
if drawCount <= 10 { // 前10次不计算连续抽卡最多连续出A个相同阵营的英雄
szCards = append(szCards, cardId)
continue
}
newID := this.module.ContinuousRestriction(session.GetUserId(), cardId, curDrawCount+int32(index+1), strPool[index])
szCards = append(szCards, newID)
continue
}
szCards = append(szCards, cardId)
// 普通卡池 最多连续出A个相同阵营的英雄
if req.DrawType == 0 {
newId := this.module.DrawCardContinuousRestrictionCamp(cardId, heroRecord.Race, sz, v)
if cardId != newId {
szCards[len(szCards)-1] = newId
}
}
}
}
}
// 消耗道具
if errdata = this.module.ConsumeRes(session, costRes, true); errdata != nil {
return
}
heroRecord.Totalcount += req.DrawCount
heroRecord.Daycount += req.DrawCount
update["star4"] = heroRecord.Star4
update["star5"] = heroRecord.Star5
update["drawcount"] = drawCount
update["totalcount"] = heroRecord.Totalcount
update["daycount"] = heroRecord.Daycount
this.module.modelRecord.ChangeHeroRecord(session.GetUserId(), update)
rsp := &pb.HeroDrawCardResp{
Data: []*pb.AtnoData{},
}
for _, heroId := range szCards {
if errdata, atno = this.module.DispenseAtno(session, []*cfg.Gameatn{{
A: "hero",
T: heroId,
N: 1,
}}, true); errdata == nil {
rsp.Data = append(rsp.Data, &pb.AtnoData{Atno: atno})
for _, v := range atno {
if v.A == "hero" && v.N == 1 {
if user := this.module.ModuleUser.GetUser(session.GetUserId()); user != nil { // 广播 首次获得英雄
this.chat.SendSysChatToWorld(comm.ChatSystem13, nil, 0, 0, user.Name, v.T)
}
}
}
} else {
return
}
}
session.SendMsg(string(this.module.GetType()), DrawCard, rsp)
// 任务统计
this.module.SendTaskMsg(session, szStar, req.DrawCount, normalDraw)
return
}