package hero import ( "go_dreamfactory/comm" "go_dreamfactory/pb" "go_dreamfactory/utils" "google.golang.org/protobuf/proto" ) //参数校验 func (this *apiComp) StrengthenUplvCheck(session comm.IUserSession, req *pb.HeroStrengthenUplvReq) (code pb.ErrorCode) { if req.HeroObjID == "" || len(req.ExpCards) == 0 { code = pb.ErrorCode_ReqParameterError return } for _, v := range req.ExpCards { if v.Value <= 0 || v.Key == "" { code = pb.ErrorCode_ReqParameterError return } } return } /// 英雄升级 func (this *apiComp) StrengthenUplv(session comm.IUserSession, req *pb.HeroStrengthenUplvReq) (code pb.ErrorCode, data proto.Message) { var ( curLv int32 curExp int32 // 当前英雄的经验 addExp int32 // 需要增加的经验 costGold int32 // 需要消耗的资源 _hero *pb.DBHero // 目标英雄 _costExpHero map[string]*pb.DBHero // 消耗英雄 minAddExp int32 _changeHero []*pb.DBHero // 变化的英雄 iLvUp int32 // 当前升级次数 _mapCost map[string]int32 // ) _costExpHero = make(map[string]*pb.DBHero, 0) _mapCost = make(map[string]int32, 0) for _, v := range req.ExpCards { // 数组转map _mapCost[v.Key] += v.Value } code = this.StrengthenUplvCheck(session, req) // check if code != pb.ErrorCode_Success { return } _hero, code = this.module.GetHeroByObjID(session.GetUserId(), req.HeroObjID) if code != pb.ErrorCode_Success { return } // 只有英雄卡才能升级 if _hero.CardType != comm.CardTypeHero { code = pb.ErrorCode_HeroTypeErr return } for k, v := range _mapCost { _expHero, c := this.module.GetHeroByObjID(session.GetUserId(), k) // 校验需要消耗经验卡牌的对象是否存在 code = c if code != pb.ErrorCode_Success { return } if _expHero.Block { // 锁定的卡不允许被消耗 code = pb.ErrorCode_HeroIsLock return } if _expHero.CardType != comm.CardTypeLevel { code = pb.ErrorCode_HeroTypeErr return } if v > _expHero.SameCount { // 校验数量 code = pb.ErrorCode_HeroNoEnough return } // 查询 本次消耗会获得多少经验 expConf := this.module.configure.GetHeroExp(_expHero.HeroID) if expConf != nil { addExp += expConf.Heroexp * v } costGold += expConf.Needgold * v // 需要消耗的金币 if _expHero.SameCount < v { // 消耗经验卡片数量不足 code = pb.ErrorCode_HeroNoEnough return } if minAddExp == 0 { minAddExp = expConf.Heroexp //初始化 } else if minAddExp > expConf.Heroexp { minAddExp = expConf.Heroexp // 取出最小的经验卡 } _costExpHero[k] = _expHero } // 金币消耗判断 curGold := this.module.ModuleUser.QueryAttributeValue(session.GetUserId(), comm.ResGold) if curGold < costGold { // 金币不足 code = pb.ErrorCode_GoldNoEnough return } if addExp == 0 { code = pb.ErrorCode_HeroExpTypeErr return } curLv = _hero.Lv curExp = _hero.Exp // 当前英雄的经验 maxLv := _hero.Star * comm.HeroStarLvRatio // 校验当前能不能升级 if _hero.Lv > maxLv { // 达到最大等级 code = pb.ErrorCode_HeroMaxLv return } _data := this.module.configure.GetHeroLv(curLv) if _data != nil { if maxLv == _hero.Lv && curExp >= _data.Heroexp[0].N { // 加经验之前校验是否达到最大等级 code = pb.ErrorCode_HeroMaxLv return } curExp += addExp // 先把经验加上 for { if len(_data.Heroexp) == 0 { break } if maxLv <= _hero.Lv && curExp >= _data.Heroexp[0].N { // 设置最大经验和等级 // 超过的经验值 leftExp := curExp - _data.Heroexp[0].N this.module.Debugf("经验溢出%d", leftExp) if leftExp >= minAddExp { code = pb.ErrorCode_HeroAddMaxExp return } curLv = maxLv curExp = _data.Heroexp[0].N break } if len(_data.Heroexp) == 0 || _data.Heroexp[0].N > curExp { // 经验不够升级则不能执行升级操作 break } else { // 升级操作 curExp -= _data.Heroexp[0].N curLv += 1 // 经验够了 那么等级+1 _data = this.module.configure.GetHeroLv(curLv) if _data == nil { // 等级加失败了 回到原来的等级 curLv -= 1 break } iLvUp++ } } } else { code = pb.ErrorCode_HeroNoExist return } this.module.Debugf("升级后当前等级: %d,经验: %d,需要消耗的金币: %d,增加的经验: %d", curLv, curExp, costGold, addExp) // 执行升级逻辑 newhero, code := this.module.modelHero.AddCardExp(session.GetUserId(), _hero, addExp) // 加经验 if code != pb.ErrorCode_Success { return } // 消耗金币 code = this.module.ModuleUser.AddAttributeValue(session, comm.ResGold, -costGold, true) if code != pb.ErrorCode_Success { // 金币不足 code = pb.ErrorCode_GoldNoEnough return } // 删除经验卡 for k, v := range _mapCost { err1 := this.module.modelHero.consumeHeroCard(session.GetUserId(), _costExpHero[k], v) if err1 != nil { code = pb.ErrorCode_HeroNoEnough this.module.Errorf("delete err failed err:%T!", err1) this.module.ModuleUser.AddAttributeValue(session, comm.ResGold, costGold, true) // 回退金币 return } _changeHero = append(_changeHero, _costExpHero[k]) } this.module.modelHero.ChangeHeroProperty(session, _hero) // 重新计算属性值 _changeHero = append(_changeHero, _hero) // 升级后的英雄 hero id 不变 if newhero != nil { _changeHero = append(_changeHero, newhero) // 原来的英雄 只是数量变化了 } session.SendMsg(string(this.module.GetType()), "change", &pb.HeroChangePush{List: _changeHero}) session.SendMsg(string(this.module.GetType()), StrengthenUplv, &pb.HeroStrengthenUplvResp{Hero: _hero}) if iLvUp > 0 { // 升级了 统计任务 this.module.ModuleTask.SendToTask(session, comm.TaskTypeUpHeroLevel, &pb.TaskParam{Second: iLvUp}) this.module.ModuleRtask.SendToRtask(session, comm.Rtype4, utils.ToInt32(_hero.HeroID), _hero.Lv) this.module.ModuleRtask.SendToRtask(session, comm.Rtype23, 1, _hero.Star, _hero.Lv) this.module.ModuleRtask.SendToRtask(session, comm.Rtype24, iLvUp) this.module.ModuleRtask.SendToRtask(session, comm.Rtype29, 1, _hero.Lv, utils.ToInt32(_hero.HeroID)) cfg := this.module.configure.GetHero(_hero.HeroID) if cfg != nil { this.module.ModuleRtask.SendToRtask(session, comm.Rtype32, 1, cfg.Color, _hero.Lv) this.module.ModuleRtask.SendToRtask(session, comm.Rtype36, 1, cfg.Color, cfg.Job, cfg.Race, _hero.JuexingLv) //xx英雄满级、共鸣、觉醒至最高状态 nextAwaken := this.module.configure.GetHeroAwakenConfig(_hero.HeroID, _hero.JuexingLv+1) if nextAwaken == nil { // 达到满级觉醒 resonConfig := this.module.configure.GetHeroResonanceConfig(_hero.HeroID, _hero.Star+1) if resonConfig == nil { // 满星 if _hero.Lv == _hero.Star*comm.HeroStarLvRatio { this.module.ModuleRtask.SendToRtask(session, comm.Rtype37, 1, cfg.Color) this.module.ModuleRtask.SendToRtask(session, comm.Rtype38, 1) } } } } this.module.ModuleRtask.SendToRtask(session, comm.Rtype33, 1, 1, _hero.Lv) } return }