package hero import ( "crypto/rand" "errors" "go_dreamfactory/comm" "go_dreamfactory/lego/core" "go_dreamfactory/modules" "go_dreamfactory/pb" cfg "go_dreamfactory/sys/configure/structs" "go_dreamfactory/sys/db" "go_dreamfactory/utils" "math" "math/big" "reflect" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/x/bsonx" ) type ModelHero struct { modules.MCompModel moduleHero *Hero } func (this *ModelHero) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { this.TableName = comm.TableHero err = this.MCompModel.Init(service, module, comp, options) this.moduleHero = module.(*Hero) // 通过uid创建索引 this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}}, }) return } //初始化英雄 func (this *ModelHero) InitHero(uid string, heroCfgId string) *pb.DBHero { heroCfg := this.moduleHero.configure.GetHeroConfig(heroCfgId) if heroCfg == nil { this.moduleHero.Errorf("%v hero not found from config %v", heroCfgId) return nil } objId := primitive.NewObjectID().Hex() newHero := &pb.DBHero{ Id: objId, Uid: uid, HeroID: heroCfg.Hid, Star: heroCfg.Star, //初始星级 Lv: 1, //初始等级 IsOverlying: true, //是否允许叠加, Block: false, //未锁定 CardType: heroCfg.Type, //卡片类型 Skins: []int32{}, EquipID: make([]string, 8), //初始装备 SameCount: 1, //默认叠加数量 AddProperty: make(map[string]int32), Energy: make(map[string]int32), Property: make(map[string]int32), EnergyProperty: make(map[string]int32), JuexProperty: make(map[string]int32), TalentProperty: make(map[string]int32), HoroscopeProperty: make(map[string]int32), } this.PropertyCompute(newHero) this.initHeroSkill(newHero) return newHero } //初始化英雄技能 func (this *ModelHero) initHeroSkill(hero *pb.DBHero) []*pb.SkillData { heroCfg := this.moduleHero.configure.GetHeroConfig(hero.HeroID) if heroCfg != nil { if heroCfg.Skill != 0 { hero.CaptainSkill = heroCfg.Skill } skills := []*pb.SkillData{} if heroCfg.Skill1 != 0 { skills = append(skills, &pb.SkillData{SkillID: heroCfg.Skill1, SkillLv: 1}) } if heroCfg.Skill2 != 0 { skills = append(skills, &pb.SkillData{SkillID: heroCfg.Skill2, SkillLv: 1}) } if heroCfg.Skill3 != 0 { skills = append(skills, &pb.SkillData{SkillID: heroCfg.Skill3, SkillLv: 1}) } hero.NormalSkill = skills } return nil } //创建一个指定的英雄 func (this *ModelHero) createOneHero(uid string, heroCfgId string) (hero *pb.DBHero, err error) { hero = this.InitHero(uid, heroCfgId) if hero != nil { if err = this.AddList(uid, hero.Id, hero); err != nil { this.moduleHero.Errorf("%v", err) return } } return } // 拷贝一个指针对象 func (this *ModelHero) copyPoint(m *pb.DBHero) *pb.DBHero { vt := reflect.TypeOf(m).Elem() newoby := reflect.New(vt) newoby.Elem().Set(reflect.ValueOf(m).Elem()) return newoby.Interface().(*pb.DBHero) } // 克隆一个英雄 // 调用此方法前注意有使用map 切片等指针类型数据是 克隆完成后自行初始化这个指针对象 func (this *ModelHero) CloneNewHero(hero *pb.DBHero) (newHero *pb.DBHero) { newHero = new(pb.DBHero) *newHero = *hero //*this.copyPoint(hero) newHero.Id = primitive.NewObjectID().Hex() this.AddList(newHero.Uid, newHero.Id, newHero) return } //初始化可叠加的英雄 func (this *ModelHero) initHeroOverlying(uid string, heroCfgId string, count int32) (hero *pb.DBHero, err error) { var ( model *db.DBModel ) hero = this.InitHero(uid, heroCfgId) if hero != nil { hero.SameCount = count if this.moduleHero.IsCross() { if model, err = this.moduleHero.GetDBModuleByUid(uid, this.TableName, this.Expired); err != nil { this.moduleHero.Errorln(err) } else { if err = model.AddList(uid, hero.Id, hero); err != nil { this.moduleHero.Errorf("err:%v", err) } } } else { if err = this.AddList(uid, hero.Id, hero); err != nil { this.moduleHero.Errorln(err) } } } return } // 该方法适用创建初始英雄 叠加英雄 count叠加数量 func (this *ModelHero) createHeroOverlying(uid string, heroCfgId string, count int32) (hero *pb.DBHero, err error) { heros := make([]*pb.DBHero, 0) if this.moduleHero.IsCross() { if dbModel, err := this.moduleHero.GetDBModuleByUid(uid, this.TableName, this.Expired); err != nil { this.moduleHero.Errorln(err) } else { if err = dbModel.GetList(uid, &heros); err != nil { this.moduleHero.Errorf("err:%v", err) } } } else { if err = this.GetList(uid, &heros); err != nil { this.moduleHero.Errorf("err:%v", err) } } if len(heros) >= 0 { for _, h := range heros { if h.HeroID == heroCfgId && h.IsOverlying { h.SameCount += count data := map[string]interface{}{ "sameCount": h.SameCount, //叠加数 } hero = h if this.moduleHero.IsCross() { if model, err := this.moduleHero.GetDBModuleByUid(uid, this.TableName, this.Expired); err != nil { this.moduleHero.Errorln(err) } else { if err := model.ChangeList(uid, h.Id, data); err != nil { return nil, err } } } else { if err := this.ChangeList(uid, h.Id, data); err != nil { return nil, err } } return } } } return this.initHeroOverlying(uid, heroCfgId, count) } //获取一个英雄(参数唯一objID) func (this *ModelHero) getOneHero(uid, heroId string) *pb.DBHero { hero := &pb.DBHero{} err := this.GetListObj(uid, heroId, hero) if err != nil { return nil } return hero } //消耗英雄卡 func (this *ModelHero) consumeHeroCard(uid string, hero *pb.DBHero, count int32) (err error) { if count == 0 { return } if hero == nil { err = errors.New("hero no exist") return } if hero.SameCount < count { err = errors.New("hero card no enough") return } hero.SameCount -= count // 数量-1 if hero.SameCount == 0 { if err := this.DelListlds(uid, hero.Id); err != nil { this.moduleHero.Errorf("%v", err) } } else { update := map[string]interface{}{ "sameCount": hero.SameCount, } err = this.ChangeList(uid, hero.Id, update) } this.moduleHero.Debugf("删除%d张卡牌uid:%s,卡牌ID:%s", count, uid, hero.Id) return } //获取玩家的英雄列表 func (this *ModelHero) getHeroList(uid string) []*pb.DBHero { heroes := make([]*pb.DBHero, 0) err := this.GetList(uid, &heroes) if err != nil { return nil } return heroes } // 觉醒 func (this *ModelHero) setJuexingProperty(hero *pb.DBHero, key string, value int32) { switch key { case comm.Hp: hero.JuexProperty[comm.Hp] += value case comm.Def: hero.JuexProperty[comm.Def] += value case comm.Atk: hero.JuexProperty[comm.Atk] += value case comm.Speed: hero.JuexProperty[comm.Speed] += value case comm.ResonanceHpPro: hero.JuexProperty[comm.Hp] += int32(math.Floor((float64(value) / 1000) * float64(hero.Property[comm.Hp]))) case comm.ResonanceAtkPro: hero.JuexProperty[comm.Atk] += int32(math.Floor((float64(value) / 1000) * float64(hero.Property[comm.Atk]))) case comm.ResonanceDefPro: hero.JuexProperty[comm.Def] += int32(math.Floor((float64(value) / 1000) * float64(hero.Property[comm.Def]))) } } // 设置共鸣能量点数属性 func (this *ModelHero) setEnergyProperty(hero *pb.DBHero, star int32) { resonConfig := this.moduleHero.configure.GetHeroResonanceConfig(hero.HeroID, star) if resonConfig == nil { return } EnergyProperty := make(map[string]int32) //副属性 for k, v := range hero.Energy { if k == comm.ResonanceHpPro { EnergyProperty[comm.Hp] += int32(math.Floor(float64(resonConfig.Hppro*v) / 1000 * float64(hero.Property[comm.Hp]))) } else if k == comm.ResonanceAtkPro { EnergyProperty[comm.Atk] += int32(math.Floor(float64(resonConfig.Atkpro*v) / 1000 * float64(hero.Property[comm.Atk]))) } else if k == comm.ResonanceDefPro { EnergyProperty[comm.Def] += int32(math.Floor(float64(resonConfig.Defpro*v) / 1000 * float64(hero.Property[comm.Def]))) } } _heroMap := make(map[string]interface{}, 0) _heroMap["enegryProperty"] = EnergyProperty if err := this.ChangeList(hero.Uid, hero.Id, _heroMap); err != nil { this.moduleHero.Errorf("mergeenegryProperty err %v", err) } } // 设置装备属性 func (this *ModelHero) setEquipProperty(hero *pb.DBHero, equip []*pb.DB_Equipment) { addProperty := make(map[string]int32) //副属性 equipSkill := make([]*pb.SkillData, 0) for i, v := range equip { if v == nil { continue } hero.EquipID[i] = v.Id addProperty[v.MainEntry.AttrName] += v.MainEntry.Value //主属性 for _, v := range v.AdverbEntry { addProperty[v.AttrName] += v.Value + v.EnchValue //附加属性 } for k, v := range addProperty { switch k { case comm.AtkPro: addProperty[comm.Atk] += int32(math.Floor((float64(v) / 1000) * float64(hero.Property[comm.Atk]))) addProperty[comm.AtkPro] = 0 case comm.DefPro: addProperty[comm.Def] += int32(math.Floor((float64(v) / 1000) * float64(hero.Property[comm.Def]))) addProperty[comm.DefPro] = 0 case comm.HpPro: addProperty[comm.Hp] += int32(math.Floor((float64(v) / 1000) * float64(hero.Property[comm.Hp]))) addProperty[comm.HpPro] = 0 } } if v.Adverbskill != nil { for _, v := range v.Adverbskill { equipSkill = append(equipSkill, &pb.SkillData{ SkillID: v.SkillId, SkillLv: v.Lv, }) } } } this.mergeAddProperty(hero.Uid, hero, addProperty, equipSkill) } //设置装备 func (this *ModelHero) setEquipment(hero *pb.DBHero) (newHero *pb.DBHero, err error) { if len(hero.EquipID) == 0 { return } var ( _suiteId int32 _equipID []string _suiteExtId int32 ) update := make(map[string]interface{}) _suiteId = hero.SuiteId _equipID = hero.EquipID _suiteExtId = hero.SuiteExtId suite1Star := hero.Suite1Star suite2Star := hero.Suite2Star suite1Lv := hero.Suite1Lv suite2Lv := hero.Suite2Lv if hero.IsOverlying && hero.SameCount > 1 { // 克隆一个新的 hero.SameCount -= 1 hero.Suite1Star = 0 hero.Suite2Star = 0 hero.Suite1Lv = 0 hero.Suite2Lv = 0 hero.SuiteId = 0 hero.SuiteExtId = 0 hero.EquipID = make([]string, 8) newHero = this.CloneNewHero(hero) hero.EquipID = make([]string, 8) hero.SameCount = 1 hero.IsOverlying = false update["isoverlying"] = false update["sameCount"] = 1 } // 修改装备属性 并更新 update["suiteId"] = _suiteId update["suiteExtId"] = _suiteExtId update["equipID"] = _equipID update["suite1Star"] = suite1Star update["suite2Star"] = suite2Star update["suite1Lv"] = suite1Lv update["suite2Lv"] = suite2Lv if err = this.ChangeList(hero.Uid, hero.Id, update); err != nil { this.moduleHero.Errorf("%v", err) return } return } //合并属性即属性值累加 (data 额外加的属性) func (this *ModelHero) mergeMainProperty(uid string, hero *pb.DBHero, data map[string]int32) (err error) { for k, v := range hero.Property { if v1, ok := data[k]; ok { v += v1 } } if err = this.ChangeList(uid, hero.Id, map[string]interface{}{ "property": hero.Property, }); err != nil { this.moduleHero.Errorf("mergeMainProperty err %v", err) } return } //合并附加属性 func (this *ModelHero) mergeAddProperty(uid string, hero *pb.DBHero, data map[string]int32, skills []*pb.SkillData) { hero.AddProperty = data if err := this.ChangeList(uid, hero.Id, map[string]interface{}{ "addProperty": data, "equipSkill": skills, }); err != nil { this.moduleHero.Errorf("mergeAddProperty err %v", err) } } func (this *ModelHero) StarAtkAddition(star int32) (addValue float32) { for i := 1; i <= int(star); i++ { starCfg := this.moduleHero.configure.GetHeroStar(int32(i)) cfg := this.moduleHero.configure.GetHeroLv(starCfg.Level) addValue += cfg.Atk * starCfg.StarupAtk / 1000.0 } return addValue } func (this *ModelHero) StarDefAddition(star int32) (addValue float32) { for i := 1; i <= int(star); i++ { starCfg := this.moduleHero.configure.GetHeroStar(int32(i)) cfg := this.moduleHero.configure.GetHeroLv(starCfg.Level) addValue += cfg.Def * starCfg.StarupDef / 1000.0 } return addValue } func (this *ModelHero) StarHpAddition(star int32) (addValue float32) { for i := 1; i <= int(star); i++ { starCfg := this.moduleHero.configure.GetHeroStar(int32(i)) cfg := this.moduleHero.configure.GetHeroLv(starCfg.Level) //this.moduleHero.Debugf("cfg.Atk= %f,starCfg.StarupHp = %f,addValue= %f", cfg.Atk, starCfg.StarupHp, addValue) addValue += cfg.Hp * starCfg.StarupHp / 1000.0 } return addValue } //属性计算 基础属性 //英雄基础属性 + 英雄等级基础属性 * 英雄成长系数 + 英雄星级对应等级属性 * 英雄品质系数 func (this *ModelHero) PropertyCompute(hero *pb.DBHero) { growCfg := this.moduleHero.configure.GetHeroLvgrow(hero.HeroID) heroCfg := this.moduleHero.configure.GetHeroConfig(hero.HeroID) lvCfg := this.moduleHero.configure.GetHeroLv(hero.Lv) starCfg := this.moduleHero.configure.GetHeroStar(hero.Star) starLvfg := this.moduleHero.configure.GetHeroLv(starCfg.Level) if growCfg == nil || heroCfg == nil || lvCfg == nil || starCfg == nil || starLvfg == nil { return } var atk = (this.StarAtkAddition(hero.Star) + lvCfg.Atk + float32(growCfg.Atk)) * (growCfg.Atkgrow / 1000.0) * 1.0 var def = (this.StarDefAddition(hero.Star) + lvCfg.Def + float32(growCfg.Def)) * (growCfg.Defgrow / 1000.0) * 1.0 var hp = (this.StarHpAddition(hero.Star) + lvCfg.Hp + float32(growCfg.Hp)) * (growCfg.Hpgrow / 1000.0) * 1.0 speed := growCfg.Speed hero.Property = map[string]int32{ comm.Hp: int32(math.Floor(float64(hp))), comm.Atk: int32(math.Floor(float64(atk))), comm.Def: int32(math.Floor(float64(def))), comm.Speed: int32(math.Floor(float64(speed))), comm.Cri: int32(growCfg.Cri), //暴击 comm.Effhit: int32(growCfg.Effhit), //效果命中 comm.Cridam: int32(growCfg.Cridam), //暴击伤害 comm.Effre: int32(growCfg.Effre), //效果抵抗 } this.resetTalentProperty(hero) } //重新计算英雄属性 func (this *ModelHero) ChangeHeroProperty(session comm.IUserSession, hero *pb.DBHero) (err error) { this.PropertyCompute(hero) //重新计算 property 的值 update := map[string]interface{}{ "property": hero.Property, "talentProperty": hero.TalentProperty, } if err = this.ChangeList(session.GetUserId(), hero.Id, update); err != nil { this.moduleHero.Errorf("ChangeHeroProperty err:%v", err) return } return } func (this *ModelHero) cleanData(uid string) { userList := this.moduleHero.GetHeroList(uid) for _, v := range userList { if err := this.DelListlds(uid, v.Id); err != nil { this.moduleHero.Errorf("cleanData err:%v", err) } } } func (this *ModelHero) AddCardExp(session comm.IUserSession, hero *pb.DBHero, exp int32) (newhero *pb.DBHero, code pb.ErrorCode) { var ( preLv int32 //加经验之前的等级 curExp int32 // 加经验之后的经验 curLv int32 // 加经验之后的等级 update map[string]interface{} // 属性变化 ) if hero == nil { code = pb.ErrorCode_HeroNoExist return } update = make(map[string]interface{}, 0) curExp = hero.Exp curLv = hero.Lv preLv = curLv var maxLv int32 // 校验等级达到上限 maxLv = hero.Star * comm.HeroStarLvRatio _data := this.moduleHero.configure.GetHeroLv(curLv) if _data != nil { var maxExp int32 maxExp = _data.Heroexp if maxLv <= curLv && curExp >= maxExp { // 加经验之前校验是否达到最大等级 code = pb.ErrorCode_HeroMaxLv return } curExp += exp // 先把经验加上 for { // 死循环判断一键升级 if _data.Heroexp == 0 { curExp = 0 break } maxExp = _data.Heroexp if maxLv <= curLv && curExp >= maxExp { // 设置最大经验和等级 curLv = maxLv curExp = maxExp break } if maxExp > curExp { // 经验不够升级则不能执行升级操作 break } else { // 升级操作 curExp -= maxExp curLv += 1 // 经验够了 那么等级+1 _data = this.moduleHero.configure.GetHeroLv(curLv) if _data == nil { // 等级加失败了 回到原来的等级 curLv -= 1 break } } } if hero.SameCount > 1 { //有堆叠的情况 hero.SameCount -= 1 newhero = this.CloneNewHero(hero) // 克隆一个新的 } this.moduleHero.Debugf("add hero exp :old lv:%d,old exp:%d,new lv:%d,new exp:%d,addexp:%d", hero.Lv, hero.Exp, curLv, curExp, exp) update["lv"] = curLv update["exp"] = curExp update["isOverlying"] = false update["sameCount"] = 1 hero.Lv = curLv hero.Exp = curExp hero.IsOverlying = false hero.SameCount = 1 if err := this.ChangeList(session.GetUserId(), hero.Id, update); err != nil { this.moduleHero.Errorf("add hero exp failed ChangeList %v", err) code = pb.ErrorCode_DBError } if curLv-preLv > 0 { // 升级了 统计任务 this.ChangeHeroProperty(session, hero) // 重新计算属性值 // 推送 this.moduleHero.ModuleRtask.SendToRtask(session, comm.Rtype113, utils.ToInt32(hero.HeroID), curLv-preLv) this.moduleHero.ModuleRtask.SendToRtask(session, comm.Rtype4, utils.ToInt32(hero.HeroID), hero.Lv) this.moduleHero.ModuleRtask.SendToRtask(session, comm.Rtype23, 1, hero.Star, hero.Lv) this.moduleHero.ModuleRtask.SendToRtask(session, comm.Rtype24, 1) this.moduleHero.ModuleRtask.SendToRtask(session, comm.Rtype29, 1, hero.Lv, utils.ToInt32(hero.HeroID)) cfg := this.moduleHero.configure.GetHeroConfig(hero.HeroID) if cfg != nil { this.moduleHero.ModuleRtask.SendToRtask(session, comm.Rtype32, 1, cfg.Color, hero.Lv) this.moduleHero.ModuleRtask.SendToRtask(session, comm.Rtype36, 1, cfg.Color, cfg.Job, cfg.Race, hero.JuexingLv) //xx英雄满级、共鸣、觉醒至最高状态 nextAwaken := this.moduleHero.configure.GetHeroAwakenConfig(hero.HeroID, hero.JuexingLv+1) if nextAwaken == nil { // 达到满级觉醒 resonConfig := this.moduleHero.configure.GetHeroResonanceConfig(hero.HeroID, cfg.Star) if resonConfig != nil && resonConfig.Maxnum == hero.ResonateNum { // 共鸣满 if hero.Lv == hero.Star*comm.HeroStarLvRatio { this.moduleHero.ModuleRtask.SendToRtask(session, comm.Rtype37, 1, cfg.Color) this.moduleHero.ModuleRtask.SendToRtask(session, comm.Rtype38, 1) } } } } this.moduleHero.ModuleRtask.SendToRtask(session, comm.Rtype33, 1, 1, hero.Lv) } } return } // 玩家离线 清除缓存 func (this *ModelHero) RemoveUserHeroInfo(session comm.IUserSession) (err error) { this.BatchDelLists(session.GetUserId()) return } func (this *ModelHero) CheckPool(drawCount int32, config *cfg.GameGlobalData) (pools string) { if config.BasePool1.S <= drawCount && config.BasePool1.E >= drawCount { return config.BasePool1.P } else if config.BasePool2.S <= drawCount && config.BasePool2.E >= drawCount { return config.BasePool2.P } else if config.BasePool3.S <= drawCount && config.BasePool3.E >= drawCount { return config.BasePool3.P } else if config.BasePool4.S <= drawCount && config.BasePool4.E >= drawCount { return config.BasePool4.P } else if config.BasePool5.S <= drawCount && config.BasePool5.E >= drawCount { return config.BasePool5.P } else if config.BasePool6.S <= drawCount && config.BasePool6.E >= drawCount { return config.BasePool6.P } return config.BasePool7.P } // 通数组里的权重随机命中 返回值为数组的下标 func (this *ModelHero) GetRandW(sz []int32) int32 { if len(sz) > 0 { var _totalW int64 // 总权重 var _tmpW int64 // 临时权重 for _, v := range sz { _totalW += int64(v) } // 随机权重 n, _ := rand.Int(rand.Reader, big.NewInt(_totalW)) for i, v := range sz { _tmpW += int64(v) if n.Int64() < _tmpW { return int32(i) } } } return 0 } // 通过卡池的权重 获取英雄 func (this *ModelHero) GetRandHeroIdBypool(sz []int32) int32 { if len(sz) > 0 { var _totalW int64 // 总权重 var _tmpW int64 // 临时权重 for _, v := range sz { _totalW += int64(v) } // 随机权重 n, _ := rand.Int(rand.Reader, big.NewInt(_totalW)) for i, v := range sz { _tmpW += int64(v) if n.Int64() < _tmpW { // 种族保底卡池命中 return int32(i) } } } return 0 } func (this *ModelHero) InitTempHero(heroCfgId string, star, lv int32) *pb.DBHero { heroCfg := this.moduleHero.configure.GetHeroConfig(heroCfgId) if heroCfg == nil { this.moduleHero.Errorf("%v hero not found from config %v", heroCfgId) return nil } newHero := &pb.DBHero{ HeroID: heroCfg.Hid, Star: star, //初始星级 Lv: lv, //初始等级 IsOverlying: true, //是否允许叠加, Block: false, //未锁定 CardType: heroCfg.Type, //卡片类型 Skins: []int32{}, EquipID: make([]string, 8), //初始装备 SameCount: 1, //默认叠加数量 AddProperty: make(map[string]int32), Energy: make(map[string]int32), Property: make(map[string]int32), EnergyProperty: make(map[string]int32), JuexProperty: make(map[string]int32), TalentProperty: make(map[string]int32), HoroscopeProperty: make(map[string]int32), } this.PropertyCompute(newHero) this.initHeroSkill(newHero) return newHero } //设置天赋属性 func (this *ModelHero) setTalentProperty(hero *pb.DBHero, conf *cfg.GameTalentSkillData) { if conf == nil || hero == nil { return } if hero.TalentProperty == nil { hero.TalentProperty = make(map[string]int32) } if conf.Hp != -1 { if _, ok := hero.TalentProperty[comm.Hp]; ok { hero.TalentProperty[comm.Hp] += int32(math.Floor((float64(conf.Hp) / 1000) * float64(hero.Property[comm.Hp]))) } else { hero.TalentProperty[comm.Hp] = int32(math.Floor((float64(conf.Hp) / 1000) * float64(hero.Property[comm.Hp]))) } } if conf.Atk != -1 { if _, ok := hero.TalentProperty[comm.Atk]; ok { hero.TalentProperty[comm.Atk] += int32(math.Floor((float64(conf.Atk) / 1000) * float64(hero.Property[comm.Atk]))) } else { hero.TalentProperty[comm.Atk] = int32(math.Floor((float64(conf.Atk) / 1000) * float64(hero.Property[comm.Atk]))) } } if conf.Def != -1 { if _, ok := hero.TalentProperty[comm.Def]; ok { hero.TalentProperty[comm.Def] += int32(math.Floor((float64(conf.Def) / 1000) * float64(hero.Property[comm.Def]))) } else { hero.TalentProperty[comm.Def] = int32(math.Floor((float64(conf.Def) / 1000) * float64(hero.Property[comm.Def]))) } } if conf.Cri != -1 { if _, ok := hero.TalentProperty[comm.Cri]; ok { hero.TalentProperty[comm.Cri] += int32(math.Floor((float64(conf.Cri) / 1000) * float64(hero.Property[comm.Cri]))) } else { hero.TalentProperty[comm.Cri] = int32(math.Floor((float64(conf.Cri) / 1000) * float64(hero.Property[comm.Cri]))) } } if conf.Speed != -1 { if _, ok := hero.TalentProperty[comm.Speed]; ok { hero.TalentProperty[comm.Speed] += int32(math.Floor((float64(conf.Speed) / 1000) * float64(hero.Property[comm.Speed]))) } else { hero.TalentProperty[comm.Speed] = int32(math.Floor((float64(conf.Speed) / 1000) * float64(hero.Property[comm.Speed]))) } } _heroMap := make(map[string]interface{}, 0) _heroMap["talentProperty"] = hero.TalentProperty if err := this.ChangeList(hero.Uid, hero.Id, _heroMap); err != nil { this.moduleHero.Errorf("mergeenegryProperty err %v", err) } } // 重置天赋属性 func (this *ModelHero) cleanTalentProperty(hero *pb.DBHero) { if hero == nil { return } hero.TalentProperty = map[string]int32{} _heroMap := make(map[string]interface{}, 0) _heroMap["talentProperty"] = hero.TalentProperty if err := this.ChangeList(hero.Uid, hero.Id, _heroMap); err != nil { this.moduleHero.Errorf("mergeenegryProperty err %v", err) } } // 重新计算天赋加成 attr hp atk def cri speed func (this *ModelHero) resetTalentProperty(hero *pb.DBHero) { var ( attr [5]int32 ) if hero == nil { return } if rst, err := this.moduleHero.modelTalent.GetHerotalent(hero.Uid); err != nil { for _, v := range rst { if v.HeroId == hero.HeroID { // 找到对应的英雄 for k := range v.Talent { if conf := this.moduleHero.configure.GetHeroTalentSkill(k); conf != nil { //获取天赋树 if conf.Hp != -1 { attr[0] += conf.Hp } if conf.Atk != -1 { attr[1] += conf.Atk } if conf.Def != -1 { attr[2] += conf.Def } if conf.Cri != -1 { attr[3] += conf.Cri } if conf.Speed != -1 { attr[4] += conf.Speed } } } break } } } hero.TalentProperty = make(map[string]int32) for k, v := range attr { if v != 0 { switch k { case 0: hero.TalentProperty[comm.Hp] = int32(math.Floor((float64(v) / 1000) * float64(hero.Property[comm.Hp]))) case 1: hero.TalentProperty[comm.Atk] = int32(math.Floor((float64(v) / 1000) * float64(hero.Property[comm.Atk]))) case 2: hero.TalentProperty[comm.Def] = int32(math.Floor((float64(v) / 1000) * float64(hero.Property[comm.Def]))) case 3: hero.TalentProperty[comm.Cri] = int32(math.Floor((float64(v) / 1000) * float64(hero.Property[comm.Cri]))) case 4: hero.TalentProperty[comm.Speed] = int32(math.Floor((float64(v) / 1000) * float64(hero.Property[comm.Speed]))) } } } // _heroMap := make(map[string]interface{}, 0) // _heroMap["talentProperty"] = hero.TalentProperty // if err := this.ChangeList(hero.Uid, hero.Id, _heroMap); err != nil { // this.moduleHero.Errorf("mergeenegryProperty err %v", err) // } }