Files
StellaSora_DataLua/lua/game/ui/mall/mallrecommendctrl.lua
T
SL1900 e0549005e1 Update - 1.9.0.103
EN: 1.9.0.103
CN: 1.9.0.104
JP: 1.9.0.106
KR: 1.9.0.108
2026-04-18 00:15:00 +09:00

407 lines
14 KiB
Lua

local MallRecommendCtrl = class("MallRecommendCtrl", BaseCtrl)
local TimerManager = require("GameCore.Timer.TimerManager")
local nBannerInterval = 5
MallRecommendCtrl._mapNodeConfig = {
goBanner = {},
goBannerList = {
sComponentName = "RectTransform"
},
btnBanner = {
sNodeName = "goBannerList",
sComponentName = "UIButton",
callback = "OnBtnClick_Banner"
},
eventActBannerDrag = {
sNodeName = "goBannerList",
sComponentName = "UIDrag",
callback = "OnDrag_Banner"
},
BannerItem = {
nCount = 3,
sComponentName = "RectTransform"
},
imgBanner = {nCount = 3, sComponentName = "Image"},
goBannerDot = {
sComponentName = "RectTransform"
},
imgPointBg = {nCount = 10},
bannerTimeout = {nCount = 3},
Recommend = {
nCount = 5,
sCtrlName = "Game.UI.Mall.MallRecommendItemCtrl"
}
}
MallRecommendCtrl._mapEventConfig = {MallOrderClear = "Refresh"}
function MallRecommendCtrl:Refresh()
if self._panel.nCurTog ~= AllEnum.MallToggle.Recommend then
return
end
if self.timer ~= nil then
self.timer:Cancel(false)
self.timer = nil
end
self.nNextRefreshTime = 0
EventManager.Hit("MallCloseDetail")
local canvasGroup = self.gameObject:GetComponent("CanvasGroup")
self:SetBanner()
for i = 1, 5 do
local RecommendCtrl = self._mapNode.Recommend[i]
RecommendCtrl:Refresh(nil, nil)
end
if canvasGroup ~= nil then
NovaAPI.SetCanvasGroupAlpha(canvasGroup, 0)
end
local callback = function(tbList, nTime)
self:RefreshRecommend(tbList)
self:SetNextRefreshTime(nTime)
self:SetTimer()
if canvasGroup ~= nil then
NovaAPI.SetCanvasGroupAlpha(canvasGroup, 1)
end
end
PlayerData.Mall:SendMallPackageListReq(callback)
end
function MallRecommendCtrl:SetBanner()
self.tbBannerList = {}
self:AddBanner()
if nil == self.tbBannerList or nil == next(self.tbBannerList) then
self._mapNode.goBanner.gameObject:SetActive(false)
else
self._mapNode.goBanner:SetActive(true)
for _, v in ipairs(self._mapNode.imgPointBg) do
v.gameObject:SetActive(false)
end
for k, v in ipairs(self.tbBannerList) do
if nil ~= self._mapNode.imgPointBg[k] then
self._mapNode.imgPointBg[k]:SetActive(true)
self._mapNode.imgPointBg[k].transform:Find("imgPoint").gameObject:SetActive(false)
end
end
self.nBannerIdx = 1
self.nLastBannerIdx = 1
self:RefreshBanner()
end
self:StartBannerTimer()
self._mapNode.eventActBannerDrag.enabled = #self.tbBannerList > 1
end
function MallRecommendCtrl:AddBanner()
local forEachMap = function(mapData)
local nCurTime = CS.ClientManager.Instance.serverTimeStamp
if mapData.ItemType == GameEnum.MallAdvRecommendItemType.BattlePass then
local id = tonumber(mapData.ItemId)
local bpConfig = ConfigTable.GetData("BattlePass", id)
if bpConfig == nil then
return
end
local nStartTime = CS.ClientManager.Instance:ISO8601StrToTimeStamp(bpConfig.StartTime)
local nEndTime = CS.ClientManager.Instance:ISO8601StrToTimeStamp(bpConfig.EndTime)
if nCurTime > nStartTime then
self:SetNextRefreshTime(nStartTime - nCurTime)
end
if nCurTime < nStartTime or nCurTime >= nEndTime then
return
end
self:SetNextRefreshTime(nEndTime - nCurTime)
table.insert(self.tbBannerList, {
nId = mapData.Id,
nType = GameEnum.MallAdvRecommendItemType.BattlePass,
sBanner = mapData.Path,
nItemId = mapData.ItemId,
nStartTime = nStartTime,
nEndTime = nEndTime
})
elseif mapData.ItemType == GameEnum.MallAdvRecommendItemType.Package or mapData.ItemType == GameEnum.MallAdvRecommendItemType.Skin then
local packageConfig = ConfigTable.GetData("MallPackage", mapData.ItemId)
if packageConfig == nil then
return
end
if packageConfig.ListTime == "" then
return
end
local nStartTime = CS.ClientManager.Instance:ISO8601StrToTimeStamp(packageConfig.ListTime)
local nEndTime = CS.ClientManager.Instance:ISO8601StrToTimeStamp(packageConfig.DeListTime)
if nCurTime > nStartTime then
self:SetNextRefreshTime(nStartTime - nCurTime)
end
if nCurTime < nStartTime or nCurTime >= nEndTime then
return
end
self:SetNextRefreshTime(nEndTime - nCurTime)
table.insert(self.tbBannerList, {
nId = mapData.Id,
nType = mapData.ItemType,
sBanner = mapData.Path,
nItemId = mapData.ItemId,
nStartTime = nStartTime,
nEndTime = nEndTime
})
else
table.insert(self.tbBannerList, {
nId = mapData.Id,
nType = mapData.ItemType,
sBanner = mapData.Path,
nItemId = mapData.ItemId,
nStartTime = nil,
nEndTime = nil
})
end
end
ForEachTableLine(DataTable.MallAdvRecommend, forEachMap)
for _, v in ipairs(self.tbBannerList) do
local nStartTime = v.nStartTime
local nEndTime = v.nEndTime
if nStartTime ~= nil and nEndTime ~= nil then
v.nStartTime = nStartTime
v.nEndTime = nEndTime
end
end
table.sort(self.tbBannerList, function(a, b)
local configA = ConfigTable.GetData("MallAdvRecommend", a.nId)
local configB = ConfigTable.GetData("MallAdvRecommend", b.nId)
if configA.Sort ~= configB.Sort then
return configA.Sort < configB.Sort
end
end)
end
function MallRecommendCtrl:SetNextRefreshTime(nTime)
if nTime < 0 then
return
end
if self.nNextRefreshTime == 0 then
self.nNextRefreshTime = nTime
else
self.nNextRefreshTime = math.min(self.nNextRefreshTime, nTime)
end
self.nNextRefreshTime = math.max(self.nNextRefreshTime, 0)
end
function MallRecommendCtrl:RefreshBanner()
local lastIndex = self.nBannerIdx - 1 <= 0 and #self.tbBannerList or self.nBannerIdx - 1
local nextIndex = self.nBannerIdx + 1 > #self.tbBannerList and 1 or self.nBannerIdx + 1
local tbCurBannerList = {}
table.insert(tbCurBannerList, self.tbBannerList[lastIndex])
table.insert(tbCurBannerList, self.tbBannerList[self.nBannerIdx])
table.insert(tbCurBannerList, self.tbBannerList[nextIndex])
for k, v in ipairs(self._mapNode.imgBanner) do
local bannerData = tbCurBannerList[k]
self:SetPngSprite(v, bannerData.sBanner)
local timeOut = self._mapNode.bannerTimeout[k]
if bannerData.nEndTime ~= nil then
timeOut:SetActive(true)
local txt_Timeout = timeOut.transform:Find("txt_Timeout"):GetComponent("TMP_Text")
NovaAPI.SetTMPText(txt_Timeout, self:GetTimeText(bannerData.nEndTime - CS.ClientManager.Instance.serverTimeStamp))
else
timeOut:SetActive(false)
end
end
self._mapNode.imgPointBg[self.nLastBannerIdx].transform:Find("imgPoint").gameObject:SetActive(false)
self.nLastBannerIdx = self.nBannerIdx
self._mapNode.imgPointBg[self.nBannerIdx].transform:Find("imgPoint").gameObject:SetActive(true)
end
function MallRecommendCtrl:StartBannerTimer()
if #self.tbBannerList > 1 then
if nil ~= self.bannerTimer then
self.bannerTimer:Cancel()
self.bannerTimer = nil
end
self.bannerTimer = self:AddTimer(0, nBannerInterval, "PlayActBannerAnim", true, true, false)
end
end
function MallRecommendCtrl:PlayActBannerAnim()
local onCompleteCb = function()
self:BannerTweenerEnd()
end
for k, v in ipairs(self._mapNode.BannerItem) do
if k == #self._mapNode.BannerItem then
v:DOAnchorPosX(self.tbBannerInitPos[k].x - self.nBannerWidth, 0.5):SetUpdate(true):OnComplete(onCompleteCb)
else
v:DOAnchorPosX(self.tbBannerInitPos[k].x - self.nBannerWidth, 0.5):SetUpdate(true)
end
end
end
function MallRecommendCtrl:BannerTweenerEnd()
for k, v in ipairs(self._mapNode.BannerItem) do
v.anchoredPosition = self.tbBannerInitPos[k]
end
self.nBannerIdx = self.nBannerIdx + 1
if self.nBannerIdx > #self.tbBannerList then
self.nBannerIdx = 1
end
self:RefreshBanner()
end
function MallRecommendCtrl:ResetBannerTimer()
if nil ~= self.BannerTimer then
TimerManager.Remove(self.BannerTimer, false)
end
self.BannerTimer = nil
end
function MallRecommendCtrl:SetTimer()
if self.timer ~= nil then
self.timer:Cancel(false)
self.timer = nil
end
if self.nNextRefreshTime > 0 then
self.timer = self:AddTimer(1, self.nNextRefreshTime, function()
self:Refresh()
end, true, true, false)
else
end
end
function MallRecommendCtrl:RefreshRecommend(tbList)
self.tbRecommendConfig = {}
local forEachMap = function(mapData)
table.insert(self.tbRecommendConfig, mapData)
end
ForEachTableLine(DataTable.MallRecommendGroup, forEachMap)
table.sort(self.tbRecommendConfig, function(a, b)
return a.Sort < b.Sort
end)
self.tbRecommendPackageId = {}
local tbRemoveGroupIndex = {}
for i, v in ipairs(self.tbRecommendConfig) do
if #v.PackageList > 0 then
local sPackageId = ""
for _, packageId in ipairs(v.PackageList) do
if self:CheckPackageShow(packageId, tbList) then
sPackageId = packageId
break
end
end
table.insert(self.tbRecommendPackageId, sPackageId)
else
table.insert(self.tbRecommendPackageId, "")
end
end
for i = 1, 5 do
local RecommendCtrl = self._mapNode.Recommend[i]
if i <= #self.tbRecommendConfig then
RecommendCtrl:Refresh(self.tbRecommendConfig[i], self.tbRecommendPackageId[i])
else
RecommendCtrl:Refresh(nil, nil)
end
end
end
function MallRecommendCtrl:CheckPackageShow(packageId, tbPackageList)
local packageConfig = ConfigTable.GetData("MallPackage", packageId)
if packageConfig == nil then
return false
end
if packageConfig.ListCondType == GameEnum.shopCond.WorldClassSpecific then
local worldClass = PlayerData.Base:GetWorldClass()
local condParams = decodeJson(packageConfig.ListCondParams)
if worldClass < tonumber(condParams[1]) then
return false
end
elseif packageConfig.ListTime ~= "" then
local nCurTime = CS.ClientManager.Instance.serverTimeStamp
local nStartTime = CS.ClientManager.Instance:ISO8601StrToTimeStamp(packageConfig.ListTime)
local nEndTime = CS.ClientManager.Instance:ISO8601StrToTimeStamp(packageConfig.DeListTime)
if nCurTime < nStartTime or nCurTime > nEndTime then
return false
end
end
local bInlist = false
for _, packageData in ipairs(tbPackageList) do
if packageId == packageData.sId then
bInlist = true
if packageData.nCurStock <= 0 then
return false
end
end
end
if not bInlist then
return false
end
return true
end
function MallRecommendCtrl:GetTimeText(remainTime)
local sTimeStr = ""
if remainTime <= 60 then
local sec = math.floor(remainTime)
sTimeStr = orderedFormat(ConfigTable.GetUIText("Mall_Remain_Time_Sec") or "", sec)
elseif 60 < remainTime and remainTime <= 3600 then
local min = math.floor(remainTime / 60)
local sec = math.floor(remainTime - min * 60)
sTimeStr = orderedFormat(ConfigTable.GetUIText("Mall_Remain_Time_Min") or "", min, sec)
elseif 3600 < remainTime and remainTime <= 86400 then
local hour = math.floor(remainTime / 3600)
local min = math.floor((remainTime - hour * 3600) / 60)
sTimeStr = orderedFormat(ConfigTable.GetUIText("Mall_Remain_Time_Hour") or "", hour, min)
elseif 86400 < remainTime then
local day = math.floor(remainTime / 86400)
local hour = math.floor((remainTime - day * 86400) / 3600)
sTimeStr = orderedFormat(ConfigTable.GetUIText("Mall_Remain_Time_Day") or "", day, hour)
end
sTimeStr = sTimeStr .. ConfigTable.GetUIText("Mall_Package_Delist") or ""
return sTimeStr
end
function MallRecommendCtrl:OnDrag_Banner(mDrag)
if mDrag.DragEventType == AllEnum.UIDragType.DragStart then
self.nBannerDragPosX = 0
self:ResetBannerTimer()
elseif mDrag.DragEventType == AllEnum.UIDragType.Drag then
self.nBannerDragPosX = self.nBannerDragPosX + mDrag.EventData.delta.x
for k, v in ipairs(self._mapNode.BannerItem) do
v.anchoredPosition = Vector2(self.tbBannerInitPos[k].x + self.nBannerDragPosX, self.tbBannerInitPos[k].y)
end
elseif mDrag.DragEventType == AllEnum.UIDragType.DragEnd then
local nPos = 0
if self.nBannerDragPosX > 0 then
nPos = self.nBannerWidth
self.nBannerIdx = 0 >= self.nBannerIdx - 1 and #self.tbBannerList or self.nBannerIdx - 1
elseif self.nBannerDragPosX < 0 then
nPos = -self.nBannerWidth
self.nBannerIdx = self.nBannerIdx + 1 > #self.tbBannerList and 1 or self.nBannerIdx + 1
end
local tweener
for k, v in ipairs(self._mapNode.BannerItem) do
tweener = v:DOAnchorPosX(self.tbBannerInitPos[k].x + nPos, 0.5):SetUpdate(true)
end
local _cb = function()
for k, v in ipairs(self._mapNode.BannerItem) do
v.anchoredPosition = self.tbBannerInitPos[k]
end
self:RefreshBanner()
self:StartBannerTimer()
end
tweener.onComplete = dotween_callback_handler(self, _cb)
self.nBannerDragPosX = 0
end
end
function MallRecommendCtrl:OnBtnClick_Banner()
local bannerData = self.tbBannerList[self.nBannerIdx]
if bannerData.nType == GameEnum.MallAdvRecommendItemType.BattlePass then
local callback = function()
local GetDataCallback = function(mapData)
if mapData.nSeasonId == 0 then
EventManager.Hit(EventId.OpenMessageBox, ConfigTable.GetUIText("Mainview_BattlePassExpireHint"))
else
EventManager.Hit(EventId.OpenPanel, PanelId.BattlePass)
end
end
PlayerData.BattlePass:GetBattlePassInfo(GetDataCallback)
end
PlayerData.Base:CheckFunctionBtn(GameEnum.OpenFuncType.BattlePass, callback)
elseif bannerData.nType == GameEnum.MallAdvRecommendItemType.MonthlyCard then
EventManager.Hit("OpenMallTog", AllEnum.MallToggle.MonthlyCard)
elseif bannerData.nType == GameEnum.MallAdvRecommendItemType.Package then
EventManager.Hit("OpenMallTog", AllEnum.MallToggle.Package)
elseif bannerData.nType == GameEnum.MallAdvRecommendItemType.Skin then
EventManager.Hit("OpenMallTog", AllEnum.MallToggle.Skin)
end
end
function MallRecommendCtrl:Awake()
self.nNextRefreshTime = 0
self.tbBannerInitPos = {}
for _, v in ipairs(self._mapNode.BannerItem) do
self.nBannerWidth = v.sizeDelta.x
table.insert(self.tbBannerInitPos, v.anchoredPosition)
end
end
function MallRecommendCtrl:OnEnable()
end
function MallRecommendCtrl:OnDisable()
end
function MallRecommendCtrl:OnDestroy()
end
return MallRecommendCtrl