package model import ( logutil "rocommon/util" "roserver/baseserver/model" "roserver/serverproto" ) var maxSlotNum = 0 type RoleSkill struct { SaveObject } func newRoleSkill(r *Role) *RoleSkill { roleSkill := &RoleSkill{ SaveObject: SaveObject{ role: r, }, } return roleSkill } func (this *RoleSkill) CopyData(data *serverproto.RoleSkill) { } func (this *RoleSkill) Load(msg interface{}) bool { proRole := msg.(*serverproto.Role) jobConfigId := proRole.RoleBase.RoleData.HeroData.ConfigId jobCfgData, ok := serverproto.JobCfgLoader[jobConfigId] if !ok { return false } //默认4个技能(level为0表示未解锁) maxSlotNum = len(jobCfgData.SkillIds) mainRoleSkill := this.role.GetRoleBase().RoleData().HeroData.Skill if len(mainRoleSkill.SkillList) < maxSlotNum { for i := len(mainRoleSkill.SkillList); i < maxSlotNum; i++ { defaultSkillId, err := model.Str2Num(jobCfgData.SkillIds[i]) if err != nil { return false } mainRoleSkill.SkillList = append(mainRoleSkill.SkillList, &serverproto.RoleSkillSlot{ Unlock: 0, DefaultSkillId: int32(defaultSkillId), }) } //当前职业信息 mainRoleSkill.JobSkillList = append(mainRoleSkill.JobSkillList, &serverproto.JobSkillData{ JobStage: jobCfgData.JobStage, // JobPoint: 0, }) //默认解锁的槽位 for i := 1; i <= maxSlotNum; i++ { slotId := this.getSkillSlotId(int32(i), 1) // cfgData,ok := skillSlotCfgList[slotId] cfgData, ok := serverproto.SkillSlotCfgLoader[slotId] if !ok { continue } conditionLen := len(cfgData.SCondition) // "0" 或者空 if conditionLen <= 0 || (conditionLen == 1 && cfgData.SCondition[0] == "0") { if int(int32(i)) <= maxSlotNum { //解锁默认为1级~ mainRoleSkill.SkillList[int32(i)-1].Unlock = 1 } } this.role.GetRoleBase().SetDirty(true) } } return true } func (this *RoleSkill) InitHeroSkill(heroData *serverproto.HeroData) bool { partnerCfgData, ok := serverproto.ParterCfgLoader[heroData.ConfigId] if !ok { return false } //默认4个技能(level为0表示未解锁) maxSlotNum = len(partnerCfgData.SkillIds) heroSkill := heroData.Skill if len(heroSkill.SkillList) < maxSlotNum { for i := len(heroSkill.SkillList); i < maxSlotNum; i++ { defaultSkillId, _ := model.Str2Res(partnerCfgData.SkillIds[i]) if defaultSkillId <= 0 { return false } heroSkill.SkillList = append(heroSkill.SkillList, &serverproto.RoleSkillSlot{ Unlock: 0, DefaultSkillId: int32(defaultSkillId), }) } //当前职业信息 heroSkill.JobSkillList = append(heroSkill.JobSkillList, &serverproto.JobSkillData{ JobStage: 1, //伙伴开始就是第一阶段 }) //默认解锁的槽位 for i := 1; i <= maxSlotNum; i++ { slotId := this.getSkillSlotId(int32(i), 1) // cfgData,ok := skillSlotCfgList[slotId] _, ok := serverproto.SkillSlotCfgLoader[slotId] if !ok { continue } conditionList := model.ConvertSkillSlotPartner[slotId].ConditionList // "0" 或者空 if len(conditionList) <= 0 { if int(int32(i)) <= maxSlotNum { //解锁默认为1级~ heroSkill.SkillList[int32(i)-1].Unlock = 1 this.SkillReplace(heroData.Id, int32(i), 0, false, true) } } else { //此处解锁状态需要加条件 if this.role.GetRoleBase().checkUnLockState(heroData.Id, conditionList) != serverproto.ErrorCode_ERROR_OK { continue } heroSkill.SkillList[int32(i)-1].Unlock = 1 this.SkillReplace(heroData.Id, int32(i), 0, false, true) } } } return true } func (this *RoleSkill) Save() { } func (this *RoleSkill) SlotChangeNtf(heroId int32) { heroData := this.role.roleHero.GetHero(heroId) if heroData == nil { return } ntfMsg := &serverproto.SCSkillSlotDataNtf{ HeroId: heroId, } for _, data := range heroData.Skill.SkillList { ntfMsg.SlotInfo = append(ntfMsg.SlotInfo, data) } this.role.ReplayGate(ntfMsg, true) } //技能重置次数隔天重置 func (this *RoleSkill) DailyReset(notify bool) { ntfMsg := &serverproto.SCSkillResetCountNtf{} this.role.GetRoleBase().RoleData().SkillResetCount = 0 ntfMsg.ResetCount = this.role.GetRoleBase().RoleData().SkillResetCount this.role.GetRoleBase().SetDirty(true) if notify { this.role.ReplayGate(ntfMsg, true) } } func (this *RoleSkill) JobSkillChangeNtf(heroId int32, roleSkill *serverproto.RoleSkill, jobTypeList []int32) { ntfMsg := &serverproto.SCJobSkillDataNtf{ HeroId: heroId, } //有变化发变化,否则全部发 if len(jobTypeList) > 0 { for _, data := range jobTypeList { for _, jobSkill := range roleSkill.JobSkillList { if jobSkill.JobStage == data { ntfMsg.JobSkillList = append(ntfMsg.JobSkillList, jobSkill) break } } } } else { for _, jobSkill := range roleSkill.JobSkillList { ntfMsg.JobSkillList = append(ntfMsg.JobSkillList, jobSkill) } } this.role.ReplayGate(ntfMsg, true) } //获得槽位技能升级所以 func (this *RoleSkill) getSkillSlotId(slotId, level int32) int32 { return slotId*1000 + level } func (this *RoleSkill) getParterSkillTreeIdx(heroId, jobType int32) int32 { return heroId*1000 + jobType } func (this *RoleSkill) getMainSkill() *serverproto.RoleSkill { return this.role.GetRoleHero().GetMainHero().Skill } //技能是否解锁 func (this *RoleSkill) isSkillUnLock(roleSkill *serverproto.RoleSkill, skillId int32) bool { if roleSkill == nil { return false } for idx := range roleSkill.JobSkillList { for _, data := range roleSkill.JobSkillList[idx].UnlockSkillList { if data.Key == skillId { return true } } } return false } //技能是否已经装备 func (this *RoleSkill) isSkillEquip(skillId int32, roleSkill *serverproto.RoleSkill) bool { for _, data := range roleSkill.SkillList { if data.SkillId == skillId { return true } } return false } //技能卸载 func (this *RoleSkill) unloadSkillEquip(skillId int32, roleSkill *serverproto.RoleSkill) { for _, data := range roleSkill.SkillList { if data.SkillId == skillId { data.SkillId = 0 break } } } //replaceSkillId=0表示放置最高级技能 func (this *RoleSkill) SkillReplace(heroId, idx, replaceSkillId int32, notify bool, heroChange bool) serverproto.ErrorCode { if idx < 0 || idx > int32(maxSlotNum) { logutil.InfoF("uid=%v SlotLevelUp slotIdx invalid", this.role.GetUUid()) return serverproto.ErrorCode_ERROR_FAIL } heroData := this.role.GetRoleHero().GetHero(heroId) if heroData == nil { logutil.InfoF("uid=%v SkillReplace hero not found heroid=%v", this.role.GetUUid(), heroId) return serverproto.ErrorCode_ERROR_FAIL } //未解锁 skillSlotData := heroData.Skill.SkillList[idx-1] if skillSlotData.Unlock == 0 { return serverproto.ErrorCode_ERROR_SKILL_SLOT_LOCK } if replaceSkillId != 0 { //判断技能是否存在(技能是否解锁) skillId := replaceSkillId*1000 + 1 _, ok := serverproto.SkillLvCfgLoader[skillId] if !ok { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST } if this.isSkillUnLock(heroData.Skill, replaceSkillId) && !this.isSkillEquip(replaceSkillId, heroData.Skill) { skillSlotData.SkillId = replaceSkillId if notify { this.SlotChangeNtf(heroId) } if heroChange { this.role.GetRoleHero().addHeroChange(heroId) } return serverproto.ErrorCode_ERROR_OK } } else { //未装备技能的选取一个最高阶技能 if skillSlotData.SkillId == 0 { for id, _ := range heroData.Skill.JobSkillList { for _, data := range heroData.Skill.JobSkillList[id].UnlockSkillList { if data.Key > replaceSkillId && !this.isSkillEquip(data.Key, heroData.Skill) { replaceSkillId = data.Key } } } if replaceSkillId != 0 { skillSlotData.SkillId = replaceSkillId if notify { this.SlotChangeNtf(heroId) } if heroChange { this.role.GetRoleHero().addHeroChange(heroId) } return serverproto.ErrorCode_ERROR_OK } } } //skill未激活 return serverproto.ErrorCode_ERROR_SKILL_NOT_ACTIVE } func (this *RoleSkill) ActiveSkill(heroId int32, skillId int32) serverproto.ErrorCode { if skillId <= 0 { return serverproto.ErrorCode_ERROR_FAIL } heroData := this.role.GetRoleHero().GetHero(heroId) if heroData == nil { logutil.InfoF("uid=%v ActiveSkill hero not found heroid=%v", this.role.GetUUid(), heroId) return serverproto.ErrorCode_ERROR_HERO_NO_FOUND } //check active ret := this.CheckActiveSkill(heroData, skillId) if ret != serverproto.ErrorCode_ERROR_OK { return ret } //active jobStage := this.activeSkill(heroData, skillId) if jobStage >= 0 { this.JobSkillChangeNtf(heroId, heroData.Skill, []int32{jobStage}) this.CheckAndFillSkillSlot(heroData) //查看当前技能是否有 被动技能。有的话计算战力, //this.role.roleFightPower.CalcSkillLevelUp(heroId, skillId, true) this.role.GetRoleHero().addHeroChange(heroData.Id) //attr change bFightChangeNotNotify := true if heroData.IsBattle { bFightChangeNotNotify = false } this.role.roleBattleAttr.AttrChange(AttrChangeST{ ChangeType: Attr_Change_Skill, ChangeHeroData: heroData, SkillCfgId: skillId, OldSkillLevel: 0, NewSkillLevel: 1, FightChangeNotNotify: bFightChangeNotNotify, }) //压制值计算 this.role.GetRoleHero().CalRepress(RepressChangeST{HeroData: heroData, BReset: false, SkillCfgId: skillId, OldSKillLevel: 0, NewSKillLevel: 1}) } return serverproto.ErrorCode_ERROR_OK } func (this *RoleSkill) CheckActiveSkill(heroData *serverproto.HeroData, skillId int32) serverproto.ErrorCode { if heroData == nil { return serverproto.ErrorCode_ERROR_HERO_NO_FOUND } //是否已经解锁 for _, data := range heroData.Skill.JobSkillList { for _, skill := range data.UnlockSkillList { if skill.Key == skillId { return serverproto.ErrorCode_ERROR_SKILL_SKILL_REACTIVE } } } //当前职业阶段是否可学 jobStage, jobType := this.getSkillStage(skillId) if this.role.roleHero.GetHeroJobStage(heroData.Id) < jobStage { return serverproto.ErrorCode_ERROR_SKILL_JOB_STAGE_ERROR } if jobType != 0 { if this.role.roleHero.GetHeroJobType(heroData.Id) != jobType { return serverproto.ErrorCode_ERROR_SKILL_JOB_TYPE_ERROR } } else { if !this.role.roleHero.IsMainHero(heroData.Id) { return serverproto.ErrorCode_ERROR_FAIL } } //等级是否够 var consumeItemList = map[int32]int32{} if this.role.roleHero.IsMainHero(heroData.Id) { skillCfg, ok := serverproto.SkillTreeCfgLoader[skillId] if !ok { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST } skillCfg2, ok2 := model.ConvertSkillTree[skillId] if !ok2 { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST } if skillCfg.OpenLevel > 0 && skillCfg.OpenLevel > this.role.GetRoleLevel() { return serverproto.ErrorCode_ERROR_SKILL_SKILL_OPEN_LEVEL } for _, data := range skillCfg2.OpenCost { consumeItemList[data.Key] = data.Value } } else { skillCfg, ok := serverproto.ParterSkillTreeCfgLoader[skillId] if !ok { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST } skillCfg2, ok2 := model.ConvertPartnerSkillTree[skillId] if !ok2 { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST } if skillCfg.OpenLevel > 0 && skillCfg.OpenLevel > heroData.BaseLevel { return serverproto.ErrorCode_ERROR_SKILL_SKILL_OPEN_LEVEL } for _, data := range skillCfg2.OpenCost { if data.Key == 0 { continue } consumeItemList[data.Key] = data.Value } } if len(consumeItemList) > 0 { if !this.role.CheckResLitNum(consumeItemList) { return serverproto.ErrorCode_ERROR_SKILL_RES_NOT_ENOUGH } //扣除道具 this.role.DelItemList(consumeItemList, AddItemST{AddFrom: AddFrom_Skill}) } //如果当前阶段没学过技能。则初始化当前阶段技能列表 return serverproto.ErrorCode_ERROR_OK } func (this *RoleSkill) SkillLevelUp(heroData *serverproto.HeroData, skillId int32) serverproto.ErrorCode { if heroData == nil { return serverproto.ErrorCode_ERROR_HERO_NO_FOUND } //stage, _ := this.getSkillStage(skillId) var bRet serverproto.ErrorCode var oldSkillLevel, newSkillLevel int32 if this.role.roleHero.IsMainHero(heroData.Id) { bRet, oldSkillLevel, newSkillLevel = this.RoleSkillLevelUp(heroData, skillId) } else { bRet, oldSkillLevel, newSkillLevel = this.PartnerSkillLevelUp(heroData, skillId) } if bRet == serverproto.ErrorCode_ERROR_OK { //战力计算 //this.role.roleFightPower.CalcSkillLevelUp(heroData.Id, skillId, true) //超值礼包开启 this.role.GetRoleActivity().SuperChargeUnlockCheck( serverproto.UnlockChargeType_UChargeType_SkillLevelUp, &SuperChargeUnlockST{}) //attr change bFightChangeNotNotify := true if heroData.IsBattle { bFightChangeNotNotify = false } this.role.roleBattleAttr.AttrChange(AttrChangeST{ ChangeType: Attr_Change_Skill, ChangeHeroData: heroData, SkillCfgId: skillId, OldSkillLevel: oldSkillLevel, NewSkillLevel: newSkillLevel, FightChangeNotNotify: bFightChangeNotNotify, }) //压制值计算 this.role.GetRoleHero().CalRepress(RepressChangeST{HeroData: heroData, BReset: false, SkillCfgId: skillId, OldSKillLevel: oldSkillLevel, NewSKillLevel: newSkillLevel}) } return bRet } func (this *RoleSkill) GetSkillLevel(heroData *serverproto.HeroData, skillId int32) int32 { for _, data := range heroData.Skill.JobSkillList { for _, subData := range data.UnlockSkillList { if subData.Key == skillId { return subData.Value } } } return -1 } func (this *RoleSkill) ReplaceNewSkill(heroId, srcSkillId, dstSkillId int32) serverproto.ErrorCode { if dstSkillId <= 0 || srcSkillId <= 0 { return serverproto.ErrorCode_ERROR_FAIL } heroData := this.role.GetRoleHero().GetHero(heroId) if heroData == nil { logutil.InfoF("uid=%v ReplaceNewSkill hero not found heroid=%v", this.role.GetUUid(), heroId) return serverproto.ErrorCode_ERROR_HERO_NO_FOUND } //// 是否存在新技能 //if this.GetSkillById(heroData.Id, dstSkillId) != nil{ // return serverproto.ErrorCode_ERROR_FAIL //} //check active ret := this.CheckActiveSkill(heroData, dstSkillId) if ret != serverproto.ErrorCode_ERROR_OK { return ret } //------------------------------------------------------ //判断技能是否存在(技能是否解锁) srcStage, srcType := this.getSkillStage(srcSkillId) if srcStage == -1 || srcType == -1 { return serverproto.ErrorCode_ERROR_OK } dstStage, dstType := this.getSkillStage(dstSkillId) if dstStage == -1 || dstType == -1 { return serverproto.ErrorCode_ERROR_OK } //找到对应的技能删除 for _, data := range heroData.Skill.JobSkillList { for index, valueType := range data.UnlockSkillList { if valueType.Key != srcSkillId { continue } data.UnlockSkillList = append(data.UnlockSkillList[:index], data.UnlockSkillList[index+1:]...) break } } // 添加新技能 var dst *serverproto.JobSkillData = nil for _, data := range heroData.Skill.JobSkillList { if data.JobStage != dstStage { continue } dst = data break } if dst == nil { dst = &serverproto.JobSkillData{JobStage: dstStage} heroData.Skill.JobSkillList = append(heroData.Skill.JobSkillList, dst) } dst.UnlockSkillList = append(dst.UnlockSkillList, &serverproto.KeyValueType{Key: dstSkillId, Value: 1}) // 变更技能槽技能 for _, slot := range heroData.Skill.SkillList { if slot.SkillId != srcSkillId { continue } slot.SkillId = dstSkillId break } //------------------------------------------------------ this.JobSkillChangeNtf(heroId, heroData.Skill, []int32{srcStage, dstStage}) this.CheckAndFillSkillSlot(heroData) //查看当前技能是否有 被动技能。有的话计算战力, //this.role.roleFightPower.CalcSkillLevelUp(heroId, dstSkillId, true) this.role.GetRoleHero().addHeroChange(heroData.Id) //超值礼包开启 if this.role.GetRoleActivity() != nil { this.role.GetRoleActivity().SuperChargeUnlockCheck( serverproto.UnlockChargeType_UChargeType_SKillAdvance, &SuperChargeUnlockST{}) } TaskMagCheck(this.role, serverproto.TaskType_Eve_Skill_Advance_Num, 1) return serverproto.ErrorCode_ERROR_OK } func (this *RoleSkill) GetSkillById(heroId, skillId int32) *serverproto.KeyValueType { heroData := this.role.roleHero.GetHero(heroId) stage, _ := this.getSkillStage(skillId) for _, data := range heroData.Skill.JobSkillList { if data.JobStage != stage { continue } for _, valueType := range data.UnlockSkillList { if valueType.Key != skillId { continue } return valueType } } return nil } func (this *RoleSkill) RoleSkillLevelUp(heroData *serverproto.HeroData, skillId int32) (serverproto.ErrorCode, int32, int32) { if heroData == nil { return serverproto.ErrorCode_ERROR_HERO_NO_FOUND, 0, 0 } stage, _ := this.getSkillStage(skillId) //配置表中有无此等级的技能配置 curLevel := this.GetSkillLevel(heroData, skillId) sCfg, _ := serverproto.SkillLvCfgLoader[skillId*1000+curLevel+1] if sCfg == nil { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST, 0, 0 } //找到是否激活这个技能 skillInfo := this.GetSkillById(heroData.Id, skillId) if skillInfo == nil || skillInfo.Value < 1 { return serverproto.ErrorCode_ERROR_FAIL, 0, 0 } //如果达到最大等级, 判断是否可以进阶 if skillCfg, ok := serverproto.SkillTreeCfgLoader[skillId]; ok { if skillInfo.Value >= skillCfg.MaxLv { if len(skillCfg.SuperSkill) <= 0 { return serverproto.ErrorCode_ERROR_SKILL_SKILL_MAX_LEVEL, 0, 0 } if skillCfg.SkillBranch > this.role.GetRoleHero().GetHeroJobStage(heroData.Id) { return serverproto.ErrorCode_ERROR_SKILL_ORDER_NOT, 0, 0 } dbJob, ok := model.DBJobChange[model.GetJobChangeKey(true, heroData.ConfigId)] if !ok { return serverproto.ErrorCode_ERROR_FAIL, 0, 0 } dstSkill := int32(0) for _, sup := range skillCfg.SuperSkill { branch, dstSkillId := model.Str2Res(sup) if dbJob.JobBranch != branch { continue } dstSkill = dstSkillId break } return this.ReplaceNewSkill(heroData.Id, skillId, dstSkill), 0, 0 } } else { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST, 0, 0 } skillCost, ok := model.ConvertSkillTree[skillId] if !ok { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST, 0, 0 } //查看等级是否够//等级不够不可以学习 upLevel, ok := skillCost.HeroLevel[skillInfo.Value-1] if ok && upLevel > this.role.roleHero.GetHeroLevel(heroData.Id) { return serverproto.ErrorCode_ERROR_SKILL_ROLE_LEVEL_NOT_ENOUGH, 0, 0 } //查看到道具是否够 upCost, _ := skillCost.UpGradeCost[skillInfo.Value-1] if upCost == nil { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST, 0, 0 } if upCost.Key != 0 && upCost.Value != 0 { var consumeItemList = map[int32]int32{} consumeItemList[upCost.Key] = upCost.Value if len(consumeItemList) > 0 { ret, resType := this.role.CheckResNum(consumeItemList) if !ret { bRet := this.role.GetResNotice(resType) return bRet, 0, 0 } //扣除道具 this.role.DelItemList(consumeItemList, AddItemST{AddFrom: AddFrom_Skill}) } } //升级 oldSkillLevel := skillInfo.Value skillInfo.Value++ this.JobSkillChangeNtf(this.role.GetRoleBase().RoleData().HeroData.Id, heroData.Skill, []int32{stage}) this.role.GetRoleHero().addHeroChange(heroData.Id) //升级技能 return serverproto.ErrorCode_ERROR_OK, oldSkillLevel, skillInfo.Value } func (this *RoleSkill) PartnerSkillLevelUp(heroData *serverproto.HeroData, skillId int32) (serverproto.ErrorCode, int32, int32) { if heroData == nil { return serverproto.ErrorCode_ERROR_HERO_NO_FOUND, 0, 0 } stage, _ := this.getSkillStage(skillId) //配置表中有无此等级的技能配置 curLevel := this.GetSkillLevel(heroData, skillId) sCfg, _ := serverproto.SkillLvCfgLoader[skillId*1000+curLevel+1] if sCfg == nil { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST, 0, 0 } //找到是否激活这个技能 var skillInfo *serverproto.KeyValueType for _, data := range heroData.Skill.JobSkillList { if stage != data.JobStage { continue } var bFind = false for _, skillData := range data.UnlockSkillList { if skillId == skillData.Key { bFind = true skillInfo = skillData break } } if !bFind { return serverproto.ErrorCode_ERROR_FAIL, 0, 0 } } if skillInfo == nil { return serverproto.ErrorCode_ERROR_FAIL, 0, 0 } ////查看当前技能等级是否达到最大等级 //skillCfg, ok := serverproto.ParterSkillTreeCfgLoader[skillId] //if !ok { // return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST, 0, 0 //} //if skillInfo.Value >= skillCfg.MaxLv { // return serverproto.ErrorCode_ERROR_SKILL_SKILL_MAX_LEVEL, 0, 0 //} //如果达到最大等级, 判断是否可以进阶 if skillCfg, ok := serverproto.ParterSkillTreeCfgLoader[skillId]; ok { if skillInfo.Value >= skillCfg.MaxLv { if len(skillCfg.SuperSkill) <= 0 { return serverproto.ErrorCode_ERROR_SKILL_SKILL_MAX_LEVEL, 0, 0 } if skillCfg.SkillBranch > this.role.GetRoleHero().GetHeroJobStage(heroData.Id) { return serverproto.ErrorCode_ERROR_SKILL_ORDER_NOT, 0, 0 } dbJob, ok := model.DBJobChange[model.GetJobChangeKey(true, heroData.ConfigId)] if !ok { return serverproto.ErrorCode_ERROR_FAIL, 0, 0 } dstSkill := int32(0) for _, sup := range skillCfg.SuperSkill { branch, dstSkillId := model.Str2Res(sup) if dbJob.JobBranch != branch { continue } dstSkill = dstSkillId break } return this.ReplaceNewSkill(heroData.Id, skillId, dstSkill), 0, 0 } } else { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST, 0, 0 } //查看到道具是否够 skillCost, ok := model.ConvertPartnerSkillTree[skillId] if !ok { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST, 0, 0 } //查看等级是否够//等级不够不可以学习 upLevel, _ := skillCost.HeroLevel[skillInfo.Value-1] if upLevel > this.role.roleHero.GetHeroLevel(heroData.Id) { return serverproto.ErrorCode_ERROR_SKILL_ROLE_LEVEL_NOT_ENOUGH, 0, 0 } upCost, _ := skillCost.UpGradeCost[skillInfo.Value-1] if upCost == nil { return serverproto.ErrorCode_ERROR_SKILL_CONFIG_DATA_NOT_EXIST, 0, 0 } if upCost.Key != 0 && upCost.Value != 0 { var consumeItemList = map[int32]int32{} consumeItemList[upCost.Key] = upCost.Value if len(consumeItemList) > 0 { ret, resType := this.role.CheckResNum(consumeItemList) if !ret { bRet := this.role.GetResNotice(resType) return bRet, 0, 0 } //扣除道具 this.role.DelItemList(consumeItemList, AddItemST{AddFrom: AddFrom_Skill}) } } //升级 oldSkillLevel := skillInfo.Value skillInfo.Value++ this.JobSkillChangeNtf(heroData.Id, heroData.Skill, []int32{stage}) this.role.GetRoleHero().addHeroChange(heroData.Id) //升级技能 return serverproto.ErrorCode_ERROR_OK, oldSkillLevel, skillInfo.Value } func (this *RoleSkill) getSkillStage(skillId int32) (int32, int32) { if this.role == nil { return -1, -1 } skillCfg, ok := serverproto.SkillTreeCfgLoader[skillId] if ok { return skillCfg.JobStage, skillCfg.JobType } skillCfg2, ok2 := model.ConvertPartnerSkillIdxList[skillId] if ok2 { partnerCfg, ok3 := serverproto.ParterCfgLoader[skillCfg2.ParterID] if ok3 { return partnerCfg.JobStage, skillCfg2.JobType } } return -1, -1 } func (this *RoleSkill) checkJobType(skillJobType int32, heroData *serverproto.HeroData) bool { if heroData == nil { return false } if this.role.roleHero.IsMainHero(heroData.Id) { jobCfg, ok := serverproto.JobCfgLoader[heroData.ConfigId] if !ok { return false } if skillJobType <= jobCfg.JobType { return true } } else { partnerCfg, ok := serverproto.ParterCfgLoader[heroData.ConfigId] if !ok { return false } if skillJobType <= partnerCfg.JobType { return true } } return false } func (this *RoleSkill) activeSkill(heroData *serverproto.HeroData, skillId int32) int32 { //判断技能是否存在(技能是否解锁) // skillCfg,ok := serverproto.SkillCfgLoader[skillId*100 + 1] jobStage, jobType := this.getSkillStage(skillId) if jobStage == -1 || jobType == -1 { return -1 } //如果还没找到该阶段数据,说明还没进行专职操作 var jobSkillData *serverproto.JobSkillData = nil var bFind = false for idx, data := range heroData.Skill.JobSkillList { if data.JobStage == jobStage { jobSkillData = heroData.Skill.JobSkillList[idx] bFind = true break } } if !bFind { //新一阶的技能数据初始化 jobSkillData = &serverproto.JobSkillData{ JobStage: jobStage, } jobSkillData.UnlockSkillList = append(jobSkillData.UnlockSkillList, &serverproto.KeyValueType{ Key: skillId, Value: 1, }) heroData.Skill.JobSkillList = append(heroData.Skill.JobSkillList, jobSkillData) return jobStage } if jobSkillData != nil { jobSkillData.UnlockSkillList = append(jobSkillData.UnlockSkillList, &serverproto.KeyValueType{ Key: skillId, Value: 1, }) } return jobStage } func (this *RoleSkill) CheckAndFillSkillSlot(heroData *serverproto.HeroData) { if heroData == nil { return } for index, data := range heroData.Skill.SkillList { if data.Unlock > 0 && data.SkillId == 0 { this.SkillReplace(heroData.Id, int32(index+1), 0, true, true) } } } func (this *RoleSkill) CheckSlotLockState() { for i := 1; i <= maxSlotNum; i++ { slotId := this.getSkillSlotId(int32(i), 1) // cfgData,ok := skillSlotCfgList[slotId] _, ok := serverproto.SkillSlotCfgLoader[slotId] if ok { if i > maxSlotNum { continue } //role mainHero := this.role.GetRoleHero().GetMainHero() if this.role.GetRoleBase().checkUnLockState(mainHero.Id, model.ConvertSkillSlotMain[slotId].ConditionList) == serverproto.ErrorCode_ERROR_OK { if this.processSlotLockState(mainHero, int32(i), true) { this.role.GetRoleHero().addHeroChange(mainHero.Id) //技能槽位变化//战力变化 //this.role.roleFightPower.CalcSkillSlotChange(mainHero) } } //hero for _, data := range this.role.GetRoleHero().heroList { if this.role.GetRoleBase().checkUnLockState(data.Id, model.ConvertSkillSlotPartner[slotId].ConditionList) == serverproto.ErrorCode_ERROR_OK { if this.processSlotLockState(data, int32(i), true) { this.role.GetRoleHero().addHeroChange(data.Id) //技能槽位变化//战力变化 //this.role.roleFightPower.CalcSkillSlotChange(data) } } } } } } func (this *RoleSkill) processSlotLockState(heroData *serverproto.HeroData, idx int32, bCondition bool) bool { if heroData.Skill.SkillList[idx-1].Unlock != 0 && heroData.Skill.SkillList[idx-1].SkillId != 0 { //已经装备技能返回 return true } //已经解锁 if heroData.Skill.SkillList[idx-1].Unlock != 0 && heroData.Skill.SkillList[idx-1].SkillId == 0 { if this.SkillReplace(heroData.Id, idx, 0, true, false) == serverproto.ErrorCode_ERROR_OK { return true } } if bCondition { //解锁默认为1级 heroData.Skill.SkillList[idx-1].Unlock = 1 //查看是否有激活的技能,直接装备技能 this.SkillReplace(heroData.Id, idx, 0, true, false) return true } return false } func (this *RoleSkill) checkSlotLevelUpState(slotData *serverproto.RoleSkillSlot) serverproto.ErrorCode { if slotData == nil { return serverproto.ErrorCode_ERROR_FAIL } //未解锁 if slotData.Unlock == 0 { return serverproto.ErrorCode_ERROR_SKILL_SLOT_LOCK } //槽位上没有技能无法进行升级 if slotData.SkillId == 0 { return serverproto.ErrorCode_ERROR_SKILL_SLOT_NO_SKILL } return serverproto.ErrorCode_ERROR_OK } func (this *RoleSkill) SwapSkill(heroId, firstSlotId, secondSlotId int32) serverproto.ErrorCode { heroData := this.role.GetRoleHero().GetHero(heroId) if heroData == nil { logutil.InfoF("uid=%v ActiveSkill hero not found heroid=%v", this.role.GetUUid(), heroId) return serverproto.ErrorCode_ERROR_FAIL } //判断槽位是否存在 slotSkillLen := int32(len(heroData.Skill.SkillList)) if firstSlotId > slotSkillLen || secondSlotId > slotSkillLen || firstSlotId < 0 || secondSlotId < 0 { return serverproto.ErrorCode_ERROR_FAIL } //判断是否解锁 firstSlotData := heroData.Skill.SkillList[firstSlotId-1] secondSlotData := heroData.Skill.SkillList[secondSlotId-1] if firstSlotData == nil || firstSlotData.Unlock <= 0 || secondSlotData == nil || secondSlotData.Unlock <= 0 { return serverproto.ErrorCode_ERROR_FAIL } fistSkill := firstSlotData.SkillId secondSkill := secondSlotData.SkillId firstSlotData.SkillId = secondSkill secondSlotData.SkillId = fistSkill // this.SlotChangeNtf(heroId, firstSlotId, firstSlotData) // this.SlotChangeNtf(heroId, secondSlotId, secondSlotData) this.SlotChangeNtf(heroId) this.role.GetRoleHero().addHeroChange(heroId) logutil.DebugF("uid=%v SwapSkillBefore %v-%v,%v-%v", this.role.GetUUid(), firstSlotId, fistSkill, secondSlotId, secondSkill) logutil.DebugF("uid=%v SwapSkillAfter %v-%v,%v-%v", this.role.GetUUid(), firstSlotId, firstSlotData.SkillId, secondSlotId, secondSlotData.SkillId) return serverproto.ErrorCode_ERROR_OK } func (this *RoleSkill) SetSkillList(heroId int32, skillList []int32) serverproto.ErrorCode { if len(skillList) <= 0 || len(skillList) > maxSlotNum { //发过来的列表元素个数 return serverproto.ErrorCode_ERROR_FAIL } heroData := this.role.roleHero.GetHero(heroId) if heroData == nil || heroData.Skill == nil || heroData.Skill.SkillList == nil || len(heroData.Skill.SkillList) <= 0 { return serverproto.ErrorCode_ERROR_FAIL } //校验技能是否解锁//未解锁,直接返回//技能必须连续不可出现中间有技能ID为0的情况 var isSkillUnlocked = false var label, hasZeroSkillId = false, false for _, skillId := range skillList { if 0 != skillId && !this.isSkillUnLock(heroData.Skill, skillId) { isSkillUnlocked = true } if 0 == skillId && !label { label = true } if 0 != skillId && label { hasZeroSkillId = true } } if isSkillUnlocked { //有未解锁的技能 return serverproto.ErrorCode_ERROR_FAIL //未解锁 } if hasZeroSkillId { //两个非零技能中间有0技能ID return serverproto.ErrorCode_ERROR_FAIL //有0技能在非0技能中间 } //校验技能槽位是否开启,对应的技能是否不变 for index, data := range heroData.Skill.SkillList { if len(skillList) <= index { break } if data.Unlock == 0 && skillList[index] != 0 { //槽位未解锁,但是发送来的列表却有技能 return serverproto.ErrorCode_ERROR_FAIL } } //清空当前技能列表设置 for _, skillData := range heroData.Skill.SkillList { skillData.SkillId = 0 } //设置技能列表 for i := 0; i < len(skillList); i++ { if 0 == skillList[i] { continue } this.SkillReplace(heroId, int32(i+1), skillList[i], false, false) } //构建消息回包 this.SlotChangeNtf(heroId) this.role.GetRoleHero().addHeroChange(heroData.Id) return serverproto.ErrorCode_ERROR_OK } func (this *RoleSkill) CheckNeedReset(heroData *serverproto.HeroData, bsuper bool) serverproto.ErrorCode { if heroData == nil { return serverproto.ErrorCode_ERROR_FAIL } if heroData.GetSkill() == nil || len(heroData.GetSkill().JobSkillList) == 0 { return serverproto.ErrorCode_ERROR_SKILL_NO_SKILL_NEED_RESET } isMain := this.role.roleHero.IsMainHero(heroData.Id) for _, skillSet := range heroData.GetSkill().JobSkillList { for _, data := range skillSet.UnlockSkillList { if data.Value <= 1 { continue } if bsuper { // 是否只重置高级经验 if isMain { db, ok := serverproto.SkillTreeCfgLoader[data.Key] if !ok { continue } if db.BeforeSkill <= 0 { continue } } else { db, ok := serverproto.ParterSkillTreeCfgLoader[data.Key] if !ok { continue } if db.BeforeSkill <= 0 { continue } } return serverproto.ErrorCode_ERROR_OK } else { return serverproto.ErrorCode_ERROR_OK } } } //到这里说明都是1级技能,不需要重置 return serverproto.ErrorCode_ERROR_SKILL_NO_SKILL_NEED_RESET } func (this *RoleSkill) ConverSkillExp(cnt int32) serverproto.ErrorCode { skillItemId := int32(serverproto.ResType_Res_Cruise) curNum := this.role.GetResNum(skillItemId) dbValue, ok := serverproto.GlobalCfgLoader[int32(serverproto.GlobalType_Global_Skill_Exp_Conver)] if !ok { return serverproto.ErrorCode_ERROR_FAIL } totalNum := dbValue.IVal * cnt if uint64(totalNum) > curNum { return serverproto.ErrorCode_ERROR_SKILL_ORDER_NOT } this.role.DelItem(skillItemId, totalNum, AddItemST{AddFrom: AddFrom_SkillExpConver}) this.role.AddItem(int32(serverproto.ResType_Res_HightSkillExp), cnt, AddFrom_SkillExpConver) return serverproto.ErrorCode_ERROR_OK } func (this *RoleSkill) ResetSkillLevel(heroId int32, bsuper bool) serverproto.ErrorCode { heroData := this.role.roleHero.GetHero(heroId) err := this.CheckNeedReset(heroData, bsuper) if err != serverproto.ErrorCode_ERROR_OK { return err } //扣资源 resetCount := this.role.GetRoleBase().RoleData().SkillResetCount if resetCount < 0 { //客户端要留个-1情况下,为关闭的设定 return serverproto.ErrorCode_ERROR_SKILL_RESET_NOT_OPEN } if resetCount >= int32(len(model.ConvertResetSkill)) { resetCount = int32(len(model.ConvertResetSkill)) - 1 } data, ok := model.ConvertResetSkill[resetCount] if !ok { return serverproto.ErrorCode_ERROR_SKILL_RESET_CONFIG_NOT_FOUND } vipSkillReset := this.role.GetRoleBase().GetVipData(model.Vip_System_SkillReset) if vipSkillReset <= 0 { if data.Value != 0 && data.Key != 0 { var consumeItemList = map[int32]int32{} consumeItemList[data.Key] = data.Value if len(consumeItemList) > 0 { if !this.role.CheckResLitNum(consumeItemList) { return serverproto.ErrorCode_ERROR_SKILL_RESET_RESOURCE_NOT_ENOUGH } //扣除道具 this.role.DelItemList(consumeItemList, AddItemST{AddFrom: AddFrom_Skill}) } } } //处理技能重置//返还道具 var addItemList = map[int32]int32{} isMain := this.role.roleHero.IsMainHero(heroId) //var payBackCount int32 = 0 for _, skillSet := range heroData.GetSkill().JobSkillList { for _, skillList := range skillSet.UnlockSkillList { if skillList.Value <= 1 { continue } bHighSkill := false if isMain { db, ok := serverproto.SkillTreeCfgLoader[skillList.Key] if !ok { continue } if db.BeforeSkill > 0 { bHighSkill = true } } else { db, ok := serverproto.ParterSkillTreeCfgLoader[skillList.Key] if !ok { continue } if db.BeforeSkill > 0 { bHighSkill = true } } if bsuper { if !bHighSkill { continue } } count := this.CalcResetBack(skillList.Key, skillList.Value, isMain) skillList.Value = 1 if count <= 0 { continue } if bHighSkill { addItemList[int32(serverproto.ResType_Res_HightSkillExp)] += count } else { addItemList[int32(serverproto.ResType_Res_Cruise)] += count } } } this.role.GetRoleBase().RoleData().SkillResetCount++ this.JobSkillChangeNtf(heroId, heroData.Skill, []int32{}) if len(addItemList) > 0 { this.role.AddItemList(addItemList, AddFrom_ResetSkill, true) } //设置藏标识 this.role.GetRoleHero().addHeroChange(heroData.Id) //重新计算这个格斗家战力 //this.role.GetRoleFightPower().CalcHeroSkillFightPower(heroId, heroData) //attr change bFightChangeNotNotify := true if heroData.IsBattle { bFightChangeNotNotify = false } this.role.roleBattleAttr.AttrChange(AttrChangeST{ ChangeType: Attr_Change_Skill, ChangeHeroData: heroData, BSkillReset: true, FightChangeNotNotify: bFightChangeNotNotify, }) //压制值计算 this.role.GetRoleHero().CalRepress(RepressChangeST{HeroData: heroData, BReset: true}) return serverproto.ErrorCode_ERROR_OK } func (this *RoleSkill) CalcResetBack(skillId, skillLevel int32, isMain bool) int32 { var count int32 = 0 if isMain { data, ok := model.ConvertSkillTree[skillId] if !ok { return 0 } value, ok := data.ResetBack[skillLevel] if !ok { return 0 } count = value } else { data, ok := model.ConvertPartnerSkillTree[skillId] if !ok { return 0 } value, ok := data.ResetBack[skillLevel] if !ok { return 0 } count = value } return count } //所有英雄技能进阶次数 func (this *RoleSkill) GetAllHeroSkillAdvanceNum() int32 { var retNum int32 = 0 var heroDataList []*serverproto.HeroData for _, heroData := range this.role.roleHero.heroList { if heroData == nil { continue } heroDataList = append(heroDataList, heroData) } heroDataList = append(heroDataList, this.role.GetRoleHero().GetMainHero()) for idx := 0; idx < len(heroDataList); idx++ { heroData := heroDataList[idx] for i := 0; i < len(heroData.Skill.JobSkillList); i++ { tmpJobSKill := heroData.Skill.JobSkillList[i] for j := 0; j < len(tmpJobSKill.UnlockSkillList); j++ { if this.role.GetRoleHero().IsMainHero(heroData.Id) { skillData, ok := serverproto.SkillTreeCfgLoader[tmpJobSKill.UnlockSkillList[j].Key] if !ok { continue } if skillData.BeforeSkill > 0 { retNum++ } } else { skillData, ok := serverproto.ParterSkillTreeCfgLoader[tmpJobSKill.UnlockSkillList[j].Key] if !ok { continue } if skillData.BeforeSkill > 0 { retNum++ } } } } } return retNum }