go_dreamfactory/modules/hero/api_drawCard.go
2023-10-17 13:54:53 +08:00

375 lines
12 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 (
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/pb"
"go_dreamfactory/sys/configure"
cfg "go_dreamfactory/sys/configure/structs"
)
func (this *apiComp) DrawCardCheck(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) DrawCard(session comm.IUserSession, req *pb.HeroDrawCardReq) (errdata *pb.ErrorData) {
var (
szCards []string // 最终抽到的卡牌
drawCount int32 // 抽卡次数
szStar []int32 //星级
costRes []*cfg.Gameatn // 消耗
star4Count int32 // 10连抽4星数量
star5Count int32 // 10连抽5星数量
cfgGlobal *cfg.GameGlobalData // 全局配置
heroRecord *pb.DBHeroRecord
strPool []string // 10连跨多个卡池情况
update map[string]interface{}
drawConf *cfg.GameDrawPoolData
err error
atno []*pb.UserAtno
IsBaodiPool bool // 是否是保底卡池
appointmap map[int32]string // 指定次数抽卡到指定卡池
// 首次获得英雄
firstGet map[string]bool
reward []*cfg.Gameatn // 许愿石奖励
)
update = make(map[string]interface{})
appointmap = make(map[int32]string)
firstGet = make(map[string]bool)
szCards = make([]string, 0)
if heroRecord, err = this.module.modelRecord.GetHeroRecord(session.GetUserId()); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Title: pb.ErrorCode_DBError.ToString(),
Message: err.Error(),
}
return
}
rsp := &pb.HeroDrawCardResp{
Data: []*pb.AtnoData{},
Wish: &pb.UserAtno{},
Record: heroRecord,
}
// 校验是否是心愿招募
if req.DrawType == comm.DrawCardType6 && req.DrawCount == 1 {
// 心愿消耗 走单独配置
// 校验许愿英雄
var cd int64
var drcount int32
//atn := this.module.ModuleTools.GetGlobalConf().ExchangeHero // 校验消耗数量
if conf := this.module.configure.GetWishHeroReplaceConfig(); conf != nil {
if heroRecord.WishHero == "" { // 如果当前许愿英雄是空 则读取 默认许愿英雄
heroRecord.WishHero = conf.InitHero
}
cd = int64(conf.Cond[heroRecord.WishHero].cd)
drcount = conf.Cond[heroRecord.WishHero].num
// 校验该抽卡是否在CD 中
if outTime, ok := heroRecord.Wish[heroRecord.WishHero]; ok {
if outTime > configure.Now().Unix() {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_HeroDrawCD,
}
return
} else { // 时间到了
heroRecord.Wish[heroRecord.WishHero] = 0 // 时间清0
}
}
costRes = append(costRes, conf.Cond[heroRecord.WishHero].buyCos)
if errdata = this.module.CheckRes(session, costRes); errdata != nil {
return
}
} else { // 配置错误
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ConfigNoFound,
Title: pb.ErrorCode_ConfigNoFound.ToString(),
Message: fmt.Sprintf("GetWishHeroReplaceConfig is nil"),
}
return
}
// 校验 解锁所需抽奖次数
if drcount > heroRecord.Race[comm.DrawCardType0] {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_HeroDrawCountErr,
}
return
}
var hero *pb.DBHero
firstGet[heroRecord.WishHero] = false
if hero, atno, errdata = this.module.ModuleHero.CreateOneHero(session, heroRecord.WishHero); errdata == nil {
for _, v := range atno {
if v.A == "hero" && v.T == heroRecord.WishHero && v.N == 1 {
firstGet[heroRecord.WishHero] = true
if user, err := this.module.ModuleUser.GetUser(session.GetUserId()); err == nil { // 广播 首次获得英雄
if HeroConf, err := this.module.configure.GetHeroConfig(heroRecord.WishHero); err == nil {
this.chat.SendSysChatToWorld(comm.ChatSystem13, hero, HeroConf.Star, 0, user.Name, v.T)
}
}
}
}
rsp.Data = append(rsp.Data, &pb.AtnoData{Atno: atno})
} else {
return
}
if errdata = this.module.ConsumeRes(session, costRes, true); errdata != nil {
return
}
// 修改recode 数据
if cd != 0 {
heroRecord.Wish[heroRecord.WishHero] = configure.Now().Unix() + cd
update["wish"] = heroRecord.Wish
this.module.modelRecord.ChangeHeroRecord(session.GetUserId(), update)
}
rsp.FirstGet = firstGet
session.SendMsg(string(this.module.GetType()), DrawCard, rsp)
return
}
// 准备数据
/////////////////////////////////////
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 // 指定次抽数据
}
////////////////////////////////////////////////////////
cfgGlobal = this.module.ModuleTools.GetGlobalConf() // 读取抽卡配置文件
if cfgGlobal == nil {
return
}
// 每日抽卡上限校验
if cfgGlobal.DrawToplimit < heroRecord.Daycount+req.DrawCount {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_HeroDayDrwaMax,
Title: pb.ErrorCode_HeroDayDrwaMax.ToString(),
Message: fmt.Sprintf("单日抽卡达到上限,抽卡次数:%d", cfgGlobal.DrawToplimit),
}
return
}
if errdata = this.DrawCardCheck(session, req); errdata != nil {
return
}
drawCount = heroRecord.Count[req.DrawType] // 获取当前阵容抽卡次数
if true { // 普通卡池抽卡
////// 获取消耗
if costRes, errdata = this.module.modelHero.CheckDrawCardRes(session, drawConf, req.Consume, req.DrawCount); errdata != nil {
return
}
// 校验是否达到保底卡池
if drawConf.Protect >= drawCount {
IsBaodiPool = true
}
///// 获取消耗 end
for i := 1; i <= int(req.DrawCount); i++ { // 一张一张的抽
heroRecord.Race[req.DrawType] += 1
drawCount++
heroRecord.Baodi5[req.DrawType]++
heroRecord.Baodi4[req.DrawType]++
if v, ok := appointmap[drawCount]; ok { // 优先校验是否是指定抽
strPool = append(strPool, v) //找到了
continue
}
Is5Star := false
starWeight := []int32{drawConf.Star3w, drawConf.Star4w, drawConf.Star5w} // 随机获取三星
if drawConf.Permission != -1 && heroRecord.Baodi5[req.DrawType] > 0 { // 橙权递增
starWeight[2] += this.module.configure.GetHeroDrawWeightConfigById(drawConf.Permission, heroRecord.Baodi5[req.DrawType])
}
starIndex := comm.GetRandW(starWeight) // 3 4 5 星索引
if IsBaodiPool {
if starIndex == 0 {
strPool = append(strPool, drawConf.P3pool)
} else if starIndex == 1 {
star4Count++
heroRecord.Baodi4[req.DrawType] = 0
strPool = append(strPool, drawConf.P4pool)
} else if starIndex == 2 {
star5Count++
heroRecord.Baodi5[req.DrawType] = 0
strPool = append(strPool, drawConf.P5pool)
Is5Star = true
}
} else {
if starIndex == 0 {
strPool = append(strPool, drawConf.N3pool)
} else if starIndex == 1 {
star4Count++
heroRecord.Baodi4[req.DrawType] = 0
strPool = append(strPool, drawConf.N4pool)
} else if starIndex == 2 {
star5Count++
heroRecord.Baodi5[req.DrawType] = 0
strPool = append(strPool, drawConf.N5pool)
Is5Star = true
}
}
// 判断是否必出5星
if heroRecord.Baodi5[req.DrawType] >= drawConf.Baidi5 && !Is5Star {
heroRecord.Baodi5[req.DrawType] = 0
star5Count++
if IsBaodiPool {
strPool[len(strPool)-1] = drawConf.P5pool
} else {
strPool[len(strPool)-1] = drawConf.N5pool
}
Is5Star = true
continue
}
// 判断是否必出4星
if heroRecord.Baodi4[req.DrawType] >= drawConf.Baodi4 {
heroRecord.Baodi4[req.DrawType] = 0
star4Count++
if IsBaodiPool {
strPool[len(strPool)-1] = drawConf.P4pool
} else {
strPool[len(strPool)-1] = drawConf.N4pool
}
continue
}
if req.DrawCount == 10 {
if star4Count >= cfgGlobal.Draw10Star4Max { // 10连抽最大4星数量
if IsBaodiPool {
strPool[len(strPool)-1] = drawConf.P3pool
} else {
strPool[len(strPool)-1] = drawConf.N3pool
}
}
if star5Count >= cfgGlobal.Draw10Star5Max { // 10连抽最大5星数量
if IsBaodiPool {
strPool[len(strPool)-1] = drawConf.P3pool
} else {
strPool[len(strPool)-1] = drawConf.N3pool
}
}
}
//抽出5星英雄后A次抽奖内不会再抽到5星英雄普通卡池+阵营卡池)
// if heroRecord.Race[req.DrawType] >= cfgGlobal.DrawCardContinuousRestrictionStar5 && Is5Star {
// if IsBaodiPool {
// strPool[len(strPool)-1] = drawConf.P3pool
// } else {
// strPool[len(strPool)-1] = drawConf.N3pool
// }
// Is5Star = false
// }
}
}
// 通过卡池获得最终的英雄
for _, v := range strPool {
card, err := this.module.configure.GetHeroByPool(v)
if err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ConfigNoFound,
Title: pb.ErrorCode_ConfigNoFound.ToString(),
Message: err.Error(),
}
return
}
szCards = append(szCards, card)
}
// 消耗道具
if errdata = this.module.ConsumeRes(session, costRes, true); errdata != nil {
return
}
heroRecord.Totalcount += req.DrawCount
heroRecord.Daycount += req.DrawCount
heroRecord.Count[req.DrawType] = drawCount
update["drawcount"] = drawCount
update["count"] = heroRecord.Count
update["totalcount"] = heroRecord.Totalcount
update["race"] = heroRecord.Race
update["daycount"] = heroRecord.Daycount
update["baodi4"] = heroRecord.Baodi4
update["baodi5"] = heroRecord.Baodi5
for _, heroId := range szCards {
//var
var (
hero *pb.DBHero
HeroConf *cfg.GameHeroData
)
if HeroConf, err = this.module.configure.GetHeroConfig(heroId); err == nil {
szStar = append(szStar, HeroConf.Star) // 获得许愿石
var tmp *cfg.Gameatn
if HeroConf.Star == 4 {
tmp = this.module.ModuleTools.GetGlobalConf().RewardStar4
reward = append(reward, tmp)
} else if HeroConf.Star == 5 {
tmp = this.module.ModuleTools.GetGlobalConf().RewardStar5
reward = append(reward, tmp)
if req.DrawType == comm.DrawCardType5 { // 限时招募
if heroRecord.LimitHero == "" {
if conf := this.module.configure.GetApportHeroReplaceConfig(); conf != nil {
heroRecord.LimitHero = conf.InitHero
update["limitHero"] = heroRecord.LimitHero
}
}
heroId = heroRecord.LimitHero // 替换成心愿英雄
}
}
if tmp != nil {
if rsp.Wish == nil {
rsp.Wish = &pb.UserAtno{
A: tmp.A,
T: tmp.T,
N: tmp.N,
}
} else {
rsp.Wish.N += tmp.N
}
}
}
firstGet[heroId] = false
var atno []*pb.UserAtno
if hero, atno, errdata = this.module.ModuleHero.CreateOneHero(session, heroId); errdata == nil {
for _, v := range atno {
if v.A == "hero" && v.T == heroId && v.N == 1 {
firstGet[heroId] = true
if user, err := this.module.ModuleUser.GetUser(session.GetUserId()); err == nil { // 广播 首次获得英雄
this.chat.SendSysChatToWorld(comm.ChatSystem13, hero, HeroConf.Star, 0, user.Name, v.T)
}
}
}
rsp.Data = append(rsp.Data, &pb.AtnoData{Atno: atno})
}
}
// 发放许愿石奖励
if errdata, atno = this.module.DispenseAtno(session, reward, true); errdata != nil {
return
}
rsp.FirstGet = firstGet
this.module.modelRecord.ChangeHeroRecord(session.GetUserId(), update)
session.SendMsg(string(this.module.GetType()), DrawCard, rsp)
// 任务统计
this.module.SendTaskMsg(session, szStar, req.DrawCount, req.DrawType)
return
}