local HorseSoul_Controller = {} local private = {} local EventSystem = require('Event/EventSystem') HorseSoul_Controller.PositionImage = { [1] = ConstAssetPathConfig.Path9, [2] = ConstAssetPathConfig.AssetPath58, [3] = ConstAssetPathConfig.AssetPath59, [4] = ConstAssetPathConfig.AssetPath60, [5] = ConstAssetPathConfig.AssetPath61, [6] = ConstAssetPathConfig.AssetPath62, } private.horseSoulGs = {} function HorseSoul_Controller.OnStartup() EventSystem.Regist(EventID.UI_HorseSoul_EquipUpdate, private.RefreshAvailableExp) EventSystem.Regist(EventID.HorseSoulPearl_UpdateBag, private.RefreshAvailableExp) EventSystem.Regist(EventID.BagItem_Update, private.RefreshAvailableExp) end function HorseSoul_Controller.IsSoulSkillInvalid(horseId) local horseInfo = MDL.WarHorse.GetInfoByID(horseId) if horseInfo.HeroID then local lineUpIds = MDL.Player.GetHeroLinUpIds() local index for i, v in ipairs(lineUpIds) do if v == horseInfo.HeroID then index = i break end end --135主将,246副将 if index and index % 2 == 0 then --获取主将的马和魂珠技能 local mainHeroHorseInfo = MDL.WarHorse.GetInfoByHeroID(lineUpIds[index - 1]) local _, mainSuitId = 0, 0 if mainHeroHorseInfo then _, mainSuitId = CTL.HorseSoul.GetSoulSkillLevel(mainHeroHorseInfo.ID) end local _, subSuitId = CTL.HorseSoul.GetSoulSkillLevel(horseInfo.ID) if mainSuitId and subSuitId and mainSuitId == subSuitId then return true end end end return false end --未装备时,服务器会发送"0"过来 function HorseSoul_Controller.JudgeSoulId(soulId) return not string.isNilOrEmpty(soulId) and soulId ~= "0" end --打开tips界面 function HorseSoul_Controller.OpenSoulTips(horseId, targetSoulId, equippedSoulId, isChildTips, isOffset) UIManager.OpenView(Const_UI_Lua.UIEnum.UIHorseSoulTipBase, { horseId = horseId, targetSoulId = targetSoulId, equippedSoulId = equippedSoulId, isChildTips = isChildTips, isOffset = isOffset }) end function HorseSoul_Controller.GotoHorseSoul() if MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.HorseSoul) then local activeHorses = MDL.WarHorse.GetActiveHorseInfoDic() if activeHorses then for _, v in pairs (activeHorses) do if v.HeroID then CTL.WarHorse.OpenSubPanel(CTL.WarHorse.Horse_EnterType.Formation, v.ConfigInfo, CTL.WarHorse.Horse_TabIndex.HorseSoul) return end end end CTL.Tips.AddTipsMsg(Const_IDS.IDS_Resonance_Horse_NoOne) else CTL.Tips.AddTipsMsg(Const_IDS.IDS_ERRORCODE_1317_InfoCode_Guild_GuildInviteTargetFunctionLock) end end -- 基础属性 function HorseSoul_Controller.GetSoulAttrTable(attrId, level, breakLevel) if breakLevel == level then local levelData = DataSheetManager.HorseSoulLevelData:GetDataByHorseSoulLevelAttrID_Level(attrId, level) return DataSheetManager.HorseSoulBreakData:GetDataByBreakType(levelData.BreakType).Attr_Table else return DataSheetManager.HorseSoulLevelData:GetDataByHorseSoulLevelAttrID_Level(attrId, level).Attr_Table end end -- 启魂属性 function HorseSoul_Controller.GetSoulAwakeAttrTable(attrId, star) return DataSheetManager.HorseSoulStarData:GetDataByHorseSoulStarAttrID_Star(attrId, star).Attr_Table end function HorseSoul_Controller.GetSoulNextMaxLevel(soulId) local soulInfo = MDL.HorseSoul.GetSoulInfoById(soulId) local levelInfo = soulInfo.levelInfo local nowLevel = levelInfo.level local breakLevel = levelInfo.breakLevel local nextMaxLevel = nowLevel for i, v in DataSheetManager.HorseSoulLevelData:GetDataByHorseSoulLevelAttrID_Level(soulInfo.soulData.HorseSoulLevelAttrID) do if v.Level >= nowLevel then if v.BreakType > 0 then if breakLevel < v.Level then return v.Level else nextMaxLevel = v.Level end end end end return DataSheetManager.HorseSoulLevelData:GetDataLengthByHorseSoulLevelAttrID_Level(soulInfo.soulData.HorseSoulLevelAttrID) end ---需要全部6个孔位的魂珠都为同一套装id才可解锁技能 ---@param horseId number 战马id ---@return boolean|number 如果为false则为未激活,如果为number则为激活 function HorseSoul_Controller.GetSoulSkillLevel(horseId) local suitId local qualityList = {} --用来存储装备魂珠各个品质的数量,判断技能解锁到几级 local starList = {} --用来存储装备魂珠各个启魂等级的数量,判断技能解锁到几级 local slotInfo = MDL.HorseSoul.GetSoulSlotInfoByHorseId(horseId) if slotInfo then for i, v in ipairs(slotInfo) do if CTL.HorseSoul.JudgeSoulId(v.soulPearl) then local soulInfo = MDL.HorseSoul.GetSoulInfoById(v.soulPearl) local soulData = soulInfo.soulData if suitId then if suitId ~= soulData.HorseSoulSuitID then --只要有一个部位与其他部位的套装Id不同就说明没有激活技能 return false end local itemData = soulInfo.itemData qualityList[itemData.Color] = qualityList[itemData.Color] and qualityList[itemData.Color] + 1 or 1 starList[soulInfo.star] = starList[soulInfo.star] and starList[soulInfo.star] + 1 or 1 else suitId = soulData.HorseSoulSuitID local itemData = soulInfo.itemData qualityList[itemData.Color] = qualityList[itemData.Color] and qualityList[itemData.Color] + 1 or 1 starList[soulInfo.star] = starList[soulInfo.star] and starList[soulInfo.star] + 1 or 1 end else --只要有一个部位没有装备就说明没有激活技能 return false end end end if not suitId then return false end local maxLevel = DataSheetManager.HorseSoulSuitData:GetDataLengthByHorseSoulSuitID_HorseSoulSkillLevel(suitId) local maxQuality, maxStar = 0, 0 for i, soulSuitData in DataSheetManager.HorseSoulSuitData:GetDataByHorseSoulSuitID_HorseSoulSkillLevel(suitId) do if soulSuitData.Soul_Table[1] then if soulSuitData.Soul_Table[1].SoulQuality >= maxQuality then maxQuality = soulSuitData.Soul_Table[1].SoulQuality end end if soulSuitData.SoulStar_Table[1] then if soulSuitData.SoulStar_Table[1].NeedSoulStar >= maxStar then maxStar = soulSuitData.SoulStar_Table[1].NeedSoulStar end end end qualityList[maxQuality] = qualityList[maxQuality] or 0 --防止为空,减少循环里面的判断 for i = maxQuality - 1, 0, -1 do qualityList[i] = qualityList[i] and qualityList[i] + qualityList[i + 1] or qualityList[i + 1] end starList[maxStar] = starList[maxStar] or 0 --防止为空,减少循环里面的判断 for i = maxStar - 1, 0, -1 do starList[i] = starList[i] and starList[i] + starList[i + 1] or starList[i + 1] end local level = 0 local libraryLevel = MDL.HorseLibrary.GetLibraryLevelAndScore() for i, v in DataSheetManager.HorseSoulSuitData:GetDataByHorseSoulSuitID_HorseSoulSkillLevel(suitId) do if libraryLevel >= v.HorseSoulSkillPictorialLevel then for _, soul in ipairs(v.Soul_Table) do if qualityList[soul.SoulQuality] and qualityList[soul.SoulQuality] < soul.SoulNum then return (level ~= 0 and level or false), suitId end end for _, soulStar in ipairs(v.SoulStar_Table) do if starList[soulStar.NeedSoulStar] and starList[soulStar.NeedSoulStar] < soulStar.NeedSoulNum then return (level ~= 0 and level or false), suitId end end level = v.HorseSoulSkillLevel else return (level ~= 0 and level or false), suitId end end return level ~= 0 and level or false, suitId end function HorseSoul_Controller.GetSoulPearlAttrTable(soulId) local soulInfo = MDL.HorseSoul.GetSoulInfoById(soulId) local levelInfo = soulInfo.levelInfo local level = levelInfo.level local levelData = DataSheetManager.HorseSoulLevelData:GetDataByHorseSoulLevelAttrID_Level(soulInfo.soulData.HorseSoulLevelAttrID, level) if not levelData then logging.error(LTAG.ERROR, "魂珠Id为", soulInfo.cfgId, ",HorseSoulLevelData表中没有AttrID为", soulInfo.soulData.HorseSoulLevelAttrID, "Level为", level, "的魂珠等级数据,请策划检查!!!") end local attrList = levelData.Attr_Table local breakType = levelData.BreakType if breakType and breakType > 0 then if levelInfo.breakLevel >= level then attrList = DataSheetManager.HorseSoulBreakData:GetDataByBreakType(breakType).Attr_Table end end return attrList end --没有图鉴加成的魂珠战力 function HorseSoul_Controller.CalculateSoulGs(soulId) local soulInfo = MDL.HorseSoul.GetSoulInfoById(soulId) if soulInfo.star > 0 then return UTL.Attr.CalculateFight(HorseSoul_Controller.GetSoulPearlAttrTable(soulId)) + UTL.Attr.CalculateFight(HorseSoul_Controller.GetSoulAwakeAttrTable(soulInfo.soulData.HorseSoulStarAttrID, soulInfo.star)) else return UTL.Attr.CalculateFight(HorseSoul_Controller.GetSoulPearlAttrTable(soulId)) end end function HorseSoul_Controller.GetTotalNeedExp(soulId) local soulInfo = MDL.HorseSoul.GetSoulInfoById(soulId) local levelInfo = soulInfo.levelInfo local level = levelInfo.level local breakLevel = levelInfo.breakLevel local levelData = DataSheetManager.HorseSoulLevelData:GetDataByHorseSoulLevelAttrID_Level(soulInfo.soulData.HorseSoulLevelAttrID, level) local breakType = levelData.BreakType if (breakType and breakType > 0) and breakLevel < level then --到达突破等级还未突破 return 0 end local needExp = -levelInfo.curExp for i, v in DataSheetManager.HorseSoulLevelData:GetDataByHorseSoulLevelAttrID_Level(soulInfo.soulData.HorseSoulLevelAttrID) do if v.Level >= level + 1 then needExp = needExp + v.LevelEXP end if v.BreakType > 0 and breakLevel < v.Level then --到达突破上限,无法再升级 break end end return needExp end local PurpleQuality = 3 function HorseSoul_Controller.AutoSelectMaterial(soulId) local soulInfo = MDL.HorseSoul.GetSoulInfoById(soulId) local levelInfo = soulInfo.levelInfo local level = levelInfo.level local levelData = DataSheetManager.HorseSoulLevelData:GetDataByHorseSoulLevelAttrID_Level(soulInfo.soulData.HorseSoulLevelAttrID, level) local breakType = levelData.BreakType if (breakType and breakType > 0) and levelInfo.breakLevel < level then --到达突破等级还未突破 return false end local needExp = HorseSoul_Controller.GetTotalNeedExp(soulId) if needExp == 0 then return false end local selectIdList = {} local selectIdDict = {} local generalItemId, generalItemExp = MDL.HorseSoul.GetGeneralMaterialItem() local generalItemCount = UTL.Item.GetItemStockCount(generalItemId) local generalNeed = generalItemCount if generalNeed > 0 then for num = 1, generalItemCount do if generalItemExp * num >= needExp then generalNeed = num break end end table.insert(selectIdList, generalItemId) selectIdDict[generalItemId] = generalNeed if needExp - generalItemExp * generalNeed <= 0 then return true, selectIdList, selectIdDict else needExp = needExp - generalItemExp * generalNeed end end for i, v in ipairs(MDL.HorseSoul.GetSoulMaterialList()) do if not MDL.HorseSoul.JudgeIfEquip(v) and v ~= soulId then local materialSoulInfo = MDL.HorseSoul.GetSoulInfoById(v) if materialSoulInfo.itemData.Color > PurpleQuality then break end selectIdDict[v] = 1 table.insert(selectIdList, v) needExp = needExp - HorseSoul_Controller.GetSoulPearlTotalExp(materialSoulInfo) if needExp <= 0 then break end end end return true, selectIdList, selectIdDict end function HorseSoul_Controller.GetSoulPearlTotalExp(soulInfo) local levelInfo = soulInfo.levelInfo local level = levelInfo.level local exp = levelInfo.curExp + soulInfo.soulData.HorseSoulExp if level > 1 then for i, v in DataSheetManager.HorseSoulLevelData:GetDataByHorseSoulLevelAttrID_Level(soulInfo.soulData.HorseSoulLevelAttrID) do if v.Level <= level then exp = exp + v.LevelEXP else break end end end return exp end function HorseSoul_Controller.SetPositionImage(image, pos) UIUtils.SetImageByAssetBundle(image, HorseSoul_Controller.PositionImage[pos]) end function private.RefreshAvailableExp() private.availableExp = 0 local generalItemId, generalItemExp = MDL.HorseSoul.GetGeneralMaterialItem() local generalItemCount = UTL.Item.GetItemStockCount(generalItemId) private.availableExp = generalItemCount * generalItemExp for i, v in ipairs(MDL.HorseSoul.GetSoulMaterialList()) do if not MDL.HorseSoul.JudgeIfEquip(v) then local materialSoulInfo = MDL.HorseSoul.GetSoulInfoById(v) if materialSoulInfo.itemData.Color > PurpleQuality then break end private.availableExp = private.availableExp + HorseSoul_Controller.GetSoulPearlTotalExp(materialSoulInfo) end end end function HorseSoul_Controller.IsPosCanEquip(pos) for i, v in ipairs(MDL.HorseSoul.GetSoulItemList()) do local soulInfo = MDL.HorseSoul.GetSoulInfoById(v) local soulData = soulInfo.soulData if (not soulInfo.equipHorseId) and soulData.HorseSoulPositionID == pos then return true end end return false end function HorseSoul_Controller.IsHorseCanEquip(horseId) if not MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.HorseSoul) then return false end local horseInfo = MDL.WarHorse.GetInfoByID(horseId) if not horseInfo or not horseInfo.HeroID then return false end local slotInfo = horseInfo.HorseInfo.soulSlotInfos for i = 1, 6 do --只有6个槽位 local soulId = slotInfo[i] and slotInfo[i].soulPearl if string.isNilOrEmpty(soulId) then if HorseSoul_Controller.IsPosCanEquip(i) then return true end end end return false end function HorseSoul_Controller.IsCanEquip() for i, v in ipairs(MDL.Formation.GetSlotHeroIds()) do if MDL.HeroSelect.GetHeroInfo(v) then local horseInfo = MDL.HeroSelect.GetHeroInfo(v).horseInfo if HorseSoul_Controller.IsHorseCanEquip(horseInfo.Id) then return true end end end return false end function HorseSoul_Controller.IsSoulPearlCanUpgrade(soulId) if not HorseSoul_Controller.JudgeSoulId(soulId) then return false end local soulInfo = MDL.HorseSoul.GetSoulInfoById(soulId) local levelInfo = soulInfo.levelInfo local level = levelInfo.level local levelData = DataSheetManager.HorseSoulLevelData:GetDataByHorseSoulLevelAttrID_Level(soulInfo.soulData.HorseSoulLevelAttrID, level) local isSuccess, nextLevelData = DataSheetManager.HorseSoulLevelData:TryGetDataByHorseSoulLevelAttrID_Level(soulInfo.soulData.HorseSoulLevelAttrID, level + 1) if not isSuccess then -- 已升到最大等级 return false end local breakType = levelData.BreakType if (breakType and breakType > 0) and levelInfo.breakLevel < level then --到达突破等级还未突破 local breakData = DataSheetManager.HorseSoulBreakData:GetDataByBreakType(breakType) return UTL.Item.GetItemStockCount(breakData.BreakGeneralItem) >= breakData.UseItemNum else local nextLevelData = DataSheetManager.HorseSoulLevelData:GetDataByHorseSoulLevelAttrID_Level(soulInfo.soulData.HorseSoulLevelAttrID, level + 1) if nextLevelData then return private.availableExp >= nextLevelData.LevelEXP end end return false end function HorseSoul_Controller.IsHorseSoulCanUpgrade(horseId) if not MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.HorseSoul) then return false end local horseInfo = MDL.WarHorse.GetInfoByID(horseId) if not horseInfo or not horseInfo.HeroID then return false end for i, v in ipairs(MDL.HorseSoul.GetSoulSlotInfoByHorseId(horseId)) do if HorseSoul_Controller.IsSoulPearlCanUpgrade(v.soulPearl) then return true end end return false end function HorseSoul_Controller.IsHasSoulCanUpgrade() for i, v in ipairs(MDL.Formation.GetSlotHeroIds()) do if MDL.HeroSelect.GetHeroInfo(v) then local horseInfo = MDL.HeroSelect.GetHeroInfo(v).horseInfo if HorseSoul_Controller.IsHorseSoulCanUpgrade(horseInfo.Id) then return true end end end return false end function HorseSoul_Controller.CheckIfHorseSoulHasRp(horseId) return HorseSoul_Controller.IsHorseSoulCanUpgrade(horseId) or HorseSoul_Controller.IsHorseCanEquip(horseId) end -- 魂珠红点 function HorseSoul_Controller.CheckIfWarHorseSoul() return HorseSoul_Controller.IsHasSoulCanUpgrade() or HorseSoul_Controller.IsCanEquip() end function HorseSoul_Controller.SetStarLevel(group_Star, starLevel) UIUtils.SetActive(group_Star.gameObject, starLevel > 0) if starLevel > 0 then for k,v in ipairs(group_Star) do UIUtils.SetActive(v, k <= starLevel) end end end function HorseSoul_Controller.CalculateHorseSoulGs(horseID) local skillGs = 0 local level, suitId = HorseSoul_Controller.GetSoulSkillLevel(horseID) if level then local skillData = DataSheetManager.HorseSoulSuitData:GetDataByHorseSoulSuitID_HorseSoulSkillLevel(suitId, level) skillGs = skillData.HorseSoulSkillGS end local totalAttrList = {} local soulStarAttrList = {} local slotList = MDL.HorseSoul.GetSoulSlotInfoByHorseId(horseID) for i, v in ipairs(slotList) do if HorseSoul_Controller.JudgeSoulId(v.soulPearl) then UTL.Attr.CombineAttr(totalAttrList, HorseSoul_Controller.GetSoulPearlAttrTable(v.soulPearl)) local soulInfo = MDL.HorseSoul.GetSoulInfoById(v.soulPearl) if soulInfo.star > 0 then UTL.Attr.CombineAttr(soulStarAttrList, HorseSoul_Controller.GetSoulAwakeAttrTable(soulInfo.soulData.HorseSoulStarAttrID, soulInfo.star)) end end end for i, v in ipairs(totalAttrList) do v.AttrNum = v.AttrNum * MDL.HorseSoul.GetHorsePictorialAdd() end private.horseSoulGs[horseID] = skillGs + UTL.Attr.CalculateFight(totalAttrList) + UTL.Attr.CalculateFight(soulStarAttrList) end function HorseSoul_Controller.GetHorseSoulGs(horseID) return private.horseSoulGs[horseID] or 0 end local function SortAttr(a, b) return a.AttrType < b.AttrType end function HorseSoul_Controller.GetHorseSoulAttrs(horseID) local attrList = {} local slotList = MDL.HorseSoul.GetSoulSlotInfoByHorseId(horseID) for i, v in ipairs(slotList) do if CTL.HorseSoul.JudgeSoulId(v.soulPearl) then local soulInfo = MDL.HorseSoul.GetSoulInfoById(v.soulPearl) local levelData = DataSheetManager.HorseSoulLevelData:GetDataByHorseSoulLevelAttrID_Level(soulInfo.soulData.HorseSoulLevelAttrID, soulInfo.levelInfo.level) UTL.Attr.CombineAttr(attrList, levelData.Attr_Table) if soulInfo.star > 0 then UTL.Attr.CombineAttr(attrList, CTL.HorseSoul.GetSoulAwakeAttrTable(soulInfo.soulData.HorseSoulStarAttrID, soulInfo.star)) end end end table.sort(attrList, SortAttr) return attrList, #attrList > 0 end return HorseSoul_Controller