package hero import ( "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/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 } //模块名 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) { err = this.ModuleBase.Init(service, module, options) 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) } func (this *Hero) Start() (err error) { var module core.IModule if module, err = this.service.GetModule(comm.ModuleLibrary); err != nil { return } this.moduleFetter = module.(comm.IHeroFetter) err = this.ModuleBase.Start() event.RegisterGO(comm.EventUserOffline, this.EventUserOffline) return } //创建单个叠加英雄 func (this *Hero) CreateRepeatHero(session comm.IUserSession, heroCfgId string, num int32, bPush bool) (code pb.ErrorCode) { _hero, err := this.modelHero.createHeroOverlying(session.GetUserId(), heroCfgId, num) if err == nil { go func(uid string, heroCfgId string) { // 携程处理 图鉴数据 if db.IsCross() { this.moduleFetter.SendRpcAddHero(session, heroCfgId) } else { this.moduleFetter.AddHeroFetterData(uid, heroCfgId) } if result, err1 := this.ModuleUser.GetUserExpand(uid); err1 == nil { initUpdate := map[string]interface{}{} sz := result.GetTujian() if len(sz) == 0 { sz = make(map[string]int32, 0) } if _, ok := result.GetTujian()[heroCfgId]; !ok { sz[heroCfgId] = 0 initUpdate["tujian"] = sz } if len(initUpdate) != 0 { this.ModuleUser.ChangeUserExpand(uid, initUpdate) } } }(session.GetUserId(), heroCfgId) // 统计任务 this.ModuleRtask.SendToRtask(session, comm.Rtype1, utils.ToInt32(heroCfgId)) // 查品质 cfg := this.configure.GetHeroConfig(heroCfgId) if cfg != nil { this.ModuleRtask.SendToRtask(session, comm.Rtype30, 1, cfg.Color) this.ModuleRtask.SendToRtask(session, comm.Rtype31, 1, cfg.Color) } if bPush { //推送 session.SendMsg("hero", "change", &pb.HeroChangePush{List: []*pb.DBHero{_hero}}) } return } code = pb.ErrorCode_HeroCreate return } //获取英雄 func (this *Hero) GetHeroByObjID(uid, heroId string) (*pb.DBHero, pb.ErrorCode) { hero := this.modelHero.getOneHero(uid, heroId) if hero == nil { return nil, pb.ErrorCode_HeroNoExist } return hero, pb.ErrorCode_Success } //佩戴装备 func (this *Hero) UpdateEquipment(session comm.IUserSession, hero *pb.DBHero, equip []*pb.DB_Equipment) (code pb.ErrorCode) { if hero == nil { code = pb.ErrorCode_HeroNoExist return } list := make([]*pb.DBHero, 0) if newHero, err := this.modelHero.setEquipment(hero); err != nil { code = pb.ErrorCode_HeroEquipUpdate 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}) // 随机任务统计 if hero.SuiteId != 0 || hero.SuiteExtId != 0 { this.SendRdTask(session) } return } func (this *Hero) SendRdTask(session comm.IUserSession) { equipmap := make(map[int32]map[int32]int32, 0) // k 套装id k1 xx星 v 数量 list := this.GetHeroList(session.GetUserId()) for _, v := range list { if v.SuiteId != 0 { if _, ok := equipmap[v.SuiteId]; !ok { equipmap[v.SuiteId] = make(map[int32]int32, 0) } equipmap[v.SuiteId][v.Suite1Star]++ } if v.SuiteExtId != 0 { if _, ok := equipmap[v.SuiteExtId]; !ok { equipmap[v.SuiteExtId] = make(map[int32]int32, 0) } equipmap[v.SuiteExtId][v.Suite2Star]++ } } for k, v := range equipmap { for k1, v1 := range v { this.ModuleRtask.SendToRtask(session, comm.Rtype46, v1, k1, k) } } } //英雄列表 func (this *Hero) GetHeroList(uid string) []*pb.DBHero { return this.modelHero.getHeroList(uid) } //查询英雄数量 func (this *Hero) QueryHeroAmount(uId string, heroCfgId string) (amount uint32) { heroes := this.GetHeroList(uId) for _, v := range heroes { if v.HeroID == heroCfgId { amount++ } } return amount } // 删除指定卡牌 func (this *Hero) DelCard(udi string, hero *pb.DBHero, amount int32) (code pb.ErrorCode) { err := this.modelHero.consumeHeroCard(udi, hero, amount) if err != nil { code = pb.ErrorCode_DBError return } return } // 清空数据 func (this *Hero) CleanData(uid string) { this.modelHero.cleanData(uid) } // 创建一些特殊的英雄 func (this *Hero) GetSpecifiedHero(session comm.IUserSession, heroConfId string, star, lv, amount int32) (code pb.ErrorCode) { if session.GetUserId() == "" || heroConfId == "" || star == 0 || lv == 0 || amount == 0 { return pb.ErrorCode_ReqParameterError } hero, err := this.modelHero.createOneHero(session.GetUserId(), heroConfId) if err != nil { return pb.ErrorCode_HeroCreate } hero.Lv = lv hero.Star = star hero.SameCount = amount _heroMap := map[string]interface{}{ "lv": hero.Lv, "star": hero.Star, "isOverlying": false, "sameCount": amount, } // 保存数据 err = this.modelHero.ChangeList(session.GetUserId(), hero.Id, _heroMap) if err != nil { log.Errorf("GetSpecified failed:%v", err) return } // push change session.SendMsg("hero", "change", &pb.HeroChangePush{List: []*pb.DBHero{hero}}) return } //Event-------------------------------------------------------------------------------------------------玩家离线 func (this *Hero) EventUserOffline(session comm.IUserSession) { err := this.modelHero.RemoveUserHeroInfo(session) this.Debugf("EventUserOffline:%s err:%v", session, err) } // 批量创建多个英雄 func (this *Hero) CreateRepeatHeros(session comm.IUserSession, heros map[string]int32, bPush bool) (code pb.ErrorCode) { for heroCfgId, num := range heros { if num == 0 { // 数量为0 不做处理 continue } if code = this.CreateRepeatHero(session, heroCfgId, num, bPush); code != pb.ErrorCode_Success { this.Errorf("create hero %s failed", heroCfgId) } } return } func (this *Hero) AddHeroExp(session comm.IUserSession, heroObjID string, exp int32) (code pb.ErrorCode) { var ( _hero *pb.DBHero newhero *pb.DBHero _changeHero []*pb.DBHero // 变化的英雄 ) if heroObjID == "" { return } _hero, code = this.GetHeroByObjID(session.GetUserId(), heroObjID) if code != pb.ErrorCode_Success { return } newhero, code = this.modelHero.AddCardExp(session, _hero, exp) if code != pb.ErrorCode_Success { return } _changeHero = append(_changeHero, _hero) // 升级后的英雄 hero id 不变 if newhero != nil { _changeHero = append(_changeHero, newhero) // 原来的英雄 只是数量变化了 } session.SendMsg(string(this.GetType()), "change", &pb.HeroChangePush{List: _changeHero}) return } // 英雄练功 func (this *Hero) KungFuHero(session comm.IUserSession, heroObjID string, bKongfu bool) (code pb.ErrorCode) { var ( _hero *pb.DBHero newhero *pb.DBHero _changeHero []*pb.DBHero // 变化的英雄 ) _hero, code = this.GetHeroByObjID(session.GetUserId(), heroObjID) if code != pb.ErrorCode_Success { return } if bKongfu && _hero.Status == pb.HeroType_HeroTypeKongFu { code = pb.ErrorCode_HeroAlreadyKongFuStatus // 已经是练功状态 return } if !bKongfu { _heroMap := map[string]interface{}{ "status": pb.HeroType_HeroTypeNil, } err1 := this.modelHero.ChangeList(session.GetUserId(), heroObjID, _heroMap) // 修改英雄信息 if err1 != nil { this.Errorf("update hero skill failed:%v", err1) code = pb.ErrorCode_DBError return } _hero.Status = pb.HeroType_HeroTypeNil _changeHero = append(_changeHero, _hero) session.SendMsg(string(this.GetType()), "change", &pb.HeroChangePush{List: _changeHero}) return } if _hero.SameCount > 1 { _hero.SameCount -= 1 newHero := this.modelHero.CloneNewHero(_hero) _changeHero = append(_changeHero, newHero) } _heroMap := map[string]interface{}{ "status": pb.HeroType_HeroTypeKongFu, "isOverlying": false, "sameCount": 1, } _hero.Status = pb.HeroType_HeroTypeKongFu _hero.SameCount = 1 err1 := this.modelHero.ChangeList(session.GetUserId(), heroObjID, _heroMap) // 修改英雄信息 if err1 != nil { this.Errorf("update hero skill failed:%v", err1) code = pb.ErrorCode_DBError return } _changeHero = append(_changeHero, _hero) // 升级后的英雄 hero id 不变 if newhero != nil { _changeHero = append(_changeHero, newhero) // 原来的英雄 只是数量变化了 } _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.InitTempHero(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 { return } else { this.modelHero.moduleHero.Errorf("find hero error: %v", err) } } } 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.moduleHero.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) { if !v.IsOverlying { tmp = append(tmp, v) } } return tmp } func (this *Hero) PushHeroProperty(session comm.IUserSession, heros []*pb.DBHero) (err error) { err = session.SendMsg(string(this.GetType()), "change", &pb.HeroChangePush{List: heros}) return }