268 lines
7.5 KiB
Go
268 lines
7.5 KiB
Go
package hero
|
||
|
||
import (
|
||
"crypto/rand"
|
||
"go_dreamfactory/comm"
|
||
"go_dreamfactory/pb"
|
||
cfg "go_dreamfactory/sys/configure/structs"
|
||
"math/big"
|
||
|
||
"google.golang.org/protobuf/proto"
|
||
)
|
||
|
||
func (this *apiComp) DrawCardCheck(session comm.IUserSession, req *pb.HeroDrawCardReq) (code pb.ErrorCode) {
|
||
if req.DrawType < 0 && (req.DrawCount == 1 || req.DrawCount == 10) { // 只能是单抽或10抽
|
||
code = pb.ErrorCode_ReqParameterError
|
||
}
|
||
return
|
||
}
|
||
|
||
//抽卡
|
||
func (this *apiComp) DrawCard(session comm.IUserSession, req *pb.HeroDrawCardReq) (code pb.ErrorCode, data proto.Message) {
|
||
var (
|
||
szCards []string // 最终抽到的卡牌
|
||
drawCount int32 // 抽卡次数
|
||
szStar []int32 //星级
|
||
costRes []*cfg.Gameatn // 消耗
|
||
star4Max int32 // 10连抽最大4星数量
|
||
star5Max int32 // 10连抽最大5星数量
|
||
cfgDraw *cfg.GameGlobalData
|
||
costAtn *cfg.Gameatn
|
||
heroRecord *pb.DBHeroRecord
|
||
pool string
|
||
_mapAddHero map[string]int32
|
||
strPool []string // 10连跨多个卡池情况
|
||
update map[string]interface{}
|
||
normalDraw bool // 是否是普通抽
|
||
)
|
||
update = make(map[string]interface{})
|
||
_mapAddHero = make(map[string]int32, 0)
|
||
cfgDraw = this.module.configure.GetGlobalConf() // 读取抽卡配置文件
|
||
if cfgDraw == nil {
|
||
return
|
||
}
|
||
code = this.DrawCardCheck(session, req)
|
||
if code != pb.ErrorCode_Success {
|
||
return
|
||
}
|
||
szCards = make([]string, 0)
|
||
|
||
heroRecord, _ = this.module.modelRecord.GetHeroRecord(session.GetUserId())
|
||
drawCount = heroRecord.Drawcount
|
||
|
||
if req.DrawType == 0 { // 普通卡池抽卡
|
||
normalDraw = true
|
||
// 获取普通抽卡池
|
||
if req.DrawCount == 1 {
|
||
costAtn = cfgDraw.BasePoolCost
|
||
} else {
|
||
costAtn = cfgDraw.BasePool10cost
|
||
}
|
||
costRes = append(costRes, costAtn)
|
||
code = this.module.CheckRes(session, costRes)
|
||
if code != pb.ErrorCode_Success { // 消耗数量不足直接返回
|
||
return
|
||
}
|
||
|
||
for i := 0; i < int(req.DrawCount); i++ {
|
||
pool = this.module.modelHero.CheckPool(drawCount, cfgDraw)
|
||
drawCount += 1
|
||
strPool = append(strPool, pool)
|
||
ret := this.module.CheckCondition(session.GetUserId())
|
||
if ret == true { // 命中插入5星英雄
|
||
szStar = append(szStar, 5)
|
||
continue
|
||
}
|
||
sz := make([]int32, 0)
|
||
if cfgDraw.BasePoolStar3 != 0 {
|
||
sz = append(sz, cfgDraw.BasePoolStar3)
|
||
}
|
||
if cfgDraw.BasePoolStar4 != 0 {
|
||
sz = append(sz, cfgDraw.BasePoolStar4)
|
||
}
|
||
if cfgDraw.BasePoolStar5 != 0 {
|
||
sz = append(sz, cfgDraw.BasePoolStar5)
|
||
}
|
||
starIndex := this.module.modelHero.GetRandW(sz)
|
||
// 特殊规则 DrawCard_5StarsInRange 第2-30次抽奖必出一个5星英雄(普通卡池)
|
||
inRangeConf := this.module.configure.GetGlobalConf().DrawCard5StarsInRange
|
||
if len(inRangeConf) == 3 {
|
||
iStart := inRangeConf[0] // 抽卡开始
|
||
iEnd := inRangeConf[1] // 抽卡结束
|
||
star := inRangeConf[2]
|
||
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
|
||
}
|
||
}
|
||
// 保底情况
|
||
if heroRecord.Drawcount == iEnd && heroRecord.Inevitable == 0 {
|
||
starIndex = star - 3
|
||
heroRecord.Inevitable = heroRecord.Drawcount
|
||
update["inevitable"] = heroRecord.Drawcount
|
||
}
|
||
}
|
||
|
||
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 {
|
||
switch req.DrawType {
|
||
case 1:
|
||
pool = cfgDraw.Camp1Pool1
|
||
|
||
costAtn = cfgDraw.Camp1PoolCost
|
||
|
||
case 2:
|
||
pool = cfgDraw.Camp2Pool1
|
||
costAtn = cfgDraw.Camp2PoolCost
|
||
case 3:
|
||
pool = cfgDraw.Camp3Pool1
|
||
costAtn = cfgDraw.Camp3PoolCost
|
||
case 4:
|
||
pool = cfgDraw.Camp4Pool1
|
||
costAtn = cfgDraw.Camp4PoolCost
|
||
}
|
||
strPool = append(strPool, pool)
|
||
} else {
|
||
costAtn = cfgDraw.Camp1PoolCost
|
||
switch req.DrawType {
|
||
case 1:
|
||
pool = cfgDraw.Camp1Pool1
|
||
costAtn = cfgDraw.Camp1Pool10cost
|
||
|
||
case 2:
|
||
pool = cfgDraw.Camp2Pool1
|
||
costAtn = cfgDraw.Camp2Pool10cost
|
||
case 3:
|
||
pool = cfgDraw.Camp3Pool1
|
||
costAtn = cfgDraw.Camp3Pool10cost
|
||
case 4:
|
||
pool = cfgDraw.Camp4Pool1
|
||
costAtn = cfgDraw.Camp4Pool10cost
|
||
}
|
||
for i := 0; i < int(req.DrawCount); i++ {
|
||
strPool = append(strPool, pool)
|
||
}
|
||
}
|
||
|
||
costRes = append(costRes, costAtn)
|
||
|
||
//阵营消耗
|
||
code = this.module.CheckRes(session, costRes)
|
||
if code != pb.ErrorCode_Success { // 消耗数量不足直接返回
|
||
return
|
||
}
|
||
for {
|
||
sz := make([]int32, 0)
|
||
if cfgDraw.CampPoolStar3 != 0 {
|
||
sz = append(sz, cfgDraw.CampPoolStar3) // 3 4 5 星权重
|
||
}
|
||
if cfgDraw.CampPoolStar4 != 0 {
|
||
sz = append(sz, cfgDraw.CampPoolStar4)
|
||
}
|
||
if cfgDraw.CampPoolStar5 != 0 {
|
||
sz = append(sz, cfgDraw.CampPoolStar5)
|
||
|
||
}
|
||
starIndex := this.module.modelHero.GetRandW(sz)
|
||
if starIndex == 1 {
|
||
star4Max++
|
||
} else if starIndex == 2 {
|
||
star5Max++
|
||
}
|
||
if star4Max >= cfgDraw.Draw10Star4Max || star5Max >= cfgDraw.Draw10Star5Max {
|
||
starIndex = 0
|
||
}
|
||
szStar = append(szStar, starIndex+3)
|
||
if len(szStar) >= int(req.DrawCount) {
|
||
break
|
||
}
|
||
}
|
||
}
|
||
for index, star := range szStar {
|
||
|
||
_data := this.module.configure.GetPollByType(strPool[index])
|
||
if _data == nil {
|
||
code = pb.ErrorCode_ConfigNoFound
|
||
return
|
||
}
|
||
sz := make([]int32, 0)
|
||
for _, v := range _data[int32(star)] {
|
||
sz = append(sz, v.Weight)
|
||
}
|
||
randomIndex := this.module.modelHero.GetRandW(sz)
|
||
|
||
if v, ok := _data[int32(star)]; ok {
|
||
if int32(len(v)) > randomIndex {
|
||
if star == 5 { // 抽出5星英雄后A次抽奖内不会再抽到5星英雄(普通卡池+阵营卡池)
|
||
curDrawCount := drawCount - req.DrawCount
|
||
if curDrawCount <= 10 { // 首次十连不计算
|
||
continue
|
||
}
|
||
newID := this.module.ContinuousRestriction(session.GetUserId(), v[randomIndex].Id, curDrawCount+int32(index), strPool[index])
|
||
szCards = append(szCards, newID)
|
||
continue
|
||
}
|
||
szCards = append(szCards, v[randomIndex].Id)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 消耗道具
|
||
code = this.module.ConsumeRes(session, costRes, true)
|
||
if code != pb.ErrorCode_Success {
|
||
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)
|
||
for _, heroId := range szCards {
|
||
|
||
_mapAddHero[heroId]++
|
||
}
|
||
_, code = this.module.CreateRepeatHeros(session, _mapAddHero, true)
|
||
|
||
///英雄招募 【玩家名称】在招募中获得了【英雄名称】!
|
||
this.module.SendChatMsg(session, _mapAddHero, szCards)
|
||
|
||
// 任务统计
|
||
this.module.SendTaskMsg(session, szStar, req.DrawCount, normalDraw)
|
||
return
|
||
}
|