local BaseCtrl = require("GameCore.UI.BaseCtrl") local CharFavourLevelUpCtrl = class("CharFavourLevelUpCtrl", BaseCtrl) local Actor2DManager = require("Game.Actor2D.Actor2DManager") local WwiseAudioMgr = CS.WwiseAudioManager.Instance local GridHeight = 51 local LayoutRebuilder = CS.UnityEngine.UI.LayoutRebuilder CharFavourLevelUpCtrl._mapNodeConfig = { trActor2D_PNG = { sNodeName = "----Actor2D_PNG----", sComponentName = "Transform" }, aniActor2D_PNG = { sNodeName = "----Actor2D_PNG----", sComponentName = "Animator" }, got_fullscreen_blur_black = { sNodeName = "t_fullscreen_blur_black", sComponentName = "GameObject" }, btnsnapshot = { sNodeName = "snapshot", sComponentName = "Button", callback = "OnBtn_ClickClose" }, rtBg = { sNodeName = "goBg", sComponentName = "RectTransform" }, goLevelUp = {}, loopAdPre = { sNodeName = "AdPre", sComponentName = "LoopScrollView" }, affinityLevel = { sCtrlName = "Game.UI.TemplateEx.TemplateAffinityLevelCtrl" }, affinityLevelBefore = { sCtrlName = "Game.UI.TemplateEx.TemplateAffinityLevelCtrl" }, trContent = { sNodeName = "--Content--", sComponentName = "RectTransform" }, btnSkipAnim = { sNodeName = "btnSkipAnim", sComponentName = "UIButton", callback = "OnBtn_SkipAnim" }, aniSafeRoot = { sNodeName = "----SafeRoot----", sComponentName = "Animator" }, goSafeRoot = { sNodeName = "----SafeRoot----", sComponentName = "GameObject" }, goNormal = {}, affinityLevelNormal = { sCtrlName = "Game.UI.TemplateEx.TemplateAffinityLevelCtrl" }, rectProgress = { sNodeName = "imgProgress", sComponentName = "RectTransform" }, rectPreProgress = { sNodeName = "imgPreProgress", sComponentName = "RectTransform" }, txtProgress = { sNodeName = "txtProgress", sComponentName = "TMP_Text" }, txtCalHeight = {nCount = 2, sComponentName = "TMP_Text"}, rtCalHeight = { nCount = 2, sNodeName = "txtCalHeight", sComponentName = "RectTransform" } } CharFavourLevelUpCtrl._mapEventConfig = {} function CharFavourLevelUpCtrl:Awake() local tbParam = self:GetPanelParam() if type(tbParam[1]) == "table" then self.tbLevelUpList = tbParam[1] else self.curCharId = tbParam[1] self.curFavourLevel = tbParam[2] self.lastFavourLevel = tbParam[3] self.curExp = tbParam[4] self.lastExp = tbParam[5] if tbParam[6] ~= nil then self.CloseCallBack = tbParam[6] end end EventManager.Hit(EventId.HideCharBgActor) self.progressBarWidth = 552 self.progressBarMinWidth = 0 self._mapNode.goLevelUp.gameObject:SetActive(false) self._mapNode.goNormal.gameObject:SetActive(false) self._mapNode.rectPreProgress.sizeDelta = Vector2(0, self._mapNode.rectPreProgress.sizeDelta.y) end function CharFavourLevelUpCtrl:OnEnable() self._mapNode.got_fullscreen_blur_black:SetActive(true) self:RefreshPanel() if self.lastFavourLevel < self.curFavourLevel then PlayerData.Voice:PlayCharFavourUpVoice(self.curCharId, self.lastFavourLevel) end end function CharFavourLevelUpCtrl:RefreshPanel() if self.tbLevelUpList ~= nil and #self.tbLevelUpList > 0 then local data = table.remove(self.tbLevelUpList, 1) self.curCharId = data.charID self.curFavourLevel = data.curLevel self.lastFavourLevel = data.lastLevel self.curExp = data.curExp self.lastExp = data.lastExp end self._mapNode.aniSafeRoot.speed = 1 self._mapNode.aniActor2D_PNG.speed = 1 self._mapNode.goSafeRoot:SetActive(true) CS.WwiseAudioManager.Instance:PostEvent("ui_charInfo_favour_up") local nSkinId = ConfigTable.GetData_Character(self.curCharId).DefaultSkinId self.DefaultHeight = self._mapNode.trContent.sizeDelta.y self._mapNode.aniSafeRoot:Play("CharFavourLevelUpPanel_in") local nAnimLen = NovaAPI.GetAnimClipLength(self._mapNode.aniSafeRoot, { "CharFavourLevelUpPanel_in" }) self.delayRefresh = self:AddTimer(1, nAnimLen, "Refresh", true, true, true) PlayerData.Char:ChangeShowAffinityLevelUpState(self.curCharId) local wait = function() coroutine.yield(CS.UnityEngine.WaitForEndOfFrame()) Actor2DManager.SetActor2D_PNG(self._mapNode.trActor2D_PNG, self:GetPanelId(), self.curCharId, nSkinId) self._mapNode.aniActor2D_PNG:Play("Actor2D_PNG_CharFavour") end cs_coroutine.start(wait) self.tbAttributeList = {} self.tbRewardList = {} self.tbDescList = {} self.tbAllList = {} local templateId = ConfigTable.GetData("CharAffinityTemplate", self.curCharId).TemplateId local nMaxAffinityLevel = PlayerData.Char:GetMaxAffinityLevel(templateId) self._mapNode.affinityLevelNormal:SetInfo(self.lastFavourLevel) local lastData = CacheTable.GetData("_AffinityLevel", templateId)[nMaxAffinityLevel < self.lastFavourLevel + 1 and nMaxAffinityLevel or self.lastFavourLevel + 1] local nLastPercent if nMaxAffinityLevel <= self.lastFavourLevel then nLastPercent = 1 else nLastPercent = self.lastExp / lastData.NeedExp end local sizeDelta = self._mapNode.rectProgress.sizeDelta sizeDelta.x = self.progressBarWidth * nLastPercent < self.progressBarMinWidth and self.progressBarMinWidth or self.progressBarWidth * nLastPercent self._mapNode.rectProgress.sizeDelta = sizeDelta NovaAPI.SetTMPText(self._mapNode.txtProgress, string.format("%d/%d", self.lastExp, lastData.NeedExp)) if self.curFavourLevel == self.lastFavourLevel then local preData = CacheTable.GetData("_AffinityLevel", templateId)[nMaxAffinityLevel < self.curFavourLevel + 1 and nMaxAffinityLevel or self.curFavourLevel + 1] local nPrePercent = self.curExp / preData.NeedExp local nWidth = self.progressBarWidth * nPrePercent < self.progressBarMinWidth and self.progressBarMinWidth or self.progressBarWidth * nPrePercent self._mapNode.rectPreProgress.sizeDelta = Vector2(nWidth, sizeDelta.y) else self._mapNode.rectPreProgress.sizeDelta = Vector2(self.progressBarWidth, sizeDelta.y) self:RefreshAllDataList() local count = self:GetAllListCount() if 1 < count then local heightCount = 3 < count and 3 or count self._mapNode.trContent.sizeDelta = Vector2(self._mapNode.trContent.sizeDelta.x, self.DefaultHeight + (heightCount - 1) * GridHeight) end end end function CharFavourLevelUpCtrl:CalTextHeight(sContent, nIndex) NovaAPI.SetTMPText(self._mapNode.txtCalHeight[nIndex], sContent) LayoutRebuilder.ForceRebuildLayoutImmediate(self._mapNode.rtCalHeight[nIndex]) return self._mapNode.rtCalHeight[nIndex].rect.height end function CharFavourLevelUpCtrl:Refresh() local templateId = ConfigTable.GetData("CharAffinityTemplate", self.curCharId).TemplateId local nMaxAffinityLevel = PlayerData.Char:GetMaxAffinityLevel(templateId) local nAniTime = 0.2 if self.curFavourLevel - self.lastFavourLevel < 6 then nAniTime = 0.2 elseif self.curFavourLevel - self.lastFavourLevel >= 6 then nAniTime = 0.1 end local nBeforeMaxExp = CacheTable.GetData("_AffinityLevel", templateId)[nMaxAffinityLevel < self.lastFavourLevel + 1 and nMaxAffinityLevel or self.lastFavourLevel + 1].NeedExp local nMaxExp = CacheTable.GetData("_AffinityLevel", templateId)[nMaxAffinityLevel < self.curFavourLevel + 1 and nMaxAffinityLevel or self.curFavourLevel + 1].NeedExp local nBeforeToMaxTime = nAniTime * (1 - self.lastExp / nBeforeMaxExp) local nBeforeToAfterTime = nAniTime * ((self.curExp - self.lastExp) / nMaxExp) local nZeroToAfterTime = nAniTime * self.curExp / nMaxExp local nAddCount = self.curFavourLevel - self.lastFavourLevel local sizeDelta = self._mapNode.rectProgress.sizeDelta local nAllTime = 0 local sequence = DOTween.Sequence() for i = self.lastFavourLevel, self.curFavourLevel - 1 do local nTime = i == 1 and nBeforeToMaxTime or nAniTime nAllTime = nAllTime + nTime sequence:AppendCallback(function() WwiseAudioMgr:PlaySound("ui_common_levelUp") end) sequence:Append(self._mapNode.rectProgress:DOSizeDelta(Vector2(self.progressBarWidth, sizeDelta.y), nTime)) sequence:AppendCallback(function() local data = CacheTable.GetData("_AffinityLevel", templateId)[i + 1 > nMaxAffinityLevel and nMaxAffinityLevel or i + 1] NovaAPI.SetTMPText(self._mapNode.txtProgress, string.format("%d/%d", data.NeedExp, data.NeedExp)) self._mapNode.affinityLevelNormal:SetInfo(i + 1) self._mapNode.rectPreProgress.sizeDelta = Vector2(self.progressBarWidth, sizeDelta.y) self._mapNode.rectProgress.sizeDelta = Vector2(0, sizeDelta.y) end) end sequence:AppendCallback(function() local data = CacheTable.GetData("_AffinityLevel", templateId)[self.curFavourLevel + 1 > nMaxAffinityLevel and nMaxAffinityLevel or self.curFavourLevel + 1] NovaAPI.SetTMPText(self._mapNode.txtProgress, string.format("%d/%d", self.curExp, data.NeedExp)) end) if self.curFavourLevel == nMaxAffinityLevel then local nTime = 1 < nAddCount and nAniTime or nBeforeToMaxTime nAllTime = nAllTime + nTime sequence:Append(self._mapNode.rectProgress:DOSizeDelta(Vector2(self.progressBarWidth, sizeDelta.y), nTime)) elseif self.curExp > 0 then local nTime = 1 < nAddCount and nZeroToAfterTime or nBeforeToAfterTime nAllTime = nAllTime + nTime sequence:AppendCallback(function() local preData = CacheTable.GetData("_AffinityLevel", templateId)[self.curFavourLevel + 1 > nMaxAffinityLevel and nMaxAffinityLevel or self.curFavourLevel + 1] local nPrePercent = self.curExp / preData.NeedExp local nWidth = self.progressBarWidth * nPrePercent < self.progressBarMinWidth and self.progressBarMinWidth or self.progressBarWidth * nPrePercent self._mapNode.rectPreProgress.sizeDelta = Vector2(nWidth, sizeDelta.y) end) local width = self.progressBarWidth * self.curExp / nMaxExp sequence:Append(self._mapNode.rectProgress:DOSizeDelta(Vector2(width, sizeDelta.y), nTime)) elseif self.curExp == 0 then local nTime = 1 < nAddCount and nAniTime or nBeforeToMaxTime nAllTime = nAllTime + nTime self._mapNode.rectPreProgress.sizeDelta = Vector2(0, sizeDelta.y) sequence:Append(self._mapNode.rectProgress:DOSizeDelta(Vector2(self.progressBarWidth, sizeDelta.y), nTime)) sequence:AppendCallback(function() self._mapNode.rectProgress.sizeDelta = Vector2(0, sizeDelta.y) end) end sequence:AppendInterval(0.05) sequence:AppendCallback(function() if self.curFavourLevel ~= self.lastFavourLevel then self._mapNode.aniSafeRoot:Play("CharFavourLevelUpPanel_up") end local count = self:GetAllListCount() self._mapNode.loopAdPre.gameObject:SetActive(true) if 0 < count then self.tbGridHeight = {} for _, v in ipairs(self.tbAllList) do local nHeight1, nHeight2 = 0 if v.rewardType == "Desc" then nHeight1 = self:CalTextHeight(v.rewardData.sFront, 1) nHeight2 = self:CalTextHeight(v.rewardData.sAfter, 2) elseif v.rewardType == "Attribute" then nHeight1 = self:CalTextHeight(ConfigTable.GetUIText("Attribute_Up"), 1) local descData = ConfigTable.GetData("EffectDesc", v.rewardData[1]) local addTxt = FormatEffectValue(v.rewardData[2], descData.isPercent, descData.Format) nHeight2 = self:CalTextHeight(descData.Desc .. " +" .. addTxt, 2) end local nHeight = math.max(nHeight1, nHeight2) + 15 table.insert(self.tbGridHeight, nHeight) end self._mapNode.loopAdPre:SetAnim(0.07) self._mapNode.loopAdPre:InitEx(self.tbGridHeight, self, self.RefreshPreAdvanceBuffsGridItem) else self._mapNode.loopAdPre.gameObject:SetActive(false) end self._mapNode.affinityLevel:SetInfo(self.curFavourLevel) self._mapNode.affinityLevelBefore:SetInfo(self.lastFavourLevel) end) sequence:SetUpdate(true) self._mapNode.btnSkipAnim.gameObject:SetActive(false) EventManager.Hit(EventId.TemporaryBlockInput, nAllTime) end function CharFavourLevelUpCtrl:RefreshPreAdvanceBuffsGridItem(go) local index = tonumber(go.name) + 1 local data = self:GetGridData(index) go = go.transform:Find("AnimRoot") local goReward = go.transform:Find("goReward") local goDesc = go.transform:Find("goDesc") local imgLine = go.transform:Find("imgLine") imgLine.gameObject:SetActive(1 < index) goReward.gameObject:SetActive(data.rewardType == "Reward") goDesc.gameObject:SetActive(data.rewardType ~= "Reward") if data.rewardType == "Reward" then local goContent = goReward:Find("goTxtContent") local imgRewardIcon = goContent:Find("goImgReward/imgReward"):GetComponent("Image") local item = ConfigTable.GetData_Item(data.rewardData[1]) self:SetPngSprite(imgRewardIcon, item.Icon2) local txtReward = goContent:Find("txtReward"):GetComponent("TMP_Text") NovaAPI.SetTMPText(txtReward, data.rewardData[2]) else local goImgLock = goDesc:Find("imgLock") local goImgAttribute = goDesc:Find("imgAttribute") goImgLock.gameObject:SetActive(data.rewardType == "Desc") goImgAttribute.gameObject:SetActive(data.rewardType == "Attribute") local txtFront = goDesc:Find("txtFront"):GetComponent("TMP_Text") local txtAfter = goDesc:Find("txtAfter"):GetComponent("TMP_Text") if data.rewardType == "Desc" then NovaAPI.SetTMPText(txtFront, data.rewardData.sFront) NovaAPI.SetTMPText(txtAfter, data.rewardData.sAfter) else NovaAPI.SetTMPText(txtFront, ConfigTable.GetUIText("Attribute_Up")) local descData = ConfigTable.GetData("EffectDesc", data.rewardData[1]) local addTxt = FormatEffectValue(data.rewardData[2], descData.isPercent, descData.Format) NovaAPI.SetTMPText(txtAfter, descData.Desc .. " +" .. addTxt) end end end function CharFavourLevelUpCtrl:RefreshAllDataList() local templateId = ConfigTable.GetData("CharAffinityTemplate", self.curCharId).TemplateId local lastEffectData = {} local curEffectData = {} local forEachAffinityLevelReward = function(mapData) if mapData.TemplateId == templateId then if mapData.AffinityLevel == self.lastFavourLevel then lastEffectData = mapData.Effect end if mapData.AffinityLevel == self.curFavourLevel then curEffectData = mapData.Effect end end end ForEachTableLine(DataTable.AffinityLevel, forEachAffinityLevelReward) self:RefreshAttributeList(lastEffectData, curEffectData) local forEachAffinityUpReward = function(mapData) if mapData.CharId == self.curCharId and mapData.RewardLevel > self.lastFavourLevel and mapData.RewardLevel <= self.curFavourLevel then self:RefreshRewardList(mapData) end end ForEachTableLine(DataTable.AffinityUpReward, forEachAffinityUpReward) table.sort(self.tbDescList, function(a, b) if a.nId == b.nId then return a.nIndex < b.nIndex end return a.nId < b.nId end) for k, v in ipairs(self.tbDescList) do table.insert(self.tbAllList, { rewardType = "Desc", rewardData = self.tbDescList[k] }) end for k, v in pairs(self.tbAttributeList) do table.insert(self.tbAllList, { rewardType = "Attribute", rewardData = {k, v} }) end for k, v in pairs(self.tbRewardList) do table.insert(self.tbAllList, { rewardType = "Reward", rewardData = {k, v} }) end end function CharFavourLevelUpCtrl:RefreshRewardList(rewardData) local index = 1 while rewardData ~= nil and (rewardData["DescFront" .. index] ~= nil or rewardData["Reward" .. index] ~= nil) do if rewardData["DescFront" .. index] ~= nil and rewardData["DescFront" .. index] ~= "" then table.insert(self.tbDescList, { nId = rewardData.Id, nIndex = index, sFront = rewardData["DescFront" .. index], sAfter = rewardData["DescAfter" .. index] }) end index = index + 1 end end function CharFavourLevelUpCtrl:GetAllListCount() local count = 0 count = count + #self.tbDescList for k, v in pairs(self.tbAttributeList) do count = count + 1 end for k, v in pairs(self.tbRewardList) do count = count + 1 end return count end function CharFavourLevelUpCtrl:GetGridData(index) local count = 0 if index <= #self.tbDescList then return { rewardType = "Desc", rewardData = self.tbDescList[index] } end index = index - #self.tbDescList for k, v in pairs(self.tbAttributeList) do index = index - 1 if index == 0 then return { rewardType = "Attribute", rewardData = {k, v} } end end for k, v in pairs(self.tbRewardList) do index = index - 1 if index == 0 then return { rewardType = "Reward", rewardData = {k, v} } end end end function CharFavourLevelUpCtrl:RefreshAttributeList(levelDataBefore, levelDataAfter) local tbBeforeValue = {} local tbAfterValue = {} if levelDataBefore ~= nil then for i = 1, #levelDataBefore do local effectData = ConfigTable.GetData("EffectValue", levelDataBefore[i]) local descId = self:GetEffectDescId(effectData.EffectTypeFirstSubtype, effectData.EffectTypeSecondSubtype) if tbBeforeValue[descId] ~= nil then tbBeforeValue[descId] = tbBeforeValue[descId] + effectData.EffectTypeParam1 else tbBeforeValue[descId] = effectData.EffectTypeParam1 end end end if levelDataAfter ~= nil then for i = 1, #levelDataAfter do local effectData = ConfigTable.GetData("EffectValue", levelDataAfter[i]) local descId = self:GetEffectDescId(effectData.EffectTypeFirstSubtype, effectData.EffectTypeSecondSubtype) if tbAfterValue[descId] ~= nil then tbAfterValue[descId] = tbAfterValue[descId] + effectData.EffectTypeParam1 else tbAfterValue[descId] = effectData.EffectTypeParam1 end end end for k, v in pairs(tbAfterValue) do if tbBeforeValue[k] ~= nil then local beforeValue = tonumber(tbBeforeValue[k]) local afterValue = tonumber(v) if beforeValue < afterValue then self.tbAttributeList[k] = afterValue - beforeValue end else self.tbAttributeList[k] = v end end end function CharFavourLevelUpCtrl:GetEffectDescId(attributeType, numType) return GameEnum.effectType.ATTR_FIX * 10000 + attributeType * 10 + numType end function CharFavourLevelUpCtrl:OnBtn_SkipAnim() self._mapNode.aniSafeRoot.speed = 1000 self._mapNode.aniActor2D_PNG.speed = 1000 if self.delayRefresh ~= nil then self.delayRefresh:Cancel() self.delayRefresh = nil end self:Refresh() end function CharFavourLevelUpCtrl:OnBtn_ClickClose() PlayerData.Char:ChangeShowAffinityLevelUpState(self.curCharId) if self.tbLevelUpList ~= nil and #self.tbLevelUpList > 0 then self._mapNode.goSafeRoot:SetActive(false) self._mapNode.loopAdPre.gameObject:SetActive(false) self:RefreshPanel() return end EventManager.Hit(EventId.RevertCharBgActor) if self.CloseCallBack ~= nil then self.CloseCallBack() end EventManager.Hit(EventId.ClosePanel, PanelId.CharFavourLevelUp) PlayerData.Phone:CheckNewChat() end return CharFavourLevelUpCtrl