Files
StellaSora_DataLua/lua/game/ui/mall/mallfurnituresetctrl.lua
T
SL1900 08b515afd9 Major Update - 2.0.0.143
EN: 2.0.0.143
CN: 2.0.0.142
JP: 2.0.0.145
KR: 2.0.0.150
2026-10-20 13:00:00 +09:00

425 lines
15 KiB
Lua

local MallFurnitureSetCtrl = class("MallFurnitureSetCtrl", BaseCtrl)
MallFurnitureSetCtrl._mapNodeConfig = {
txtWindowTitle = {
sComponentName = "TMP_Text",
sLanguageId = "Shop_TitleBuy"
},
txtTagName = {sComponentName = "TMP_Text"},
imgTag = {},
goFurniture = {},
txtFurnitureValue = {sComponentName = "TMP_Text"},
txtName = {sComponentName = "TMP_Text"},
goCurrency = {},
imgCurrency = {sComponentName = "Image"},
txtPrice = {sComponentName = "TMP_Text"},
txtPriceCn = {
sComponentName = "TMP_Text",
sLanguageId = "Mall_Package_PriceTitle"
},
svList = {
sNodeName = "lsvList",
sComponentName = "LoopScrollView"
},
goTime = {},
txtLimit = {sComponentName = "TMP_Text"},
txtLimitCn = {
sComponentName = "TMP_Text",
sLanguageId = "Mall_Package_LimitTitle"
},
txtTime = {sComponentName = "TMP_Text"},
txtTimeCn = {
sComponentName = "TMP_Text",
sLanguageId = "Mall_Package_TimeTitle"
},
txtTitleFurnitureList = {
sComponentName = "TMP_Text",
sLanguageId = "Mall_Package_FurnitureList"
},
btnBuy1 = {
sComponentName = "UIButton",
callback = "OnBtnClick_Buy"
},
btnBuy2 = {
sComponentName = "UIButton",
callback = "OnBtnClick_Disable"
},
txtBtnBuy = {
nCount = 2,
sComponentName = "TMP_Text",
sLanguageId = "Mall_Btn_Buy"
},
btnClose = {
sComponentName = "UIButton",
callback = "OnBtnClick_Close"
},
goTitleList = {
sComponentName = "RectTransform"
},
eventDrag = {
sNodeName = "goTitleList",
sComponentName = "UIDrag",
callback = "OnDrag_Banner"
},
goTitleItem = {
nCount = 3,
sComponentName = "RectTransform"
},
imgTitleImg = {nCount = 3, sComponentName = "Image"},
imgPointBg = {nCount = 4},
imgPoint = {nCount = 4}
}
MallFurnitureSetCtrl._mapEventConfig = {}
function MallFurnitureSetCtrl:Refresh(mapData)
self.sId = mapData.sId
local mapCfg = ConfigTable.GetData("MallPackage", mapData.sId)
self:PlayInAni()
self:RefreshInfo(mapCfg)
self:RefreshPrice(mapCfg)
self:RefreshLimit(mapCfg, mapData)
self:RefreshTime(mapData)
self:RefreshFurnitureValue(mapCfg)
self:RefreshItem(mapCfg)
self:RefreshBuy(mapCfg, mapData)
end
function MallFurnitureSetCtrl:RefreshInfo(mapCfg)
NovaAPI.SetTMPText(self._mapNode.txtName, mapCfg.DetailName)
self.tbIcon = {}
local tbItem = decodeJson(mapCfg.Items)
if next(tbItem) == nil then
return
end
local tbSet = {}
for sSetId in pairs(tbItem) do
table.insert(tbSet, tonumber(sSetId))
end
local mapDormCfg = ConfigTable.GetData("DormLayoutReward", tbSet[1])
if not mapDormCfg then
return
end
self._mapNode.imgTag:SetActive(mapDormCfg.RoomLayoutTag ~= "")
if mapDormCfg.RoomLayoutTag ~= "" then
NovaAPI.SetTMPText(self._mapNode.txtTagName, mapDormCfg.RoomLayoutTag)
end
table.insert(self.tbIcon, mapDormCfg.RoomLayoutListIcon)
self:SetBanner()
end
function MallFurnitureSetCtrl:SetBanner()
self:ResetBannerTimer()
self.nBannerIdx = 1
self.nBannerDragPosX = 0
for k, v in ipairs(self._mapNode.goTitleItem) do
v.anchoredPosition = self.tbBannerInitPos[k]
end
self._mapNode.eventDrag.enabled = 1 < #self.tbIcon
for k, v in ipairs(self._mapNode.imgPointBg) do
v:SetActive(false)
end
if next(self.tbIcon) == nil then
return
end
self:RefreshBanner()
self:StartBannerTimer()
end
function MallFurnitureSetCtrl:RefreshBanner()
local nCount = #self.tbIcon
local nLastIdx = self.nBannerIdx - 1 <= 0 and nCount or self.nBannerIdx - 1
local nNextIdx = nCount < self.nBannerIdx + 1 and 1 or self.nBannerIdx + 1
local tbCurIcon = {
self.tbIcon[nLastIdx],
self.tbIcon[self.nBannerIdx],
self.tbIcon[nNextIdx]
}
for k, v in ipairs(self._mapNode.imgTitleImg) do
if tbCurIcon[k] ~= nil then
self:SetPngSprite(v, tbCurIcon[k] .. "_big")
end
end
for k, v in ipairs(self._mapNode.imgPoint) do
v:SetActive(k == self.nBannerIdx)
end
end
function MallFurnitureSetCtrl:StartBannerTimer()
if self.bannerTimer == nil and #self.tbIcon > 1 then
self.bannerTimer = self:AddTimer(0, self.nBannerInterval, "PlayBannerAnim", true, true, false)
end
end
function MallFurnitureSetCtrl:ResetBannerTimer()
if self.bannerTimer ~= nil then
self.bannerTimer:Cancel(false)
end
self.bannerTimer = nil
end
function MallFurnitureSetCtrl:PlayBannerAnim()
local onCompleteCb = function()
self:BannerTweenerEnd()
end
for k, v in ipairs(self._mapNode.goTitleItem) do
if k == #self._mapNode.goTitleItem 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 MallFurnitureSetCtrl:BannerTweenerEnd()
for k, v in ipairs(self._mapNode.goTitleItem) do
v.anchoredPosition = self.tbBannerInitPos[k]
end
self.nBannerIdx = self.nBannerIdx + 1 > #self.tbIcon and 1 or self.nBannerIdx + 1
self:RefreshBanner()
end
function MallFurnitureSetCtrl:OnDrag_Banner(mDrag)
if #self.tbIcon <= 1 then
return
end
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.goTitleItem) 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.tbIcon or self.nBannerIdx - 1
elseif self.nBannerDragPosX < 0 then
nPos = -self.nBannerWidth
self.nBannerIdx = self.nBannerIdx + 1 > #self.tbIcon and 1 or self.nBannerIdx + 1
end
local tweener
for k, v in ipairs(self._mapNode.goTitleItem) do
tweener = v:DOAnchorPosX(self.tbBannerInitPos[k].x + nPos, 0.5):SetUpdate(true)
end
local _cb = function()
for k, v in ipairs(self._mapNode.goTitleItem) 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 MallFurnitureSetCtrl:RefreshPrice(mapCfg)
if mapCfg.CurrencyType == GameEnum.currencyType.Cash then
self._mapNode.goCurrency:SetActive(false)
NovaAPI.SetTMPText(self._mapNode.txtPrice, tostring(mapCfg.CurrencyShowPrice))
elseif mapCfg.CurrencyType == GameEnum.currencyType.Item then
self._mapNode.goCurrency:SetActive(true)
NovaAPI.SetTMPText(self._mapNode.txtPrice, mapCfg.CurrencyItemQty)
self:SetPngSprite(self._mapNode.imgCurrency, ConfigTable.GetData_Item(mapCfg.CurrencyItemId).Icon2)
elseif mapCfg.CurrencyType == GameEnum.currencyType.Free then
self._mapNode.goCurrency:SetActive(false)
NovaAPI.SetTMPText(self._mapNode.txtPrice, ConfigTable.GetUIText("Mall_Package_Free"))
end
end
function MallFurnitureSetCtrl:RefreshLimit(mapCfg, mapData)
NovaAPI.SetTMPText(self._mapNode.txtLimit, mapData.nCurStock .. "/" .. mapCfg.Stock)
if mapCfg.RefreshType == GameEnum.mallPackageRefreshType.None then
NovaAPI.SetTMPText(self._mapNode.txtLimitCn, ConfigTable.GetUIText("Mall_Package_LimitTitle"))
elseif mapCfg.RefreshType == GameEnum.mallPackageRefreshType.Day then
NovaAPI.SetTMPText(self._mapNode.txtLimitCn, ConfigTable.GetUIText("Mall_Package_DayLimitTitle"))
elseif mapCfg.RefreshType == GameEnum.mallPackageRefreshType.Week then
NovaAPI.SetTMPText(self._mapNode.txtLimitCn, ConfigTable.GetUIText("Mall_Package_WeekLimitTitle"))
elseif mapCfg.RefreshType == GameEnum.mallPackageRefreshType.Month then
NovaAPI.SetTMPText(self._mapNode.txtLimitCn, ConfigTable.GetUIText("Mall_Package_MonthLimitTitle"))
end
end
function MallFurnitureSetCtrl:GetTimeStr(nRemainTime)
local str = ""
if nRemainTime <= 3600 then
str = ConfigTable.GetUIText("Mall_Package_WithinHour")
elseif 3600 < nRemainTime and nRemainTime <= 86400 then
str = orderedFormat(ConfigTable.GetUIText("Mall_Package_Hour") or "", math.floor(nRemainTime / 3600))
elseif 86400 < nRemainTime then
str = orderedFormat(ConfigTable.GetUIText("Mall_Package_Day") or "", math.floor(nRemainTime / 86400))
end
return str
end
function MallFurnitureSetCtrl:RefreshTime(mapData)
self._mapNode.goTime:SetActive(mapData.nNextRefreshTime > 0)
if mapData.nNextRefreshTime <= 0 then
return
end
local sSuffix = mapData.bPrioritizeDeList and ConfigTable.GetUIText("Mall_Package_Delist") or ConfigTable.GetUIText("Mall_Package_Refresh")
local sPrefix = self:GetTimeStr(mapData.nNextRefreshTime - CS.ClientManager.Instance.serverTimeStamp)
NovaAPI.SetTMPText(self._mapNode.txtTime, sPrefix .. sSuffix)
end
function MallFurnitureSetCtrl:RefreshFurnitureValue(mapCfg)
local nValue = PlayerData.Mall:GetFurnitureSetCollectionValue(mapCfg)
NovaAPI.SetTMPText(self._mapNode.txtFurnitureValue, tostring(nValue))
end
function MallFurnitureSetCtrl:RefreshItem(mapCfg)
self.tbFurniture = {}
local mapIndex = {}
for sSetId in pairs(decodeJson(mapCfg.Items) or {}) do
local itemCfg = ConfigTable.GetData_Item(tonumber(sSetId))
if itemCfg ~= nil then
for sItemId, nCount in pairs(decodeJson(itemCfg.UseArgs) or {}) do
local nId = tonumber(sItemId)
local furnitureCfg = ConfigTable.GetData("DormFurniture", nId)
local furnitureItemCfg = ConfigTable.GetData_Item(nId)
if furnitureCfg ~= nil and furnitureItemCfg ~= nil then
local nIndex = mapIndex[nId]
if nIndex == nil then
table.insert(self.tbFurniture, {
nId = nId,
nCount = nCount,
nRarity = furnitureItemCfg.Rarity
})
mapIndex[nId] = #self.tbFurniture
else
self.tbFurniture[nIndex].nCount = self.tbFurniture[nIndex].nCount + nCount
end
end
end
end
end
table.sort(self.tbFurniture, function(a, b)
if a.nRarity ~= b.nRarity then
return a.nRarity < b.nRarity
else
return a.nId < b.nId
end
end)
for nInstanceId, objCtrl in pairs(self.tbGridCtrl) do
self:UnbindCtrlByNode(objCtrl)
self.tbGridCtrl[nInstanceId] = nil
end
self._mapNode.svList:Init(#self.tbFurniture, self, self.OnGridRefresh, self.OnGridClick)
end
function MallFurnitureSetCtrl:OnGridRefresh(goGrid, nIdx)
local mapItem = self.tbFurniture[nIdx + 1]
if mapItem == nil then
return
end
local nInstanceId = goGrid:GetInstanceID()
if self.tbGridCtrl[nInstanceId] == nil then
self.tbGridCtrl[nInstanceId] = self:BindCtrlByNode(goGrid, "Game.UI.Dorm.DormEditor.TemplateDormFurnitureItem")
end
self.tbGridCtrl[nInstanceId]:Refresh(mapItem.nId, mapItem.nCount, 0)
end
function MallFurnitureSetCtrl:OnGridClick(goGrid, nIdx)
local mapItem = self.tbFurniture[nIdx + 1]
if mapItem == nil then
return
end
self._mapNode.svList:SetScrollGridPos(nIdx, 0.1, 1)
EventManager.Hit(EventId.BlockInput, true)
self:AddTimer(1, 0.1, function()
EventManager.Hit(EventId.BlockInput, false)
UTILS.ClickItemGridWithTips(mapItem.nId, goGrid.transform:Find("btnGrid"), false, false, false)
end, true, true, true)
end
function MallFurnitureSetCtrl:RefreshBuy(mapCfg, mapData)
local tbCond = decodeJson(mapCfg.OrderCondParams)
local bPurchaseAble = PlayerData.Shop:CheckShopCond(mapCfg.OrderCondType, tbCond)
local bAble = bPurchaseAble and mapData.nCurStock > 0
self._mapNode.btnBuy1.gameObject:SetActive(bAble)
self._mapNode.btnBuy2.gameObject:SetActive(not bAble)
if not bPurchaseAble then
self.sDisableTip = ConfigTable.GetUIText("Shop_Condition")
elseif mapData.nCurStock == 0 then
self.sDisableTip = ConfigTable.GetUIText("Shop_GoodsEmpty")
end
end
function MallFurnitureSetCtrl:PlayInAni()
self.gameObject:SetActive(true)
self.ani:Play("t_window_04_t_in")
EventManager.Hit(EventId.TemporaryBlockInput, 0.3)
end
function MallFurnitureSetCtrl:PlayOutAni()
self.ani:Play("t_window_04_t_out")
self:AddTimer(1, 0.2, "Close", true, true, true)
end
function MallFurnitureSetCtrl:Close()
self.gameObject:SetActive(false)
end
function MallFurnitureSetCtrl:Awake()
self.ani = self.gameObject.transform:GetComponent("Animator")
self.tbGridCtrl = {}
self.tbIcon = {}
self.tbBannerInitPos = {}
for _, v in ipairs(self._mapNode.goTitleItem) do
self.nBannerWidth = v.sizeDelta.x
table.insert(self.tbBannerInitPos, v.anchoredPosition)
end
self.nBannerInterval = ConfigTable.GetConfigNumber("Activity_Banner_Interval_Time")
self._mapNode.eventDrag:SetStrictDrag(true)
end
function MallFurnitureSetCtrl:OnEnable()
end
function MallFurnitureSetCtrl:OnDisable()
self:ResetBannerTimer()
for nInstanceId, objCtrl in pairs(self.tbGridCtrl) do
self:UnbindCtrlByNode(objCtrl)
self.tbGridCtrl[nInstanceId] = nil
end
self.tbGridCtrl = {}
end
function MallFurnitureSetCtrl:OnDestroy()
end
function MallFurnitureSetCtrl:OnBtnClick_Buy()
local mapCfg = ConfigTable.GetData("MallPackage", self.sId)
if not mapCfg then
return
end
local nCurrencyType = mapCfg.CurrencyType
if nCurrencyType == GameEnum.currencyType.Cash then
PlayerData.Mall:BuyPackage(self.sId, mapCfg.StatisticalGroup)
else
local bShowConfirm = false
if nCurrencyType == GameEnum.currencyType.Item then
local nHas = 0
if mapCfg.CurrencyItemId == AllEnum.CoinItemId.FREESTONE or mapCfg.CurrencyItemId == AllEnum.CoinItemId.STONE then
bShowConfirm = true
nHas = PlayerData.Coin:GetCoinCount(AllEnum.CoinItemId.FREESTONE) + PlayerData.Coin:GetCoinCount(AllEnum.CoinItemId.STONE)
else
nHas = PlayerData.Coin:GetCoinCount(mapCfg.CurrencyItemId)
end
if nHas < mapCfg.CurrencyItemQty then
local funcOpenBuyGem = function()
EventManager.Hit("MallCloseDetail")
EventManager.Hit("OpenMallTog", AllEnum.MallToggle.Gem)
end
if mapCfg.CurrencyItemId == AllEnum.CoinItemId.FREESTONE or mapCfg.CurrencyItemId == AllEnum.CoinItemId.STONE then
local msg = {
nType = AllEnum.MessageBox.Confirm,
sContent = orderedFormat(ConfigTable.GetUIText("Recruit_Charge") or "", ConfigTable.GetData_Item(AllEnum.CoinItemId.STONE).Id),
callbackConfirm = funcOpenBuyGem,
bBlur = false
}
EventManager.Hit(EventId.OpenMessageBox, msg)
elseif mapCfg.CurrencyItemId == AllEnum.CoinItemId.Furniture then
PlayerData.Coin:ExchangeFurnitureCoin(mapCfg.CurrencyItemQty, funcOpenBuyGem)
end
return
end
end
if bShowConfirm then
local msg = {
nType = AllEnum.MessageBox.Confirm,
sContent = orderedFormat(ConfigTable.GetUIText("Mall_Package_Buy_Confirm") or "", mapCfg.CurrencyItemQty, mapCfg.CurrencyItemId, mapCfg.DetailName),
callbackConfirm = function()
PlayerData.Mall:SendMallPackageOrderReq(self.sId)
end,
bBlur = false
}
EventManager.Hit(EventId.OpenMessageBox, msg)
else
PlayerData.Mall:SendMallPackageOrderReq(self.sId)
end
end
end
function MallFurnitureSetCtrl:OnBtnClick_Disable()
EventManager.Hit(EventId.OpenMessageBox, self.sDisableTip)
end
function MallFurnitureSetCtrl:OnBtnClick_Close()
EventManager.Hit("MallCloseDetail")
end
return MallFurnitureSetCtrl