package hero import ( "fmt" "go_dreamfactory/comm" "go_dreamfactory/lego/core" "go_dreamfactory/lego/sys/log" "go_dreamfactory/modules" "go_dreamfactory/pb" "math" mengine "github.com/dengsgo/math-engine/engine" "go.mongodb.org/mongo-driver/bson/primitive" ) 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) { err = this.MCompModel.Init(service, module, comp, options) this.moduleHero = module.(*Hero) this.TableName = "hero" return } //初始化英雄 func (this *ModelHero) initHero(uid string, heroCfgId int32) *pb.DBHero { heroCfg := this.moduleHero.configure.GetHero(heroCfgId) if heroCfg == nil { log.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, 6), //初始装备 SameCount: 1, //默认叠加数量 AddProperty: make(map[string]int32), Energy: make(map[int32]int32), Property: make(map[string]int32), } this.initHeroSkill(newHero) return newHero } //初始化英雄技能 func (this *ModelHero) initHeroSkill(hero *pb.DBHero) []*pb.SkillData { heroCfg := this.moduleHero.configure.GetHero(hero.HeroID) if heroCfg != nil { skills := []*pb.SkillData{{ SkillID: heroCfg.Skill1, SkillLv: 1, }, { SkillID: heroCfg.Skill2, SkillLv: 1, }, { SkillID: heroCfg.Skill3, SkillLv: 1, }} hero.NormalSkill = skills hero.CaptainSkill = heroCfg.Skill } return nil } //创建一个指定的英雄 func (this *ModelHero) createOneHero(uid string, heroCfgId int32) (err error) { hero := this.initHero(uid, heroCfgId) if hero != nil { if err = this.moduleHero.modelHero.AddList(uid, hero.Id, hero); err != nil { log.Errorf("%v", err) return } } return nil } //创建多个指定的英雄 heroCfgIds可填入多个英雄ID func (this *ModelHero) createMultiHero(uid string, heroCfgIds ...int32) error { heroes, err := this.moduleHero.modelHero.getHeroList(uid) if err != nil { return err } if len(heroes) == 0 { for _, v := range heroCfgIds { if err := this.createOneHero(uid, v); err != nil { return err } } } else { findHero := func(heroId int32) (*pb.DBHero, bool) { for _, h := range heroes { if h.HeroID == heroId { return h, true } } return nil, false } for _, v := range heroCfgIds { if h, ok := findHero(v); ok { h.SameCount++ data := map[string]interface{}{ "sameCount": h.SameCount, //叠加数 } if err := this.modifyHeroData(uid, h.Id, data); err != nil { return err } } else { if err := this.createOneHero(uid, v); err != nil { return err } } } } return nil } //获取一个英雄 func (this *ModelHero) getOneHero(uid, heroId string) *pb.DBHero { hero := &pb.DBHero{} err := this.moduleHero.modelHero.GetListObj(uid, heroId, hero) if err != nil { return nil } return hero } //消耗一张英雄卡 func (this *ModelHero) consumeOneHeroCard(uid, heroId string, count int32) (err error) { for i := 0; i < int(count); i++ { if err := this.moduleHero.modelHero.DelListlds(uid, heroId); err != nil { log.Errorf("%v", err) break } } return } //更新英雄数据 func (this *ModelHero) modifyHeroData(uid, heroId string, data map[string]interface{}) error { return this.moduleHero.modelHero.ChangeList(uid, heroId, data) } //获取玩家的英雄列表 func (this *ModelHero) getHeroList(uid string) ([]*pb.DBHero, error) { heroes := make([]*pb.DBHero, 0) err := this.GetList(uid, &heroes) if err != nil { return nil, err } return heroes, nil } //更新装备 func (this *ModelHero) setEquipment(uid, heroId string, equipIds []string) error { update := map[string]interface{}{ "equipID": equipIds, } return this.moduleHero.modelHero.modifyHeroData(uid, heroId, update) } //合并属性即属性值累加 func (this *ModelHero) mergeMainProperty(uid, heroId string, data map[string]int32) { hero := this.getOneHero(uid, heroId) if hero == nil { return } hero.Property[comm.Hp] += data[comm.Hp] hero.Property[comm.Atk] += data[comm.Atk] hero.Property[comm.Def] += data[comm.Def] update := map[string]interface{}{ comm.Hp: hero.Property[comm.Hp], comm.Atk: hero.Property[comm.Atk], comm.Def: hero.Property[comm.Def], } if err := this.modifyHeroData(uid, heroId, update); err != nil { log.Errorf("mergeMainProperty err %v", err) } } //合并附加属性 func (this *ModelHero) mergeAddProperty(uid, heroId string, data map[string]int32) { hero := this.getOneHero(uid, heroId) if hero == nil { return } hero.AddProperty[comm.HpPro] += data[comm.HpPro] hero.AddProperty[comm.AtkPro] += data[comm.AtkPro] hero.AddProperty[comm.DefPro] += data[comm.DefPro] update := map[string]interface{}{ comm.HpPro: hero.AddProperty[comm.HpPro], comm.AtkPro: hero.AddProperty[comm.AtkPro], comm.DefPro: hero.AddProperty[comm.DefPro], } if err := this.modifyHeroData(uid, heroId, update); err != nil { log.Errorf("mergeAddProperty err %v", err) } } //属性计算 - 暂时放在modelHero里实现 //英雄基础属性 + 英雄等级基础属性 * 英雄成长系数 + 英雄星级对应等级属性 * 英雄品质系数 func (this *ModelHero) PropertyCompute(uid, heroId string) map[string]int32 { hero := this.getOneHero(uid, heroId) if hero == nil { return nil } //英雄等级基础属性levelup heroLvCfg := this.moduleHero.configure.GetHeroLv(hero.Lv) if heroLvCfg == nil { return nil } //英雄基础配置 newhero heroCfg := this.moduleHero.configure.GetHero(hero.HeroID) if heroCfg == nil { return nil } //品质系数 stargrowCfg := this.moduleHero.configure.GetHeroStar(heroCfg.Star) if stargrowCfg == nil { return nil } //英雄星级对应等级属性 heroStarCfg := this.moduleHero.configure.GetHeroLv(stargrowCfg.Level) if heroStarCfg == nil { return nil } //成长系数 lvGrow := this.moduleHero.configure.GetHeroLvgrow(hero.HeroID) if lvGrow == nil { return nil } curHp := hero.Property[comm.Hp] exprHp := fmt.Sprintf("%v + %v * %v/1000 + %v * %v", (curHp + lvGrow.Hp), heroLvCfg.Hp, lvGrow.Hpgrow, heroStarCfg.Hp, stargrowCfg.StarupHp) hp, _ := mengine.ParseAndExec(exprHp) curAtk := hero.Property[comm.Atk] exprAtk := fmt.Sprintf("%v +%v * %v/1000 + %v * %v", (curAtk + lvGrow.Atk), heroLvCfg.Atk, lvGrow.Atkgrow, heroStarCfg.Atk, stargrowCfg.StarupAtk) atk, _ := mengine.ParseAndExec(exprAtk) curDef := hero.Property[comm.Def] exprDef := fmt.Sprintf("%v +%v * %v/1000 + %v * %v", (curDef + lvGrow.Def), heroLvCfg.Def, lvGrow.Defgrow, heroStarCfg.Def, stargrowCfg.StarupDef) def, _ := mengine.ParseAndExec(exprDef) return map[string]int32{ comm.Hp: int32(math.Floor(hp)), comm.Atk: int32(math.Floor(atk)), comm.Def: int32(math.Floor(def)), } } //推送用户指定英雄属性 func (this *ModelHero) PushHeroProperty(session comm.IUserSession, heroId string) (err error) { m := this.PropertyCompute(session.GetUserId(), heroId) update := map[string]interface{}{ "property": m, } if err = this.ChangeList(session.GetUserId(), heroId, update); err != nil { return } return session.SendMsg("push", "property", &pb.HeroProperty{Property: m}) } // 英雄升星 func (this *ModelHero) HeroStarUp(session comm.IUserSession, hero *pb.DBHero) (code pb.ErrorCode) { _heroMap := map[string]interface{}{ "star": hero.Star, } // 保存数据 err1 := this.modifyHeroData(session.GetUserId(), hero.Id, _heroMap) if err1 != nil { code = pb.ErrorCode_DBError log.Errorf("update hero skill failed:%v", err1) } // 计算属性 data := make(map[string]int32, 0) newConfig := this.moduleHero.configure.GetHeroStar(hero.Star - 1) if newConfig == nil { code = pb.ErrorCode_ConfigurationException return } data[comm.Hp] = int32(math.Floor((1.0 + float64(newConfig.StarupHp)) * float64(hero.Property[comm.Hp]) / 100)) data[comm.Atk] = int32(math.Floor((1.0 + float64(newConfig.StarupAtk)) * float64(hero.Property[comm.Atk]) / 100)) data[comm.Def] = int32(math.Floor((1.0 + float64(newConfig.StarupDef)) * float64(hero.Property[comm.Def]) / 100)) data[comm.Speed] = int32(math.Floor((1.0 + float64(newConfig.StarupSpeed)) * float64(hero.Property[comm.Speed]) / 100)) this.mergeMainProperty(session.GetUserId(), hero.Id, data) err1 = this.PushHeroProperty(session, hero.Id) // 推送属性变化 if err1 != nil { code = pb.ErrorCode_Unknown log.Errorf("PushHeroProperty err!") } return }