local DivineWeapon_Controller = {} local private = {} local EventSystem = require('Event/EventSystem') DivineWeapon_Controller.ForgeLineType = { Top = 1, Center = 2, Bottom = 3, Rely = 4, Terminal = 5 } DivineWeapon_Controller.ForgePointState = { Lock = 1, Available = 2, Activate = 3 } function DivineWeapon_Controller.OnStartup() CTL.Bag.RegisteEventByItemType(LuaConst.ItemType.WeaponFragment, private.RefreshRedPoint) CTL.Bag.RegisteEventByItemType(LuaConst.ItemType.Appearance, private.RefreshRedPoint) CTL.Bag.RegisteEventByItemType(LuaConst.ItemType.Materials, private.RefreshRedPoint) EventSystem.Regist(EventID.UI_DivineWeapon_ForgeUpdate, private.RefreshRedPoint) EventSystem.Regist(EventID.AcquireSystemRedAfterUnlock, private.RefreshRedPoint) EventSystem.Regist(EventID.UI_HeroBreak_BreakSuccess, private.RefreshRedPoint) EventSystem.Regist(EventID.UI_HeroShow_UpdateHeroShow, private.RefreshRedPoint) EventSystem.Regist(EventID.UI_DivineWeapon_ForgeSoul_Update, private.RefreshRedPoint) EventSystem.Regist(EventID.UI_AssistanceFight_HeroChange, private.RefreshRedPoint) EventSystem.Regist(EventID.UI_HeroFormation_ChangeHero, private.RefreshRedPoint) EventSystem.Regist(EventID.UI_HeroAwaken_UpdateBreakInfo, private.RefreshRedPoint) EventSystem.Regist(EventID.FunctionUnlockUpdate, private.RefreshInfoByFunction) private.forgeDatas = {} -- 初始化锻造配置 for _, v in DataSheetManager.MagicWeaponFoundry:GetEnumerator() do if not private.forgeDatas[v.ID] then private.forgeDatas[v.ID] = { lines = LuaExt.CreateTable(3), relyPointDict = {}, topRelyLines = {}, bottomRelyLines = {}, finalPoint = nil } end local forgeData = private.forgeDatas[v.ID] if v.LineType == DivineWeapon_Controller.ForgeLineType.Rely then if #v.NeedPoint == 2 then local isOnTop = false for _, pointID in ipairs (v.NeedPoint) do if not forgeData.relyPointDict[pointID] then forgeData.relyPointDict[pointID] = {v} else table.insert(forgeData.relyPointDict[pointID], v) end local pointData = DataSheetManager.MagicWeaponFoundry:GetDataByID_PointID(v.ID, pointID) if pointData and pointData.LineType == DivineWeapon_Controller.ForgeLineType.Top then isOnTop = true end end if isOnTop then table.insert(forgeData.topRelyLines, v) else table.insert(forgeData.bottomRelyLines, v) end end elseif v.LineType == DivineWeapon_Controller.ForgeLineType.Terminal then forgeData.finalPoint = v else local lines = forgeData.lines if not lines[v.LineType] then lines[v.LineType] = {} end local singleLine = lines[v.LineType] table.insert(singleLine, v) end end end function DivineWeapon_Controller.OnShutdown() private.forgeDatas = nil end ---@return string 返回一个包含所有属性的字符串 function DivineWeapon_Controller.GetDivineWeaponBreakAttrText(weaponId, weaponStar, numColor) local breakAttrText = "" local starBreakAttrId = DataSheetManager.MagicWeaponStar:GetDataByMagicWeaponID_Star(weaponId, weaponStar).AttrSpecial if starBreakAttrId and starBreakAttrId > 0 then local attrTable = DataSheetManager.MagicWeaponStarAttr:GetDataByAttrRepeatID(starBreakAttrId).Attr_Table for i, v in ipairs(attrTable) do local attrText = UTL.Attr.GetAttrText(v.AttrType, v.AttrNum, numColor) if i == 1 then breakAttrText = attrText else breakAttrText = breakAttrText .. "," .. attrText end end end return breakAttrText end ---@return table 返回属性数组 function DivineWeapon_Controller.GetDivineWeaponBreakAttrTextList(weaponId, weaponStar, numColor) local starBreakAttrId = DataSheetManager.MagicWeaponStar:GetDataByMagicWeaponID_Star(weaponId, weaponStar).AttrSpecial if starBreakAttrId and starBreakAttrId > 0 then local attrTable = DataSheetManager.MagicWeaponStarAttr:GetDataByAttrRepeatID(starBreakAttrId).Attr_Table if attrTable and #attrTable > 0 then local breakAttrText = {} for i, v in ipairs(attrTable) do local attrText = UTL.Attr.GetAttrText(v.AttrType, v.AttrNum, numColor) table.insert(breakAttrText, attrText) end return breakAttrText end end return nil end function private.RefreshRedPoint() CTL.RedPoint.AddOneRedPointFunc(private.RealRefreshRedPoint) end function private.RealRefreshRedPoint() local isRed = false for i,v in ipairs(MDL.DivineWeapon.GetAllData()) do if MDL.Player.HeroIsLineUp(v.MagicWeaponID) and MDL.DivineWeapon.GetEnoughLevel(v) or CTL.Appearance.CanActiveWeaponAppearance(v.MagicWeaponID) or CTL.HeroAwaken.CheckWeaponAwakenRed(v.MagicWeaponID) then CTL.RedPoint.AddRedPoint(CTL.RedPoint.RedPointKey.WeaponBtn_WeaponView_Act) isRed = true break end end if not isRed then CTL.RedPoint.RemoveRedPoint(CTL.RedPoint.RedPointKey.WeaponBtn_WeaponView_Act) end isRed = false local list = MDL.DivineWeapon.GetFormationData() for i,v in ipairs(list) do if CTL.Appearance.CanActiveWeaponAppearance(v.MagicWeaponID) or MDL.Player.HeroIsLineUp(v.MagicWeaponID) then if MDL.DivineWeapon.GetEnoughLevel(v) or CTL.Appearance.IsShowWeaponRedPoint(v.MagicWeaponID) then CTL.RedPoint.AddRedPoint(CTL.RedPoint.RedPointKey.Formation_Weapon) isRed = true elseif MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.DivineWeaponForge) then if DivineWeapon_Controller.HasForgeRP(v.MagicWeaponID) then CTL.RedPoint.AddRedPoint(CTL.RedPoint.RedPointKey.Formation_Weapon) isRed = true end end end end if not isRed then CTL.RedPoint.RemoveRedPoint(CTL.RedPoint.RedPointKey.Formation_Weapon) end isRed = false for i,v in ipairs(MDL.DivineWeapon.GetAllData()) do if MDL.Player.HeroIsLineUp(v.MagicWeaponID) and CTL.Appearance.IsShowWeaponRedPoint(v.MagicWeaponID) then CTL.RedPoint.AddRedPoint(CTL.RedPoint.RedPointKey.WeaponBtn_WeaponView_Appearance) isRed = true break end end if not isRed then CTL.RedPoint.RemoveRedPoint(CTL.RedPoint.RedPointKey.WeaponBtn_WeaponView_Appearance) end isRed = false if MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.DivineWeaponForge) then for i,v in ipairs(MDL.DivineWeapon.GetAllData()) do if MDL.Player.HeroIsLineUp(v.MagicWeaponID) and DivineWeapon_Controller.HasForgeRP(v.MagicWeaponID) then CTL.RedPoint.AddRedPoint(CTL.RedPoint.RedPointKey.WeaponBtn_WeaponView_Forge) isRed = true break end end end if not isRed then CTL.RedPoint.RemoveRedPoint(CTL.RedPoint.RedPointKey.WeaponBtn_WeaponView_Forge) end CTL.DivineWeaponForgeSoul.RefreshDivineWeaponForgeSoulRedPoint() end function DivineWeapon_Controller.IfDivineWeaponCanUpgrade(heroId) local data = DataSheetManager.MagicWeaponData:GetDataByMagicWeaponID(heroId) return MDL.DivineWeapon.GetEnoughLevel(data) or CTL.Appearance.IsShowWeaponRedPoint(data.MagicWeaponID) or CTL.DivineWeapon.HasForgeRP(data.MagicWeaponID) or CTL.HeroAwaken.CheckWeaponAwakenRed(data.MagicWeaponID) or CTL.HeroAwaken.CheckWeaponSkillRed(data.MagicWeaponID) end function DivineWeapon_Controller.IsMaxMusouLevel(divineWeaponId) local heroInfo = MDL.HeroSelect.GetHeroInfo(divineWeaponId) local isUnlock = heroInfo and heroInfo.isMagicWeaponActive or false local starLevel = isUnlock and heroInfo.magicWeaponLevel or 0 local curMusouLevel local maxMusouLevel = 0 for i, v in DataSheetManager.MagicWeaponStar:GetDataByMagicWeaponID_Star(divineWeaponId) do if starLevel == v.Star then curMusouLevel = v.MusouLevel end maxMusouLevel = v.MusouLevel end return curMusouLevel == maxMusouLevel end --开关玩法时执行 function private.RefreshInfoByFunction(funcId, isUnlock) if funcId == MDL.Unlock.FunctionType.Weapon then if not isUnlock then private.EndAndCloseDivineWeapon() end end end function private.EndAndCloseDivineWeapon() logging.log(LTAG.LOG, "EndAndCloseDivineWeapon") UIManager.CloseView(Const_UI_Lua.UIEnum.UICommonNoteView) UIManager.CloseView(Const_UI_Lua.UIEnum.UIResonanceInfo) UIManager.CloseView(Const_UI_Lua.UIEnum.UIDivineWeaponBreak) UIManager.CloseView(Const_UI_Lua.UIEnum.UIDivineWeaponAwaken) UIManager.CloseView(Const_UI_Lua.UIEnum.UIDivineWeaponBreakInfoView) UIManager.CloseView(Const_UI_Lua.UIEnum.UIDivineWeaponSkillTips) UIManager.CloseView(Const_UI_Lua.UIEnum.UIDivineWeaponAppearance) UIManager.CloseView(Const_UI_Lua.UIEnum.UIPreviewItemTips) EventSystem.Dispatch(EventID.UI_DivineWeapon_OnCloseGamePlay) end function DivineWeapon_Controller.GetLineDataByID(id) if not id or not private.forgeDatas[id] then return nil, 0 end local lines = private.forgeDatas[id].lines local maxLineCount = lines[1] and #lines[1] or 0 maxLineCount = (lines[2] and #lines[2] > maxLineCount) and #lines[2] or maxLineCount maxLineCount = (lines[3] and #lines[3] > maxLineCount) and #lines[3] or maxLineCount return lines, maxLineCount, private.forgeDatas[id].topRelyLines, private.forgeDatas[id].bottomRelyLines end function DivineWeapon_Controller.GetRelyPointDicts(pointData) if pointData then local forgeDatas = private.forgeDatas[pointData.ID] if forgeDatas and forgeDatas.relyPointDict and forgeDatas.relyPointDict[pointData.PointID] then return forgeDatas.relyPointDict[pointData.PointID] end end return nil end function DivineWeapon_Controller.GetLineSkillBaseIDAndSkillLevel(pointData) if pointData then local skillID = DivineWeapon_Controller.MagicWeaponFoundryShowID(pointData) local _, skillData = DataSheetManager.SkillTipsData:TryGetDataByID(skillID) if skillData then local lines = DivineWeapon_Controller.GetLineDataByID(pointData.ID) if lines and lines[pointData.LineType] and #lines[pointData.LineType] > 0 then local baseSkillID = DivineWeapon_Controller.MagicWeaponFoundryShowID(lines[pointData.LineType][1]) local skillNextData = DataSheetManager.SkillTipsData:GetDataByID(baseSkillID) local level = 1 while (skillNextData ~= nil) do if skillNextData.ID == skillID then break end local _, nextData = DataSheetManager.SkillTipsData:TryGetDataByID(skillNextData.NextDisplaySkill) skillNextData = nextData level = level + 1 end return baseSkillID, level end end end return 0, 0 end function DivineWeapon_Controller.GetLineSkillCurSkillIdAndCurLevel(heroId, pointData, inputSkillId) if pointData then local lines = DivineWeapon_Controller.GetLineDataByID(pointData.ID) if lines and lines[pointData.LineType] and #lines[pointData.LineType] > 0 then local skillNextData = DataSheetManager.SkillTipsData:GetDataByID(inputSkillId) local curLevel = 0 local curSkillId = inputSkillId while (skillNextData ~= nil) do local curPointData = skillNextData.LevelUpTypeParam>0 and DataSheetManager.MagicWeaponFoundry:GetDataByID_PointID(pointData.ID, skillNextData.LevelUpTypeParam) or nil if curPointData then if skillNextData.LevelUpTypeParam ~= 0 and DivineWeapon_Controller.GetPointState(heroId, curPointData) ~= CTL.DivineWeapon.ForgePointState.Activate then break end end curLevel = curLevel + 1 skillNextData = skillNextData.NextDisplaySkill>0 and DataSheetManager.SkillTipsData:GetDataByID(skillNextData.NextDisplaySkill) or nil if not skillNextData then break end curSkillId = skillNextData.ID end return curSkillId, curLevel end end return 0 end function DivineWeapon_Controller.MagicWeaponFoundryShowID(pointData) if not pointData.MagicWeaponFoundryShowID or #pointData.MagicWeaponFoundryShowID == 0 then return pointData.SkillShowID[1] --没配专门的展示技能,就取原先的技能数据,一般有且只有一个 else return pointData.MagicWeaponFoundryShowID[1] --目前只用第一个,以后要扩展再说 end end function DivineWeapon_Controller.GetPointDataByID_Index(id, index) local lines = DivineWeapon_Controller.GetLineDataByID(id) if lines then local point1 = lines[1] and lines[1][index] or nil local point2 = lines[2] and lines[2][index] or nil local point3 = lines[3] and lines[3][index] or nil return point1, point2, point3 end return nil, nil, nil end function DivineWeapon_Controller.GetPointState(heroId, pointData) if not heroId or not pointData then return DivineWeapon_Controller.ForgePointState.Lock end for _, v in ipairs (pointData.NeedPoint) do local relyPointData = DataSheetManager.MagicWeaponFoundry:GetDataByID_PointID(pointData.ID, v) local relyPointState = DivineWeapon_Controller.GetPointState(heroId, relyPointData) if relyPointState ~= DivineWeapon_Controller.ForgePointState.Activate then return DivineWeapon_Controller.ForgePointState.Lock end end if pointData.LineType == DivineWeapon_Controller.ForgeLineType.Rely then return DivineWeapon_Controller.ForgePointState.Activate end local isTriggerComplete = pointData.triggerID == 0 or MDL.Unlock.IsTriggerIdComplete(pointData.triggerID) if not isTriggerComplete then return DivineWeapon_Controller.ForgePointState.Lock end if pointData.LineType ~= DivineWeapon_Controller.ForgeLineType.Rely and pointData.LineType ~= DivineWeapon_Controller.ForgeLineType.Terminal then local maxLinePointID = MDL.DivineWeapon.GetForgeLineMaxActivatePointID(heroId, pointData.LineType) if pointData.PointID > maxLinePointID then local itemRepeatData = DataSheetManager.MagicWeaponFoundryItemRepeat:GetDataByItemRepeatID(pointData.ItemRepeat) if itemRepeatData and #itemRepeatData.Item_Table > 0 then for _, itemData in ipairs (itemRepeatData.Item_Table) do if UTL.Item.GetItemStockCount(itemData.ItemID) < itemData.ItemNum then return DivineWeapon_Controller.ForgePointState.Lock end end end return DivineWeapon_Controller.ForgePointState.Available end end return DivineWeapon_Controller.ForgePointState.Activate end function DivineWeapon_Controller.GetForgeTemplateID(heroId) if not heroId then return 0 end local templateID = 0 local heroInfo = MDL.HeroSelect.GetHeroInfo(heroId) if heroInfo then local curAttrWeaponAppearanceId = heroInfo.curAttrWeaponAppearanceId if curAttrWeaponAppearanceId > 0 and curAttrWeaponAppearanceId ~= heroId then local appearanceData = DataSheetManager.WeaponAppearance:GetDataByID(curAttrWeaponAppearanceId) templateID = appearanceData and appearanceData.MagicWeaponFoundry or 0 else local magicData = DataSheetManager.MagicWeaponData:GetDataByMagicWeaponID(heroId) templateID = magicData and magicData.MagicWeaponFoundry or 0 end end return templateID end function DivineWeapon_Controller.HasForgeRP(heroId) if not MDL.Unlock.IsUnlock(MDL.Unlock.FunctionType.DivineWeaponForge) then return false end if CTL.DivineWeaponForgeSoul.GetIsShowRedpoint(heroId) then return true end --只有上阵武将和助战武将才给红点提示 if MDL.Formation.GetSlotIndexByHeroId(heroId) == nil and MDL.AssistanceFight.IsHeroOnAssistancePos(heroId) == false then return false end return private.HasForgeLineRP(heroId, DivineWeapon_Controller.ForgeLineType.Top) or private.HasForgeLineRP(heroId, DivineWeapon_Controller.ForgeLineType.Center) or private.HasForgeLineRP(heroId, DivineWeapon_Controller.ForgeLineType.Bottom) end function private.HasForgeLineRP(heroId, lineType) local magicData = DataSheetManager.MagicWeaponData:GetDataByMagicWeaponID(heroId) local templateID = DivineWeapon_Controller.GetForgeTemplateID(heroId) if templateID ~= 0 and lineType then local pointID = MDL.DivineWeapon.GetForgeLineMaxActivatePointID(heroId, lineType) if pointID == 0 then local lines = CTL.DivineWeapon.GetLineDataByID(templateID) if not lines or not lines[lineType] then return false end local points = lines[lineType] if not points[1] then return false end pointID = points[1].PointID else pointID = pointID + 1 end local _, nextPointData = DataSheetManager.MagicWeaponFoundry:TryGetDataByID_PointID(templateID, pointID) if not nextPointData then return false end return DivineWeapon_Controller.GetPointState(heroId, nextPointData) == CTL.DivineWeapon.ForgePointState.Available end return false end --获取同一条线上的下一个点 function DivineWeapon_Controller.GetNextPointData(templateID, lastPointData) local lastLineType = lastPointData.LineType local hasFind = false for i,v in DataSheetManager.MagicWeaponFoundry:GetDataByID_PointID(templateID) do if hasFind then if v.LineType == lastLineType then return v end break end if v.PointID == lastPointData.PointID then hasFind = true end end return nil end -- 判断所有锻铸是否全部激活 function DivineWeapon_Controller.IsDivineWeaponForgeMax(magicWeaponID) -- 历史原因 heroId 和 magicWeaponID 相同 local templateID = CTL.DivineWeapon.GetForgeTemplateID(magicWeaponID) local lines = CTL.DivineWeapon.GetLineDataByID(templateID) if lines == nil then -- 为被激活 return false end for _, line in ipairs(lines) do for _, pointData in ipairs(line) do if CTL.DivineWeapon.GetPointState(magicWeaponID, pointData) ~= DivineWeapon_Controller.ForgePointState.Activate then return false end end end return true end -- 是否激活到最大等级 function DivineWeapon_Controller.IsWeaponReachMaxStar(weaponId) local heroInfo = MDL.HeroSelect.GetHeroInfo(weaponId) local weaponLevel = heroInfo.magicWeaponLevel or 0 local weaponStar = (heroInfo.magicWeaponStar or 0) + 1 local heroBreakLevel = heroInfo.starLevel local isMax = weaponLevel == MDL.DivineWeapon.GetBreakMax(weaponId) return isMax or (weaponStar == MDL.DivineWeapon.STARMAX and heroBreakLevel == weaponLevel) or heroBreakLevel < weaponLevel end -- 神兵模型资源是否加载完成 function DivineWeapon_Controller.IsDivineWeaponAssetAllLoaded(weaponId, weaponAppearanceId) local magicWeaponData = nil if weaponAppearanceId and weaponAppearanceId>0 then magicWeaponData = DataSheetManager.MagicWeaponStar:GetDataByMagicWeaponID_Star(weaponAppearanceId, 15) else magicWeaponData = DataSheetManager.MagicWeaponData:GetDataByMagicWeaponID(weaponId) end return DivineWeapon_Controller.IsDivineWeaponAssetAllLoadedByModelId(magicWeaponData.PreviewModel) end function DivineWeapon_Controller.IsDivineWeaponAssetAllLoadedByModelId(magicWeaponModelId) local weaponModelData = DataSheetManager.MagicWeaponModel:GetDataByID(magicWeaponModelId) for i, v in ipairs(weaponModelData.ModelPart_Table) do if CTL.HotFix.CanAssetLoad(v.Prefeb) == false then return false end end return true end function DivineWeapon_Controller.GetWeaponIntelligence(weaponId) local awakenExtra = CTL.HeroAwaken.GetWeaponExtraIntelligence(weaponId) local appearanceId = MDL.HeroSelect.GetAttrWeaponAppearanceIDByHeroID(weaponId) local weaponData = MDL.Appearance.GetAppearanceDataByHeroID_AppearanceID(weaponId, appearanceId, MDL.Appearance.AppearanceType.Weapon) return weaponData.appearanceConfig.MagicWeaponTalent + awakenExtra end return DivineWeapon_Controller