package hero import ( "fmt" "go_dreamfactory/comm" "go_dreamfactory/lego/core" "go_dreamfactory/lego/sys/event" "go_dreamfactory/lego/sys/log" "go_dreamfactory/modules" "go_dreamfactory/pb" "go_dreamfactory/sys/configure" cfg "go_dreamfactory/sys/configure/structs" "go_dreamfactory/sys/db" "go_dreamfactory/utils" "go.mongodb.org/mongo-driver/bson" ) func NewModule() core.IModule { m := new(Hero) return m } type Hero struct { modules.ModuleBase api *apiComp configure *configureComp modelHero *ModelHero modelRecord *ModelRecord // 英雄抽卡保底,次数等数据 modelTalent *ModelTalent // 天赋系统 moduleFetter comm.IHeroFetter service core.IService moduleHoroscope comm.IHoroscope chat comm.IChat passon comm.IPasson mail comm.Imail modelDrawRecode *modelDrawRecode // 抽卡记录 } // 模块名 func (this *Hero) GetType() core.M_Modules { return comm.ModuleHero } // 模块初始化接口 注册用户创建角色事件 func (this *Hero) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) { if err = this.ModuleBase.Init(service, module, options); err != nil { return } this.service = service return } // 装备组件 func (this *Hero) OnInstallComp() { this.ModuleBase.OnInstallComp() this.api = this.RegisterComp(new(apiComp)).(*apiComp) this.modelHero = this.RegisterComp(new(ModelHero)).(*ModelHero) this.modelRecord = this.RegisterComp(new(ModelRecord)).(*ModelRecord) this.modelTalent = this.RegisterComp(new(ModelTalent)).(*ModelTalent) this.configure = this.RegisterComp(new(configureComp)).(*configureComp) this.modelDrawRecode = this.RegisterComp(new(modelDrawRecode)).(*modelDrawRecode) } func (this *Hero) Start() (err error) { if err = this.ModuleBase.Start(); err != nil { return } var module core.IModule if module, err = this.service.GetModule(comm.ModuleLibrary); err != nil { return } this.moduleFetter = module.(comm.IHeroFetter) if module, err = this.service.GetModule(comm.ModuleHoroscope); err != nil { return } this.moduleHoroscope = module.(comm.IHoroscope) if module, err = this.service.GetModule(comm.ModuleChat); err != nil { return } this.chat = module.(comm.IChat) if module, err = this.service.GetModule(comm.ModulePasson); err != nil { return } this.passon = module.(comm.IPasson) if module, err = this.service.GetModule(comm.ModuleMail); err != nil { return } this.mail = module.(comm.Imail) event.RegisterGO(comm.EventUserOffline, this.EventUserOffline) return } // 获取英雄 func (this *Hero) GetHeroByObjID(uid, heroId string) (hero *pb.DBHero, errdata *pb.ErrorData) { hero = this.modelHero.getOneHero(uid, heroId) if hero == nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_HeroNoExist, Title: pb.ErrorCode_HeroNoExist.ToString(), } } return } // 佩戴装备 func (this *Hero) UpdateEquipment(session comm.IUserSession, hero *pb.DBHero, equip []*pb.DB_Equipment) (errdata *pb.ErrorData) { if hero == nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_HeroNoExist, Title: pb.ErrorCode_HeroNoExist.ToString(), } return } list := make([]*pb.DBHero, 0) // if newHero, err := this.modelHero.setEquipment(session.GetUserId(), hero); err != nil { // errdata = &pb.ErrorData{ // Code: pb.ErrorCode_HeroEquipUpdate, // Title: pb.ErrorCode_HeroEquipUpdate.ToString(), // } // return // } else { // if newHero != nil { // list = append(list, newHero) // } // } list = append(list, hero) this.modelHero.setEquipProperty(hero, equip) session.SendMsg("hero", "change", &pb.HeroChangePush{List: list}) return } // 佩戴专属武器 func (this *Hero) UpdateExclusive(session comm.IUserSession, hero *pb.DBHero, exw *pb.DB_Exclusive) (errdata *pb.ErrorData) { if hero == nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_HeroNoExist, Title: pb.ErrorCode_HeroNoExist.ToString(), } return } list := make([]*pb.DBHero, 0) list = append(list, hero) this.modelHero.setExclusiveProperty(hero, exw) session.SendMsg("hero", "change", &pb.HeroChangePush{List: list}) return } // 英雄列表 func (this *Hero) GetHeroList(uid string) []*pb.DBHero { return this.modelHero.getHeroList(uid) } func (this *Hero) QueryHeroByConfId(uId string, heroCfgId string) (hero *pb.DBHero) { heroes := this.GetHeroList(uId) for _, v := range heroes { if v.HeroID == heroCfgId { return v } } return nil } // 删除指定卡牌 func (this *Hero) DelCard(udi string, hero *pb.DBHero) (errdata *pb.ErrorData) { err := this.modelHero.consumeHeroCard(udi, hero) if err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_DBError, Title: pb.ErrorCode_DBError.ToString(), Message: err.Error(), } return } return } // 清空数据 func (this *Hero) CleanData(uid string) { this.modelHero.cleanData(uid) } // Event-------------------------------------------------------------------------------------------------玩家离线 func (this *Hero) EventUserOffline(uid, sessionid string) { this.modelHero.RemoveUserHeroInfo(uid) } // 批量创建多个英雄 func (this *Hero) CreateRepeatHeros(session comm.IUserSession, heros map[string]int32, bPush bool) (atno []*pb.UserAtno, errdata *pb.ErrorData) { var ( szAddHero []string changeList []*pb.DBHero curSzCard []string err error addres [][]*cfg.Gameatn add []*pb.DBHero res []*cfg.Gameatn ) for k, v := range heros { for i := 0; i < int(v); i++ { curSzCard = append(curSzCard, k) } } if addres, add, err = this.modelHero.ImitateHeros(session, curSzCard, false); err == nil { for _, v := range add { changeList = append(changeList, v) szAddHero = append(szAddHero, v.HeroID) } } for _, v := range addres { for _, v1 := range v { if v1.A != "hero" { res = append(res, v1) } } } if errdata, atno = this.DispenseAtno(session, res, true); errdata != nil { return } return } // 英雄练功 func (this *Hero) KungFuHero(session comm.IUserSession, heroObjID string, bKongfu bool, kongfuUid string) (errdata *pb.ErrorData) { var ( _hero *pb.DBHero _changeHero []*pb.DBHero // 变化的英雄 model *db.DBModel // 跨服对象 err error ) if this.IsCross() { _hero = &pb.DBHero{} if model, err = this.GetDBModelByUid(session.GetUserId(), this.modelHero.TableName); err == nil { if err := model.GetListObj(session.GetUserId(), heroObjID, _hero); err != nil { this.Errorf("err:%v", err) return } } } else { _hero, errdata = this.GetHeroByObjID(session.GetUserId(), heroObjID) if errdata != nil { return } } if bKongfu && _hero.Status == pb.HeroType_HeroTypeKongFu { errdata = &pb.ErrorData{ Code: pb.ErrorCode_HeroAlreadyKongFuStatus, // 已经是练功状态 Title: pb.ErrorCode_HeroAlreadyKongFuStatus.ToString(), } return } if !bKongfu && _hero.Status == pb.HeroType_HeroTypeNil { return } _hero.KongfuUid = kongfuUid if bKongfu { _hero.Status = pb.HeroType_HeroTypeKongFu } else { _hero.Status = pb.HeroType_HeroTypeNil _hero.KongfuUid = "" } _heroMap := map[string]interface{}{ "status": _hero.Status, "kongfuUid": _hero.KongfuUid, } if this.IsCross() { if model != nil { if err := model.ChangeList(session.GetUserId(), heroObjID, _heroMap); err != nil { this.Errorf("err:%v", err) errdata = &pb.ErrorData{ Code: pb.ErrorCode_DBError, Title: pb.ErrorCode_DBError.ToString(), Message: err.Error(), } return } } } else { if err := this.modelHero.ChangeList(session.GetUserId(), heroObjID, _heroMap); err != nil { // 修改英雄信息 this.Errorf("err:%v", err) errdata = &pb.ErrorData{ Code: pb.ErrorCode_DBError, Title: pb.ErrorCode_DBError.ToString(), Message: err.Error(), } return } } _changeHero = append(_changeHero, _hero) session.SendMsg(string(this.GetType()), "change", &pb.HeroChangePush{List: _changeHero}) return } // 创建怪物英雄 func (this *Hero) CreateMonster(heroCid string, star, lv int32) (hero *pb.DBHero) { hero = this.modelHero.InitMonsterHero(heroCid, star, lv) return } // 只通过唯一id 查询英雄信息 func (this *Hero) QueryCrossHeroinfo(oid string) (hero *pb.DBHero, err error) { if this.IsCross() { for _, tag := range db.GetServerTags() { conn, err1 := db.ServerDBConn(tag) // 遍历连接对象 if err1 != nil { continue } sr := conn.Mgo.FindOne(comm.TableHero, bson.M{ "_id": oid, }) hero = &pb.DBHero{} if err = sr.Decode(hero); err != nil { this.modelHero.module.Errorf("find hero error: %v", err) } return } } else { // 不是跨服就查本服 注意 这个接口是给跨服玩法调用 理论上这个分支是不会执行的 if res := this.modelHero.DB.FindOne(comm.TableHero, bson.M{ "_id": oid, }); res == nil { hero = &pb.DBHero{} if err = res.Decode(hero); err != nil { this.modelHero.module.Errorf("find hero error: %v", err) return } } } return } // 获取非叠加英雄信息 func (this *Hero) GetHeroListByUse(uid string) []*pb.DBHero { tmp := make([]*pb.DBHero, 0) for _, v := range this.modelHero.getHeroList(uid) { tmp = append(tmp, v) } return tmp } func (this *Hero) PushHeroProperty(session comm.IUserSession, heros []*pb.DBHero) (err error) { if len(heros) > 0 { err = session.SendMsg(string(this.GetType()), "change", &pb.HeroChangePush{List: heros}) } return } // 检查大于lv等级英雄的数量 func (this *Hero) CheckLvNum(uid string, lv int32) int32 { tmp := make([]*pb.DBHero, 0) for _, v := range this.modelHero.getHeroList(uid) { if v.Lv >= lv { tmp = append(tmp, v) } } return int32(len(tmp)) } func (this *Hero) GetTujianHeroNum(uid string) int32 { return int32(len(this.modelHero.getHeroList(uid))) } // //拥有觉醒至A级的B星英雄N个 func (this *Hero) CheckJuexingHeroNum(uid string, juexingLv int32, star int32) int32 { tmp := make([]*pb.DBHero, 0) for _, v := range this.modelHero.getHeroList(uid) { if v.JuexingLv >= juexingLv && v.Star >= star { tmp = append(tmp, v) } } return int32(len(tmp)) } // 获取所有满星满级满觉醒的英雄 func (this *Hero) GetAllMaxHero(session comm.IUserSession) (errdata *pb.ErrorData) { this.modelTalent.CleanAllHeroTalent(session.GetUserId()) // 清除所有英雄 this.modelHero.RemoveUserHeroInfo(session.GetUserId()) data := this.modelHero.module.configure.GetHeroConfigData() var ( changeHero []*pb.DBHero ) for _, v := range data { if v.Handbook { cid := v.Hid maxStar := v.Star starConf, _ := this.configure.GetHeroStarupConfig(cid, v.Star) if starConf == nil { continue // 走到这里说明配置表没有配置数据 } // 获取最大星级 maxStar = this.configure.GetHeroMaxStar(cid, v.Star) maxLv, err := this.configure.GetHeroMaxLv(maxStar) if err != nil { // 最大等级 errdata = &pb.ErrorData{ Code: pb.ErrorCode_ConfigNoFound, Title: pb.ErrorCode_ConfigNoFound.ToString(), Message: fmt.Sprintf("cid:%s err:%s", cid, err.Error()), } } maxJux := 1 // 最大觉醒等级 for i := 1; ; i++ { _, err := this.configure.GetHeroAwakenConfig(cid, int32(i)) if err != nil { maxJux = i - 1 break } } // 开始创建英雄 hero, err := this.modelHero.gmCreateSpecialHero(session.GetUserId(), v.Hid) if err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_HeroCreate, Title: pb.ErrorCode_HeroCreate.ToString(), Message: err.Error(), } } // 觉醒技能带入 for i := 1; i <= maxJux; i++ { if awakenData, err := this.configure.GetHeroAwakenConfig(cid, int32(i)); err == nil { if awakenData.Skill != 0 { skillMaxLv := this.configure.GetHeroSkillMaxLvConfig(uint32(awakenData.Skill)) hero.Awakenskill = append(hero.Awakenskill, &pb.SkillData{ SkillID: awakenData.Skill, SkillLv: skillMaxLv, }) } } else { break } } // 获取满级技能 for _, skill := range hero.NormalSkill { skillMaxLv := this.configure.GetHeroSkillMaxLvConfig(uint32(skill.SkillID)) if skill.SkillLv < skillMaxLv && skillMaxLv > 0 { skill.SkillLv = skillMaxLv } } hero.Lv = maxLv hero.Star = maxStar hero.JuexingLv = int32(maxJux) if true { // 满天赋 talent, _ := this.modelTalent.CreateHeroTalent(session.GetUserId(), hero.HeroID) data, err := this.configure.GMGetTalentByHeroId(hero.HeroID) if err == nil { for _, v := range data { talent.Talent[v.Skillid] = 1 if v.Skill != 0 { hero.Talentskill = append(hero.Talentskill, &pb.SkillData{ SkillID: v.Skill, SkillLv: 1, }) } } } update := make(map[string]interface{}, 0) update["talent"] = talent.Talent if err = this.modelTalent.ChangeHeroTalent(talent, update); err != nil { this.Errorf("update failed :%v", err) } } this.modelHero.PropertyCompute(hero) // 重新计算属性 _heroMap := map[string]interface{}{ "lv": hero.Lv, "star": hero.Star, "juexingLv": hero.JuexingLv, "sameCount": 1, "normalSkill": hero.NormalSkill, "talentProperty": hero.TalentProperty, "property": hero.Property, "horoscopeProperty": hero.HoroscopeProperty, "juexProperty": hero.JuexProperty, "awakenskill": hero.Awakenskill, "talentskill": hero.Talentskill, "fightvalue": hero.Fightvalue, } // 保存数据 err = this.modelHero.ChangeList(session.GetUserId(), hero.Id, _heroMap) if err != nil { log.Errorf("GetSpecified failed:%v", err) continue } changeHero = append(changeHero, hero) } } //推送 if len(changeHero) > 0 { this.passon.HeroUpLv(session, changeHero[0].HeroID, changeHero[0].Lv) session.SendMsg("hero", "change", &pb.HeroChangePush{List: changeHero}) } return } func (this *Hero) SendTaskMsg(session comm.IUserSession, szStar []int32, drawCount int32, drawtype int32, szCards []string) { // 任务统计 var ( tasks []*pb.BuriedParam colorCount int32 ) if drawtype == comm.DrawCardType0 { //普通招募 if drawCount == 10 { sz := make(map[int32]int32, 0) for _, star := range szStar { sz[star]++ } for k := range sz { tasks = append(tasks, comm.GetBuriedParam(comm.Rtype17, 1, k)) } } tasks = append(tasks, comm.GetBuriedParam(comm.Rtype14, drawCount)) tasks = append(tasks, comm.GetBuriedParam(comm.Rtype18, drawCount)) tasks = append(tasks, comm.GetBuriedParam(comm.Rtype141, drawCount)) tasks = append(tasks, comm.GetBuriedParam(comm.Rtype143, drawCount)) tasks = append(tasks, comm.GetBuriedParam(comm.Rtype145, drawCount)) } else { // 阵营招募 tasks = append(tasks, comm.GetBuriedParam(comm.Rtype15, drawCount)) tasks = append(tasks, comm.GetBuriedParam(comm.Rtype19, drawCount)) tasks = append(tasks, comm.GetBuriedParam(comm.Rtype142, drawCount)) tasks = append(tasks, comm.GetBuriedParam(comm.Rtype144, drawCount)) tasks = append(tasks, comm.GetBuriedParam(comm.Rtype146, drawCount)) if drawCount == 10 { tasks = append(tasks, comm.GetBuriedParam(comm.Rtype91, 1)) } } for _, star := range szStar { tasks = append(tasks, comm.GetBuriedParam(comm.Rtype16, star, 1)) } if drawCount == 10 { tasks = append(tasks, comm.GetBuriedParam(comm.Rtype90, 1)) } for _, v := range szCards { if conf, e := this.configure.GetHeroConfig(v); e != nil { tasks = append(tasks, comm.GetBuriedParam(comm.Rtype245, conf.Color, conf.Race, 1)) if conf.Color >= 3 { // 紫色以上 colorCount++ } } } if colorCount > 0 { tasks = append(tasks, comm.GetBuriedParam(comm.Rtype246, colorCount)) } tasks = append(tasks, comm.GetBuriedParam(comm.Rtype89, drawCount)) this.ModuleBuried.TriggerBuried(session, tasks...) } func (this *Hero) RegisterInstructor(session comm.IUserSession, heroOid []string, fulllvenr int32) (errdata *pb.ErrorData) { var ( _szHero []*pb.DBHero model *db.DBModel err error _heroMap map[string]interface{} _changeHero []*pb.DBHero // 变化的英雄 ) if this.IsCross() { if model, err = this.GetDBModelByUid(session.GetUserId(), this.modelHero.TableName); err == nil { for _, v := range heroOid { _hero := &pb.DBHero{} if err := model.GetListObj(session.GetUserId(), v, _hero); err != nil { this.Errorf("err:%v", err) return } _szHero = append(_szHero, _hero) } } } else { for _, v := range heroOid { _hero, err := this.GetHeroByObjID(session.GetUserId(), v) if err != nil { errdata = err return } _szHero = append(_szHero, _hero) } } for _, v := range _szHero { _heroMap = make(map[string]interface{}) if fulllvenr == 0 && v.Fulllvenr != 0 { v.Fulllvenr = 0 _heroMap["fulllvenr"] = 0 } else if v.Fulllvenr == 0 && fulllvenr != 0 { // 校验有没有满级 var maxlv int32 if maxlv, err = this.configure.GetHeroMaxLv(v.Star); err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_ConfigNoFound, Title: pb.ErrorCode_ConfigNoFound.ToString(), Message: fmt.Sprintf("cid:%s id:%s err:%s", v.HeroID, v.Id, err.Error()), } return } if v.Lv < maxlv { errdata = &pb.ErrorData{ Code: pb.ErrorCode_HeroLvNoEnough, Title: pb.ErrorCode_HeroLvNoEnough.ToString(), } return } v.Fulllvenr = fulllvenr _heroMap["fulllvenr"] = v.Fulllvenr } else { errdata = &pb.ErrorData{ Code: pb.ErrorCode_HeroIsRegister, Title: pb.ErrorCode_HeroIsRegister.ToString(), } return } if this.IsCross() { if model != nil { if err := model.ChangeList(session.GetUserId(), v.Id, _heroMap); err != nil { this.Errorf("err:%v", err) errdata = &pb.ErrorData{ Code: pb.ErrorCode_DBError, Title: pb.ErrorCode_DBError.ToString(), Message: err.Error(), } return } } } else { if err := this.modelHero.ChangeList(session.GetUserId(), v.Id, _heroMap); err != nil { // 修改英雄信息 this.Errorf("err:%v", err) errdata = &pb.ErrorData{ Code: pb.ErrorCode_DBError, Title: pb.ErrorCode_DBError.ToString(), Message: err.Error(), } return } } _changeHero = append(_changeHero, v) } if len(_changeHero) > 0 { session.SendMsg(string(this.GetType()), "change", &pb.HeroChangePush{List: _changeHero}) } return } // 只通过唯一id 查询英雄信息 func (this *Hero) QueryCrossMultipleHeroinfo(uid string, oid []string) (hero []*pb.DBHero, err error) { if this.IsCross() { if tag, _, b := utils.UIdSplit(uid); b { if conn, err := db.ServerDBConn(tag); err == nil { dbModel := db.NewDBModel(tag, comm.TableMail, conn) err = dbModel.GetListObjs(uid, oid, &hero) } } } else { hero, err = this.modelHero.getHeros(uid, oid) } return } func (this *Hero) AddHeroFetterAttribute(session comm.IUserSession, attr map[string][]*cfg.Gameatr) { chanegCard := make([]*pb.DBHero, 0) heroList := this.GetHeroList(session.GetUserId()) for _, v := range heroList { if v1, ok := attr[v.HeroID]; ok { // 找到对应的英雄ID _heroMap := make(map[string]interface{}, 0) this.modelHero.SetHeroFetterProperty(v, v1) _heroMap["fetters"] = v.Fetters // 保存数据 err := this.modelHero.ChangeList(session.GetUserId(), v.Id, _heroMap) if err != nil { this.Errorf("SetHeroFetterProperty failed:%v", err) continue } chanegCard = append(chanegCard, v) } } if len(chanegCard) > 0 { session.SendMsg(string(this.GetType()), "change", &pb.HeroChangePush{List: chanegCard}) } } func (this *Hero) QueryHeroTelnetByCount(uid string, count int) (hids []string) { list, err := this.modelTalent.GetHerotalent(uid) if err != nil { return } for _, v := range list { if len(v.Talent) >= count { hids = append(hids, v.HeroId) } } return } func (this *Hero) PassonHero(session comm.IUserSession, heroObjID map[string]bool) (errdata *pb.ErrorData) { var ( _hero *pb.DBHero _changeHero []*pb.DBHero // 变化的英雄 model *db.DBModel // 跨服对象 err error ) for oid, b := range heroObjID { if this.IsCross() { _hero = &pb.DBHero{} if model, err = this.GetDBModelByUid(session.GetUserId(), this.modelHero.TableName); err == nil { if err := model.GetListObj(session.GetUserId(), oid, _hero); err != nil { this.Errorf("err:%v", err) return } } } else { _hero, errdata = this.GetHeroByObjID(session.GetUserId(), oid) if errdata != nil { return } } _hero.Ispasson = b _heroMap := map[string]interface{}{ "ispasson": _hero.Ispasson, } if this.IsCross() { if model != nil { if err := model.ChangeList(session.GetUserId(), oid, _heroMap); err != nil { this.Errorf("err:%v", err) errdata = &pb.ErrorData{ Code: pb.ErrorCode_DBError, Title: pb.ErrorCode_DBError.ToString(), Message: err.Error(), } return } } } else { if err := this.modelHero.ChangeList(session.GetUserId(), oid, _heroMap); err != nil { // 修改英雄信息 this.Errorf("err:%v", err) errdata = &pb.ErrorData{ Code: pb.ErrorCode_DBError, Title: pb.ErrorCode_DBError.ToString(), Message: err.Error(), } return } } } _changeHero = append(_changeHero, _hero) session.SendMsg(string(this.GetType()), "change", &pb.HeroChangePush{List: _changeHero}) return } // 构建一个虚拟等级的英雄 func (this *Hero) GetVirtualHero(hero *pb.DBHero, lv int32) *pb.DBHero { if hero == nil || lv <= 0 { return hero } hero.Lv = lv this.modelHero.initHeroSkill(hero) // 初始英雄技能 this.modelHero.PropertyCompute(hero) return hero } func (this *Hero) CheckPeachReward(session comm.IUserSession, ctime int64) { var ( reward []*cfg.Gameatn // 奖励 ) if drawConf, err := this.configure.GetHeroDrawConfigByType(comm.DrawCardType0); err == nil { if drawConf.Etime != -1 { if ctime+int64(drawConf.Etime*3600*24) < configure.Now().Unix() { // 校验时间 是否在活动范围 heroRecord, _ := this.modelRecord.GetHeroRecord(session.GetUserId()) if !heroRecord.Peachreward { allreawd := this.configure.GetAllDrawRewardConf() for k, v := range allreawd { if _, ok := heroRecord.Peach[k]; !ok { if v1, ok := heroRecord.Race[comm.DrawCardType0]; ok { if v1 > v.Num { //可以领取 reward = append(reward, v.Reward) } } } } heroRecord.Peachreward = true update := make(map[string]interface{}) update["peachreward"] = heroRecord.Peachreward this.modelRecord.ChangeHeroRecord(session.GetUserId(), update) // 发邮件 if len(reward) > 0 { this.mail.SendMailByUID(session.GetUserId(), comm.MailPeackReward, reward, []string{}) } } } } } return } func (this *Hero) AddHerosExp(session comm.IUserSession, heroObjs []string, exp int32) (curAddExp map[string]int32, award []*cfg.Gameatn, errdata *pb.ErrorData) { var ( ids []string = make([]string, 0) heros []*pb.DBHero changeHero []*pb.DBHero // 变化的英雄 err error ) curAddExp = make(map[string]int32, len(heroObjs)) for _, v := range heroObjs { if v != "" { ids = append(ids, v) } } if this.IsCross() { if model, err := this.GetDBModelByUid(session.GetUserId(), this.modelHero.TableName); err == nil { if err := model.GetListObjs(session.GetUserId(), ids, &heros); err != nil { this.Errorf("err:%v", err) errdata = &pb.ErrorData{ Code: pb.ErrorCode_DBError, Message: err.Error(), } return } if curAddExp, award, errdata = this.modelHero.AddCardExp(session, heros, exp, model); errdata != nil { return } changeHero = append(changeHero, heros...) } } else { if heros, err = this.modelHero.getHeros(session.GetUserId(), ids); err != nil { errdata = &pb.ErrorData{ Code: pb.ErrorCode_DBError, Message: err.Error(), } return } if curAddExp, award, errdata = this.modelHero.AddCardExp(session, heros, exp, nil); errdata != nil { return } changeHero = append(changeHero, heros...) } if len(changeHero) > 0 { session.SendMsg(string(this.GetType()), "change", &pb.HeroChangePush{List: changeHero}) } return } func (this *Hero) GetRandomCardByCardPool(uid string, count int32) (cards []string, err error) { var ( drawCount int32 // 抽卡次数 star4Count int32 // 10连抽4星数量 star5Count int32 // 10连抽5星数量 heroRecord *pb.DBHeroRecord strPool []string update map[string]interface{} drawConf *cfg.GameDrawPoolData IsBaodiPool bool // 是否是保底卡池 appointmap map[int32]string // 指定次数抽卡到指定卡池 ) var drawType int32 drawType = 9 update = make(map[string]interface{}) appointmap = make(map[int32]string) if heroRecord, err = this.modelRecord.GetHeroRecord(uid); err != nil { return } drawConf, err = this.configure.GetHeroDrawConfigByType(drawType) // 获取新的抽卡配置 if err != nil { return } for _, v := range drawConf.RecruitmentType { appointmap[v.K] = v.S // 指定次抽数据 } drawCount = heroRecord.Count[drawType] // 获取当前阵容抽卡次数 if true { // 普通卡池抽卡 // 校验是否达到保底卡池 if drawConf.Protect >= drawCount && drawConf.Protect != 0 { IsBaodiPool = true } ///// 获取消耗 end for i := 1; i <= int(count); i++ { // 一张一张的抽 heroRecord.Race[drawType] += 1 drawCount++ heroRecord.Baodi5[drawType]++ heroRecord.Baodi4[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[drawType] > 0 { // 橙权递增 starWeight[2] += this.configure.GetHeroDrawWeightConfigById(drawConf.Permission, heroRecord.Baodi5[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[drawType] = 0 strPool = append(strPool, drawConf.P4pool) } else if starIndex == 2 { star5Count++ heroRecord.Baodi5[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[drawType] = 0 strPool = append(strPool, drawConf.N4pool) } else if starIndex == 2 { star5Count++ heroRecord.Baodi5[drawType] = 0 strPool = append(strPool, drawConf.N5pool) Is5Star = true } } // 判断是否必出5星 if heroRecord.Baodi5[drawType] >= drawConf.Baidi5 && !Is5Star { heroRecord.Baodi5[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[drawType] >= drawConf.Baodi4 { heroRecord.Baodi4[drawType] = 0 star4Count++ if IsBaodiPool { strPool[len(strPool)-1] = drawConf.P4pool } else { strPool[len(strPool)-1] = drawConf.N4pool } continue } } } // 通过卡池获得最终的英雄 for _, v := range strPool { if card, err := this.configure.GetHeroByPool(v); err == nil { cards = append(cards, card) } } heroRecord.Count[drawType] = drawCount update["count"] = heroRecord.Count update["race"] = heroRecord.Race update["baodi4"] = heroRecord.Baodi4 update["baodi5"] = heroRecord.Baodi5 err = this.modelRecord.ChangeHeroRecord(uid, update) return }