204 lines
6.2 KiB
Go
204 lines
6.2 KiB
Go
package hero
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/pb"
|
|
"go_dreamfactory/utils"
|
|
"math/big"
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
//参数校验
|
|
func (this *apiComp) StrengthenUpSkillCheck(session comm.IUserSession, req *pb.HeroStrengthenUpSkillReq) (code pb.ErrorCode) {
|
|
if req.HeroObjID == "" || len(req.CostCardObj) == 0 {
|
|
code = pb.ErrorCode_ReqParameterError
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
/// 英雄技能升级
|
|
func (this *apiComp) StrengthenUpSkill(session comm.IUserSession, req *pb.HeroStrengthenUpSkillReq) (code pb.ErrorCode, data proto.Message) {
|
|
var (
|
|
probability map[int32]int32 // 即将升级技能的权重
|
|
upSkillPos int32 // 升级的技能位置
|
|
totalprobability int32 // 所有技能总权重
|
|
|
|
_hero *pb.DBHero // 操作的英雄
|
|
ChangeList []*pb.DBHero // 推送 改变的英雄
|
|
mapCostHero map[string]int32 // 消耗的技能卡
|
|
mapCostObj map[string]*pb.DBHero // 消耗的技能卡对象
|
|
costGold int32 // 金币消耗
|
|
lvUpCount int32 // 技能升级的次数
|
|
)
|
|
mapCostHero = make(map[string]int32, 0)
|
|
mapCostObj = make(map[string]*pb.DBHero, 0)
|
|
ChangeList = make([]*pb.DBHero, 0)
|
|
|
|
code = this.StrengthenUpSkillCheck(session, req) // check
|
|
if code != pb.ErrorCode_Success {
|
|
return
|
|
}
|
|
_hero, code = this.module.GetHeroByObjID(session.GetUserId(), req.HeroObjID) // 查询目标卡是否存在
|
|
if code != pb.ErrorCode_Success {
|
|
return
|
|
}
|
|
// 查询配置表 找出原始品质
|
|
heroCfg := this.module.configure.GetHero(_hero.HeroID)
|
|
if heroCfg == nil {
|
|
code = pb.ErrorCode_HeroNoExist
|
|
return
|
|
}
|
|
|
|
for _, v := range req.CostCardObj { // 数组转 map
|
|
mapCostHero[v]++
|
|
}
|
|
for k, v := range mapCostHero {
|
|
costHero, c := this.module.GetHeroByObjID(session.GetUserId(), k) // 查询消耗卡是否存在
|
|
if c != pb.ErrorCode_Success {
|
|
code = c
|
|
return
|
|
}
|
|
if costHero.Block { // 锁定的卡不允许被消耗
|
|
code = pb.ErrorCode_HeroIsLock
|
|
return
|
|
}
|
|
if costHero.SameCount < v { // 数量校验
|
|
code = pb.ErrorCode_HeroNoEnough
|
|
return
|
|
}
|
|
tmp := this.module.configure.GetHero(costHero.HeroID) // 星级校验
|
|
if tmp.Color != heroCfg.Color {
|
|
code = pb.ErrorCode_HeroColorErr
|
|
return
|
|
}
|
|
if tmp.Type != comm.CardTypeSkill { // 查看是不是升级卡
|
|
code = pb.ErrorCode_HeroTypeErr
|
|
return
|
|
}
|
|
expConf := this.module.configure.GetHeroExp(costHero.HeroID) // 消耗多少金币
|
|
if expConf != nil {
|
|
costGold += expConf.Needgold * v
|
|
lvUpCount += expConf.Skilllevelup * v
|
|
} else {
|
|
lvUpCount += v // 计算技能升级次数
|
|
}
|
|
|
|
mapCostObj[k] = costHero
|
|
}
|
|
// 检查金币消耗
|
|
curGold := this.module.ModuleUser.QueryAttributeValue(session.GetUserId(), comm.ResGold)
|
|
if curGold < costGold { // 金币不足
|
|
code = pb.ErrorCode_GoldNoEnough
|
|
return
|
|
}
|
|
|
|
tmpUpSkillID := make(map[int32]bool, 0)
|
|
for i := 0; i < int(lvUpCount); i++ { // 升级技能
|
|
probability = make(map[int32]int32, 0)
|
|
for index, skill := range _hero.NormalSkill {
|
|
skillMaxLv := this.module.configure.GetHeroSkillMaxLvConfig(uint32(skill.SkillID))
|
|
if skill.SkillLv < skillMaxLv { // 找到没有满级的技能id
|
|
tmpUpSkillID[int32(index)] = true
|
|
skillData := this.module.configure.GetHeroSkillUpConfig(skill.SkillID)
|
|
if skillData == nil {
|
|
code = pb.ErrorCode_ConfigNoFound
|
|
return
|
|
}
|
|
|
|
probability[skill.SkillID] = skillData.Probability[skill.SkillLv] // 获取权重
|
|
}
|
|
}
|
|
if len(tmpUpSkillID) == 0 {
|
|
code = pb.ErrorCode_HeroMaxSkillLv
|
|
return
|
|
}
|
|
|
|
totalprobability = 0
|
|
// 根据权重升级对应的技能
|
|
for _, v := range probability {
|
|
totalprobability += v
|
|
}
|
|
if totalprobability == 0 {
|
|
code = pb.ErrorCode_HeroMaxLv // 升满了
|
|
return
|
|
}
|
|
n, _ := rand.Int(rand.Reader, big.NewInt(int64(totalprobability)))
|
|
tmp := 0
|
|
for k, v := range probability {
|
|
tmp += int(v)
|
|
if int32(n.Int64()) < v { // 找到了
|
|
upSkillPos = k
|
|
break
|
|
}
|
|
}
|
|
for index, skill := range _hero.NormalSkill {
|
|
if int32(index) == upSkillPos { // 找到指定位置技能并升级
|
|
skill.SkillLv += 1
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
code = this.module.ModuleUser.AddAttributeValue(session, comm.ResGold, -costGold, true)
|
|
if code != pb.ErrorCode_Success { // 金币不足
|
|
code = pb.ErrorCode_GoldNoEnough
|
|
return
|
|
}
|
|
|
|
for k, v := range mapCostObj {
|
|
code = this.module.DelCard(session.GetUserId(), v, mapCostHero[k])
|
|
if code != pb.ErrorCode_Success {
|
|
code = this.module.ModuleUser.AddAttributeValue(session, comm.ResGold, costGold, true)
|
|
return
|
|
}
|
|
ChangeList = append(ChangeList, v)
|
|
}
|
|
// 堆叠情况
|
|
if _hero.SameCount > 1 {
|
|
_hero.SameCount -= 1
|
|
newHero := this.module.modelHero.CloneNewHero(_hero)
|
|
ChangeList = append(ChangeList, newHero)
|
|
}
|
|
_heroMap := map[string]interface{}{
|
|
"normalSkill": _hero.NormalSkill,
|
|
"isOverlying": false,
|
|
"sameCount": 1,
|
|
}
|
|
_hero.SameCount = 1
|
|
err1 := this.module.modelHero.ChangeList(session.GetUserId(), req.HeroObjID, _heroMap) // 修改英雄信息
|
|
if err1 != nil {
|
|
this.module.Errorf("update hero skill failed:%v", err1)
|
|
code = pb.ErrorCode_DBError
|
|
return
|
|
}
|
|
this.module.modelHero.ChangeHeroProperty(session, _hero) // 推送属性变化
|
|
ChangeList = append(ChangeList, _hero)
|
|
session.SendMsg(string(this.module.GetType()), "change", &pb.HeroChangePush{List: ChangeList})
|
|
session.SendMsg(string(this.module.GetType()), StrengthenUpSkill, &pb.HeroStrengthenUpSkillResp{Hero: _hero})
|
|
|
|
this.module.ModuleRtask.SendToRtask(session, comm.Rtype52, utils.ToInt32(_hero.HeroID), 1)
|
|
this.module.ModuleRtask.SendToRtask(session, comm.Rtype53, 1)
|
|
// 检查是不是满级技能
|
|
maxLv := true
|
|
for _, skill := range _hero.NormalSkill {
|
|
skillMaxLv := this.module.configure.GetHeroSkillMaxLvConfig(uint32(skill.SkillID))
|
|
if skill.SkillLv < skillMaxLv { // 找到没有满级的技能id
|
|
maxLv = false
|
|
}
|
|
}
|
|
if maxLv {
|
|
this.module.ModuleRtask.SendToRtask(session, comm.Rtype54, 1)
|
|
this.module.ModuleRtask.SendToRtask(session, comm.Rtype57, 1)
|
|
}
|
|
cfg := this.module.configure.GetHero(_hero.HeroID)
|
|
if cfg != nil {
|
|
this.module.ModuleRtask.SendToRtask(session, comm.Rtype55, cfg.Color, 1)
|
|
this.module.ModuleRtask.SendToRtask(session, comm.Rtype56, 1, 1, cfg.Job)
|
|
}
|
|
return
|
|
}
|