322 lines
8.8 KiB
Go
322 lines
8.8 KiB
Go
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
|
|
}
|