Initial version - 1.2.0.60

EN: 1.2.0.60
CN: 1.2.0.61
JP: 1.2.0.63
KR: 1.2.0.67
This commit is contained in:
SL1900
2025-12-03 01:00:00 +09:00
commit 5e0d58cfad
3595 changed files with 9373562 additions and 0 deletions
+341
View File
@@ -0,0 +1,341 @@
local ShopCtrl = class("ShopCtrl", BaseCtrl)
local LocalSettingData = require("GameCore.Data.LocalSettingData")
local Actor2DManager = require("Game.Actor2D.Actor2DManager")
local BubbleVoiceManager = require("Game.Actor2D.BubbleVoiceManager")
local PlayerVoiceData = PlayerData.Voice
ShopCtrl._mapNodeConfig = {
TopBar = {
sNodeName = "TopBarPanel",
sCtrlName = "Game.UI.TopBarEx.TopBarCtrl"
},
rawImgActor2D = {
sNodeName = "----Actor2D----",
sComponentName = "RawImage"
},
trActor2D_PNG = {
sNodeName = "----Actor2D_PNG----",
sComponentName = "Transform"
},
aniRoot = {
sNodeName = "----SafeAreaRoot----",
sComponentName = "Animator"
},
btnActor2D = {
sComponentName = "Button",
callback = "OnBtnClick_Actor2D"
},
svTog = {
sComponentName = "LoopScrollView"
},
trSvTog = {sNodeName = "svTog", sComponentName = "Transform"},
goRefresh = {},
txtRefreshCn = {sComponentName = "TMP_Text"},
txtRefreshTime = {sComponentName = "TMP_Text"},
Goods = {
sNodeName = "---Goods---",
sCtrlName = "Game.UI.ShopEx.ShopGoodsCtrl"
},
btnDailyGift = {
sComponentName = "UIButton",
callback = "OnBtnClick_DailyGift"
},
txtGiftOff = {sComponentName = "TMP_Text"},
txtDailyGift = {
sComponentName = "TMP_Text",
sLanguageId = "Shop_DailyGift"
},
goGiftOn = {},
goGiftOff = {},
reddotGift = {},
goBubbleRoot = {
sNodeName = "----fixed_bubble----"
}
}
ShopCtrl._mapEventConfig = {
ShopTimeRefresh = "OnEvent_TimeRefresh",
[EventId.IsNewDay] = "RefreshDailyGift",
[EventId.NewFuncUnlockWorldClass] = "OnEvent_NewFuncUnlockWorldClass",
[EventId.ShowBubbleVoiceText] = "OnEvent_ShowBubbleVoiceText",
ShopBuyVoice = "PlayBuyVoice",
[EventId.UIBackConfirm] = "OnEvent_UIBack",
[EventId.UIHomeConfirm] = "OnEvent_Home"
}
ShopCtrl._mapRedDotConfig = {
[RedDotDefine.Shop_Daily] = {sNodeName = "reddotGift"}
}
local npcId = 9131
function ShopCtrl:CheckShopData()
EventManager.Hit("ShopCloseDetail")
PlayerData.Shop:CheckShopData(function()
self:RefreshData()
self:RefreshTog()
self:SetTimer()
self:SwitchTog()
end)
self:RefreshNPC2D()
end
function ShopCtrl:RefreshData()
self.tbShops = PlayerData.Shop:GetShopList()
self.nShopCount = #self.tbShops
self.ctrlTog = {}
if self.nCurTog == nil then
self.nCurTog = 1
if self._panel.nDefaultId then
for k, v in ipairs(self.tbShops) do
if v.nId == self._panel.nDefaultId then
self.nCurTog = k
break
end
end
end
end
if not self.tbShops[self.nCurTog] or self.nSelectShop and self.tbShops[self.nCurTog].nId ~= self.nSelectShop then
self.nCurTog = 1
end
self.nSelectShop = self.tbShops[self.nCurTog].nId
end
function ShopCtrl:RefreshTog()
if self.nShopCount > 0 then
self._mapNode.svTog.gameObject:SetActive(true)
for nInstanceID, objCtrl in pairs(self.ctrlTog) do
self:UnbindCtrlByNode(objCtrl)
self.ctrlTog[nInstanceID] = nil
end
self._mapNode.svTog:Init(self.nShopCount, self, self.OnGridRefresh, self.OnGridBtnClick)
else
self._mapNode.svTog.gameObject:SetActive(false)
end
end
function ShopCtrl:OnGridRefresh(goGrid, gridIndex)
local nIndex = gridIndex + 1
local nInstanceID = goGrid:GetInstanceID()
if not self.ctrlTog[nInstanceID] then
self.ctrlTog[nInstanceID] = self:BindCtrlByNode(goGrid, "Game.UI.TemplateEx.TemplateToggleCtrl")
end
self.ctrlTog[nInstanceID]:SetText(self.tbShops[nIndex].sName)
self.ctrlTog[nInstanceID]:SetDefault(nIndex == self.nCurTog)
end
function ShopCtrl:OnGridBtnClick(goGrid, gridIndex)
local nIndex = gridIndex + 1
local nInstanceID = goGrid:GetInstanceID()
if nIndex == self.nCurTog then
return
end
self.ctrlTog[nInstanceID]:SetTrigger(true)
if self.nCurTog then
local goSelect = self._mapNode.trSvTog:Find("Viewport/Content/" .. self.nCurTog - 1)
if goSelect then
self.ctrlTog[goSelect.gameObject:GetInstanceID()]:SetTrigger(false)
end
end
self.nCurTog = nIndex
self.nSelectShop = self.tbShops[self.nCurTog].nId
self:SwitchTog()
self._mapNode.aniRoot:Play("ShopPanel_in")
self:PlaySwitchTogVoice()
end
function ShopCtrl:SetTimer()
if self.timer ~= nil then
self.timer:Cancel(false)
self.timer = nil
end
local nTime = PlayerData.Shop:GetShopAutoUpdateTime()
if 0 < nTime then
self.timer = self:AddTimer(1, nTime, function()
self:CheckShopData()
EventManager.Hit(EventId.CloseMessageBox)
EventManager.Hit(EventId.OpenMessageBox, ConfigTable.GetUIText("Shop_ShopRefresh"))
end, true, true, false)
end
end
function ShopCtrl:SwitchTog()
local mapShop = self.tbShops[self.nCurTog]
self._mapNode.TopBar:CreateCoin(mapShop.tbShopCoin)
self._mapNode.Goods:Open(mapShop.nId, mapShop.nNextRefreshTime)
self.nRemainTime = mapShop.nNextRefreshTime == 0 and 0 or mapShop.nNextRefreshTime - CS.ClientManager.Instance.serverTimeStamp
if self.timerCountDown == nil then
self.timerCountDown = self:AddTimer(0, 1, "RefreshTime", false, true, false)
end
if self.nRemainTime > 0 then
self._mapNode.goRefresh:SetActive(true)
self:RefreshTime()
self.timerCountDown:Pause(false)
else
self._mapNode.goRefresh:SetActive(false)
self.timerCountDown:Pause(true)
end
end
function ShopCtrl:RefreshTime()
self.nRemainTime = self.nRemainTime - 1
if self.nRemainTime > 0 then
local mapShop = self.tbShops[self.nCurTog]
NovaAPI.SetTMPText(self._mapNode.txtRefreshCn, mapShop.nNextRefreshTime == mapShop.nCloseTime and ConfigTable.GetUIText("Shop_NextClose") or ConfigTable.GetUIText("Shop_NextRefresh"))
local sTime = ""
if self.nRemainTime <= 60 then
local sec = math.floor(self.nRemainTime)
sTime = orderedFormat(ConfigTable.GetUIText("Shop_NextRefresh_Sec"), sec)
elseif self.nRemainTime > 60 and self.nRemainTime <= 3600 then
local min = math.floor(self.nRemainTime / 60)
local sec = math.floor(self.nRemainTime - min * 60)
if sec == 0 then
min = min - 1
sec = 60
end
sTime = orderedFormat(ConfigTable.GetUIText("Shop_NextRefresh_Min"), min, sec)
elseif self.nRemainTime > 3600 and self.nRemainTime <= 86400 then
local hour = math.floor(self.nRemainTime / 3600)
local min = math.floor((self.nRemainTime - hour * 3600) / 60)
if min == 0 then
hour = hour - 1
min = 60
end
sTime = orderedFormat(ConfigTable.GetUIText("Shop_NextRefresh_Hour"), hour, min)
elseif self.nRemainTime > 86400 then
local day = math.floor(self.nRemainTime / 86400)
local hour = math.floor((self.nRemainTime - day * 86400) / 3600)
if hour == 0 then
day = day - 1
hour = 24
end
sTime = orderedFormat(ConfigTable.GetUIText("Shop_NextRefresh_Day"), day, hour)
end
NovaAPI.SetTMPText(self._mapNode.txtRefreshTime, sTime)
else
self.timerCountDown:Pause(true)
end
end
function ShopCtrl:RefreshNPC2D()
local bUseL2D = LocalSettingData.mapData.UseLive2D
self._mapNode.rawImgActor2D.transform.localScale = bUseL2D == true and Vector3.one or Vector3.zero
self._mapNode.trActor2D_PNG.localScale = bUseL2D == true and Vector3.zero or Vector3.one
if bUseL2D == true then
Actor2DManager.SetBoardNPC2D(self:GetPanelId(), self._mapNode.rawImgActor2D, npcId)
else
Actor2DManager.SetBoardNPC2D_PNG(self._mapNode.trActor2D_PNG, self:GetPanelId(), npcId)
end
end
function ShopCtrl:RefreshDailyGift()
local bUnlock = PlayerData.Base:CheckFunctionUnlock(GameEnum.OpenFuncType.DailyReward)
NovaAPI.SetTMPText(self._mapNode.txtGiftOff, bUnlock and ConfigTable.GetUIText("Shop_Received") or ConfigTable.GetUIText("Shop_DailyGift_Locked"))
if bUnlock then
local bActive = PlayerData.Shop:GetDailyShopReward()
self._mapNode.goGiftOff:SetActive(not bActive)
self._mapNode.goGiftOn:SetActive(bActive)
else
self._mapNode.goGiftOff:SetActive(true)
self._mapNode.goGiftOn:SetActive(false)
end
end
function ShopCtrl:PlayEnterVoice()
local nTimeNow = CS.ClientManager.Instance.serverTimeStampWithTimeZone
local bFirst = PlayerData.Shop:GetShopFirstIn()
local sTimeVoice = ""
local nHour = tonumber(os.date("!%H", nTimeNow))
if 6 <= nHour and nHour < 12 then
sTimeVoice = "greetmorn_npc"
elseif 12 <= nHour and nHour < 18 then
sTimeVoice = "greetnoon_npc"
else
sTimeVoice = "greetnight_npc"
end
if bFirst then
PlayerData.Voice:PlayCharVoice(sTimeVoice, npcId, nil, true)
else
local nIndex = math.random(1, 2)
local sVoice = nIndex == 1 and sTimeVoice or "greet_npc"
PlayerData.Voice:PlayCharVoice(sVoice, npcId, nil, true)
end
end
function ShopCtrl:PlayBuyVoice(bSale, bLimit)
local sVoice = ""
if bSale then
sVoice = "onsale"
elseif bLimit then
sVoice = "limited"
else
sVoice = "thank_npc"
end
PlayerData.Voice:PlayCharVoice(sVoice, npcId, nil, true)
end
function ShopCtrl:PlaySwitchTogVoice()
PlayerData.Voice:PlayCharVoice("Tab", npcId, nil, true)
end
function ShopCtrl:PlayDailyGiftVoice()
PlayerData.Voice:PlayCharVoice("thanksp", npcId, nil, true)
end
function ShopCtrl:FadeIn(bPlayFadeIn)
EventManager.Hit(EventId.SetTransition)
self._mapNode.aniRoot:Play("ShopPanel_in")
end
function ShopCtrl:Awake()
self.nCurTog = nil
end
function ShopCtrl:OnEnable()
PlayerVoiceData:StartBoardFreeTimer(npcId)
self:PlayEnterVoice()
self:RefreshDailyGift()
self:CheckShopData()
end
function ShopCtrl:OnDisable()
if self.ctrlTog then
for nInstanceId, objCtrl in pairs(self.ctrlTog) do
self:UnbindCtrlByNode(objCtrl)
self.ctrlTog[nInstanceId] = nil
end
self.ctrlTog = {}
end
Actor2DManager.UnsetBoardNPC2D()
BubbleVoiceManager.StopBubbleAnim()
PlayerVoiceData:ClearTimer()
PlayerVoiceData:StopCharVoice()
end
function ShopCtrl:OnDestroy()
end
function ShopCtrl:OnBtnClick_Actor2D()
PlayerVoiceData:PlayBoardNPCClickVoice(npcId)
end
function ShopCtrl:OnBtnClick_DailyGift()
local checkcallback = function()
local bActive = PlayerData.Shop:GetDailyShopReward()
if not bActive then
EventManager.Hit(EventId.OpenMessageBox, ConfigTable.GetUIText("Shop_DailyGift_Received"))
return
end
local callback = function()
self:RefreshDailyGift()
self:PlayDailyGiftVoice()
end
PlayerData.Shop:SendDailyShopRewardReceiveReq(callback)
end
PlayerData.Base:CheckFunctionBtn(GameEnum.OpenFuncType.DailyReward, checkcallback, "ui_systerm_locked")
end
function ShopCtrl:OnEvent_TimeRefresh()
self:CheckShopData()
end
function ShopCtrl:OnEvent_NewFuncUnlockWorldClass(nId)
if nId == GameEnum.OpenFuncType.DailyReward then
self:RefreshDailyGift()
end
end
function ShopCtrl:OnEvent_ShowBubbleVoiceText(nNpcId, nId)
if nNpcId ~= npcId then
return
end
local mapVoDirectoryData = ConfigTable.GetData("VoDirectory", nId)
if mapVoDirectoryData == nil then
printError("VoDirectory未找到数据id:" .. nId)
return
end
BubbleVoiceManager.PlayFixedBubbleAnim(self._mapNode.goBubbleRoot, mapVoDirectoryData.voResource)
end
function ShopCtrl:OnEvent_UIBack(nPanelId)
if PanelId.DiscSample ~= nPanelId or PanelId.CharBgTrialPanel ~= nPanelId then
PlayerVoiceData:StartBoardFreeTimer(npcId)
end
end
function ShopCtrl:OnEvent_Home(nPanelId)
if PanelId.DiscSample ~= nPanelId or PanelId.CharBgTrialPanel ~= nPanelId then
PlayerVoiceData:StartBoardFreeTimer(npcId)
end
end
return ShopCtrl
+72
View File
@@ -0,0 +1,72 @@
local ShopGoodsCtrl = class("ShopGoodsCtrl", BaseCtrl)
ShopGoodsCtrl._mapNodeConfig = {
sv = {
sComponentName = "LoopScrollView"
}
}
ShopGoodsCtrl._mapEventConfig = {
ShopRefreshGoods = "CheckGoodsData"
}
function ShopGoodsCtrl:Open(nShopId, nShopAutoTime)
self.nShopId = nShopId
self.nShopAutoTime = nShopAutoTime
self:CheckGoodsData(true)
end
function ShopGoodsCtrl:CheckGoodsData(bResetPos)
PlayerData.Shop:CheckGoodsData(self.nShopId)
self.tbGoods = PlayerData.Shop:GetGoodsList(self.nShopId)
self:SetTimer()
self:RefreshList(bResetPos)
end
function ShopGoodsCtrl:SetTimer()
if self.timer ~= nil then
self.timer:Cancel(false)
self.timer = nil
end
local nTime = PlayerData.Shop:GetGoodsAutoUpdateTime(self.nShopId)
if 0 < nTime and (self.nShopAutoTime == 0 or nTime < self.nShopAutoTime) then
self.timer = self:AddTimer(1, nTime, function()
EventManager.Hit("ShopCloseDetail")
EventManager.Hit(EventId.CloseMessageBox)
self:CheckGoodsData(true)
EventManager.Hit(EventId.OpenMessageBox, ConfigTable.GetUIText("Shop_GoodsRefresh"))
end, true, true, false)
end
end
function ShopGoodsCtrl:RefreshList(bResetPos)
for nInstanceId, objCtrl in pairs(self.tbGridCtrl) do
self:UnbindCtrlByNode(objCtrl)
self.tbGridCtrl[nInstanceId] = nil
end
self._mapNode.sv:SetAnim(0.04)
self._mapNode.sv:Init(#self.tbGoods, self, self.OnGridRefresh, self.OnGridBtnClick, not bResetPos)
end
function ShopGoodsCtrl:OnGridRefresh(goGrid, gridIndex)
local nIndex = gridIndex + 1
local mapData = self.tbGoods[nIndex]
local nInstanceID = goGrid:GetInstanceID()
if not self.tbGridCtrl[nInstanceID] then
self.tbGridCtrl[nInstanceID] = self:BindCtrlByNode(goGrid, "Game.UI.ShopEx.ShopGoodsItemCtrl")
end
self.tbGridCtrl[nInstanceID]:Refresh(mapData)
end
function ShopGoodsCtrl:OnGridBtnClick(goGrid, gridIndex)
local nIndex = gridIndex + 1
local mapData = self.tbGoods[nIndex]
EventManager.Hit(EventId.OpenPanel, PanelId.ShopPopupPanel, mapData, self.nShopId)
end
function ShopGoodsCtrl:Awake()
self.tbGridCtrl = {}
end
function ShopGoodsCtrl:OnEnable()
end
function ShopGoodsCtrl:OnDisable()
for nInstanceId, objCtrl in pairs(self.tbGridCtrl) do
self:UnbindCtrlByNode(objCtrl)
self.tbGridCtrl[nInstanceId] = nil
end
self.tbGridCtrl = {}
end
function ShopGoodsCtrl:OnDestroy()
end
return ShopGoodsCtrl
+255
View File
@@ -0,0 +1,255 @@
local ShopGoodsDetailCtrl = class("ShopGoodsDetailCtrl", BaseCtrl)
ShopGoodsDetailCtrl._mapNodeConfig = {
txtWindowTitle = {
sComponentName = "TMP_Text",
sLanguageId = "Shop_TitleBuy"
},
goItem = {
sCtrlName = "Game.UI.TemplateEx.TemplateItemCtrl"
},
btnDetail = {
sComponentName = "UIButton",
callback = "OnBtnClick_Detail"
},
txtName = {sComponentName = "TMP_Text"},
txtDesc = {sComponentName = "TMP_Text"},
txtHas = {sComponentName = "TMP_Text"},
txtPriceCn = {
sComponentName = "TMP_Text",
sLanguageId = "Shop_UnitPrice"
},
imgCoin = {nCount = 2, sComponentName = "Image"},
goOrigin = {},
txtOrigin = {sComponentName = "TMP_Text"},
txtPrice = {sComponentName = "TMP_Text"},
imgDiscount = {},
txtDiscount = {
sComponentName = "TMP_Text",
sLanguageId = "Shop_Discount"
},
txtStock = {sComponentName = "TMP_Text"},
goStock = {},
txtBtnBuy = {
nCount = 2,
sComponentName = "TMP_Text",
sLanguageId = "Shop_Btn_Buy"
},
txtCoinCount = {sComponentName = "TMP_Text"},
btnBuy = {
sComponentName = "UIButton",
callback = "OnBtnClick_Buy"
},
btnClose = {
sComponentName = "UIButton",
callback = "OnBtnClick_Close"
},
btnBuy2 = {
sComponentName = "UIButton",
callback = "OnBtnClick_Disable"
},
txtDisable = {sComponentName = "TMP_Text"},
goQuantitySelector = {
sNodeName = "tc_quantity_selector",
sCtrlName = "Game.UI.TemplateEx.TemplateQuantitySelectorCtrl"
}
}
ShopGoodsDetailCtrl._mapEventConfig = {}
function ShopGoodsDetailCtrl:Refresh(mapData, nShopId)
self.mapData = mapData
self.nShopId = nShopId
self.bAble = self.mapData.bPurchasTime and self.mapData.bPurchasable and not self.mapData.bSoldOut
self:PlayInAni()
self:RefreshInfo(mapData)
self:RefreshPrice(mapData)
self:RefreshBuyState()
self:RefreshBuyCount()
end
function ShopGoodsDetailCtrl:RefreshInfo(mapData)
local mapCfg = ConfigTable.GetData_Item(mapData.nItemId)
NovaAPI.SetTMPText(self._mapNode.txtName, mapData.sName)
self._mapNode.goItem:SetItem(mapData.nItemId, nil, mapData.nItemQuantity, nil, nil, nil, nil, true)
if mapCfg and (mapCfg.Type == GameEnum.itemType.Disc or mapCfg.Type == GameEnum.itemType.Char or mapCfg.Type == GameEnum.itemType.CharacterSkin) then
self._mapNode.txtHas.gameObject:SetActive(false)
else
self._mapNode.txtHas.gameObject:SetActive(true)
local nCount = PlayerData.Item:GetItemCountByID(mapData.nItemId)
if 999999 < nCount then
local nFloor = math.floor(nCount / 100)
local nK = string.format("%.0f", nFloor / 10)
local sCount = nK .. "k"
NovaAPI.SetTMPText(self._mapNode.txtHas, ConfigTable.GetUIText("Shop_Has") .. sCount)
else
NovaAPI.SetTMPText(self._mapNode.txtHas, ConfigTable.GetUIText("Shop_Has") .. nCount)
end
end
NovaAPI.SetTMPText(self._mapNode.txtDesc, mapData.sDesc)
local bLimit = mapData.nMaximumLimit > 0
if bLimit then
local nLeft = mapData.nMaximumLimit - mapData.nBoughtCount
NovaAPI.SetTMPText(self._mapNode.txtStock, orderedFormat(ConfigTable.GetUIText("Shop_Stock"), nLeft))
NovaAPI.SetTMPColor(self._mapNode.txtStock, nLeft == 0 and Red_Unable or Blue_Dark)
else
NovaAPI.SetTMPText(self._mapNode.txtStock, ConfigTable.GetUIText("Shop_Unlimited"))
NovaAPI.SetTMPColor(self._mapNode.txtStock, Blue_Dark)
end
self._mapNode.btnDetail.interactable = mapCfg and (mapCfg.Stype == GameEnum.itemStype.Disc or mapCfg.Stype == GameEnum.itemStype.Char or mapCfg.Stype == GameEnum.itemStype.RandomPackage or mapCfg.Stype == GameEnum.itemStype.ComCYO or mapCfg.Stype == GameEnum.itemStype.OutfitCYO)
end
function ShopGoodsDetailCtrl:RefreshPrice(mapData)
for i = 1, 2 do
self:SetSprite_Coin(self._mapNode.imgCoin[i], mapData.nCurrencyItemId)
end
NovaAPI.SetTMPText(self._mapNode.txtPrice, mapData.nPrice)
local bSale = mapData.nOriginalPrice > 0
self._mapNode.imgDiscount:SetActive(bSale)
self._mapNode.goOrigin:SetActive(bSale)
if bSale then
NovaAPI.SetTMPText(self._mapNode.txtOrigin, mapData.nOriginalPrice)
end
end
function ShopGoodsDetailCtrl:RefreshBuyCount()
local nCost = self.nBuyCount * self.mapData.nPrice
NovaAPI.SetTMPText(self._mapNode.txtCoinCount, nCost)
local nHasCoin = PlayerData.Coin:GetCoinCount(self.mapData.nCurrencyItemId)
NovaAPI.SetTMPColor(self._mapNode.txtCoinCount, nCost > nHasCoin and Red_Unable or Blue_Normal)
end
function ShopGoodsDetailCtrl:RefreshBuyState()
self._mapNode.btnBuy.gameObject:SetActive(self.bAble)
self._mapNode.btnBuy2.gameObject:SetActive(not self.bAble)
self._mapNode.txtDisable.gameObject:SetActive(not self.mapData.bPurchasable or self.mapData.bSoldOut)
self.nBuyCount = self.bAble and 1 or 0
local nMax = self:CountMaxBuy()
local callback = function(nCount)
self.nBuyCount = nCount
self:RefreshBuyCount()
end
self._mapNode.goQuantitySelector:Init(callback, self.nBuyCount, nMax)
if self.mapData.bSoldOut then
NovaAPI.SetTMPText(self._mapNode.txtDisable, ConfigTable.GetUIText("Shop_Cond_SoldOutShort"))
elseif not self.mapData.bPurchasable then
if self.mapData.nPurchaseCondType == GameEnum.shopCond.WorldClassSpecific then
NovaAPI.SetTMPText(self._mapNode.txtDisable, orderedFormat(ConfigTable.GetUIText("Shop_Cond_WorldClassShort"), self.mapData.tbPurchaseCondParams[1]))
elseif self.mapData.nPurchaseCondType == GameEnum.shopCond.ShopPreGoodsSellOut then
NovaAPI.SetTMPText(self._mapNode.txtDisable, ConfigTable.GetUIText("Shop_Cond_PreGoodsSellOut"))
end
end
end
function ShopGoodsDetailCtrl:CountMaxBuy()
local nHasCoin = PlayerData.Coin:GetCoinCount(self.mapData.nCurrencyItemId)
local nMax = math.floor(nHasCoin / self.mapData.nPrice)
if nMax == 0 then
return 1
end
if 0 < self.mapData.nMaximumLimit then
local nRemain = self.mapData.nMaximumLimit - self.mapData.nBoughtCount
return nMax > nRemain and nRemain or nMax
else
return nMax
end
end
function ShopGoodsDetailCtrl:PlayInAni()
self.gameObject:SetActive(true)
self.ani:Play("t_window_04_t_in")
EventManager.Hit(EventId.TemporaryBlockInput, 0.3)
end
function ShopGoodsDetailCtrl:PlayOutAni()
self.ani:Play("t_window_04_t_out")
self:AddTimer(1, 0.2, "Close", true, true, true)
end
function ShopGoodsDetailCtrl:Close()
self.gameObject:SetActive(false)
end
function ShopGoodsDetailCtrl:Awake()
self.ani = self.gameObject.transform:GetComponent("Animator")
end
function ShopGoodsDetailCtrl:OnEnable()
end
function ShopGoodsDetailCtrl:OnDisable()
end
function ShopGoodsDetailCtrl:OnDestroy()
end
function ShopGoodsDetailCtrl:OnBtnClick_Buy()
local nCost = self.nBuyCount * self.mapData.nPrice
local nHasCoin = PlayerData.Coin:GetCoinCount(self.mapData.nCurrencyItemId)
local sName = ConfigTable.GetData_Item(self.mapData.nCurrencyItemId).Title
if nCost > nHasCoin then
EventManager.Hit(EventId.OpenMessageBox, orderedFormat(ConfigTable.GetUIText("Shop_NotEnough"), sName))
return
end
local buy = function()
local callback = function()
EventManager.Hit("ShopRefreshGoods")
EventManager.Hit("ShopCloseDetail")
local bSale = self.mapData.nOriginalPrice > 0
local bLimit = 0 < self.mapData.nMaximumLimit
EventManager.Hit("ShopBuyVoice", bSale, bLimit)
end
PlayerData.Shop:SendResidentShopPurchaseReq(self.nShopId, self.mapData.nId, self.nBuyCount, callback)
end
local buy_confirm = function()
local nAll = self.mapData.nItemQuantity * self.nBuyCount
local sTip = 1 < nAll and orderedFormat(ConfigTable.GetUIText("Shop_MultiBuyComfirm"), nCost, sName, nAll, self.mapData.sName) or orderedFormat(ConfigTable.GetUIText("Shop_BuyComfirm"), nCost, sName, self.mapData.sName)
local msg = {
nType = AllEnum.MessageBox.Confirm,
sContent = sTip,
callbackConfirm = buy,
bBlur = false
}
EventManager.Hit(EventId.OpenMessageBox, msg)
end
local mapCfg = ConfigTable.GetData_Item(self.mapData.nItemId)
local sTip
if mapCfg.Type == GameEnum.itemType.Disc then
sTip = PlayerData.Item:GetDiscHoldingState(self.mapData.nItemId, self.nBuyCount)
elseif mapCfg.Type == GameEnum.itemType.Char then
sTip = PlayerData.Item:GetCharHoldingState(self.mapData.nItemId, self.nBuyCount)
elseif mapCfg.Stype == GameEnum.itemStype.CharShard then
local nCharId = PlayerData.Talent:GetFragmentsToChar(self.mapData.nItemId)
sTip = PlayerData.Item:GetCharHoldingState(nCharId, 0, self.nBuyCount)
end
if sTip then
local msg = {
nType = AllEnum.MessageBox.Confirm,
sContent = sTip,
callbackConfirm = buy_confirm,
bBlur = false
}
EventManager.Hit(EventId.OpenMessageBox, msg)
else
buy_confirm()
end
end
function ShopGoodsDetailCtrl:OnBtnClick_Close()
EventManager.Hit("ShopCloseDetail")
end
function ShopGoodsDetailCtrl:OnBtnClick_Detail()
local mapCfg = ConfigTable.GetData_Item(self.mapData.nItemId)
if not mapCfg then
return
end
if mapCfg.Stype == GameEnum.itemStype.Disc then
EventManager.Hit(EventId.OpenPanel, PanelId.DiscSample, self.mapData.nItemId)
elseif mapCfg.Stype == GameEnum.itemStype.Char then
EventManager.Hit(EventId.OpenPanel, PanelId.CharBgTrialPanel, PanelId.CharInfoTrial, self.mapData.nItemId)
elseif mapCfg.Stype == GameEnum.itemStype.RandomPackage or mapCfg.Stype == GameEnum.itemStype.ComCYO then
local tbDetailItem, sDetailTitle = PlayerData.Item:GetCYODisplayItem(self.mapData.nItemId)
local msg = {
nType = AllEnum.MessageBox.ItemList,
tbItem = tbDetailItem,
sTitle = sDetailTitle,
bBlur = false
}
EventManager.Hit(EventId.OpenMessageBox, msg)
elseif mapCfg.Stype == GameEnum.itemStype.OutfitCYO then
EventManager.Hit(EventId.OpenPanel, PanelId.DiscPreview, self.mapData.nItemId)
end
end
function ShopGoodsDetailCtrl:OnBtnClick_Disable()
if self.mapData.bSoldOut then
EventManager.Hit(EventId.OpenMessageBox, ConfigTable.GetUIText("Shop_GoodsEmpty"))
elseif not self.mapData.bPurchasable then
EventManager.Hit(EventId.OpenMessageBox, ConfigTable.GetUIText("Shop_Condition"))
elseif not self.mapData.bPurchasTime then
EventManager.Hit(EventId.OpenMessageBox, ConfigTable.GetUIText("Shop_NotPurchasTime"))
end
end
return ShopGoodsDetailCtrl
+128
View File
@@ -0,0 +1,128 @@
local ShopGoodsItemCtrl = class("ShopGoodsItemCtrl", BaseCtrl)
ShopGoodsItemCtrl._mapNodeConfig = {
imgRare = {sComponentName = "Image"},
imgDiscount = {},
txtDiscount = {
sComponentName = "TMP_Text",
sLanguageId = "Shop_Discount"
},
imgLeft = {},
txtLeft = {sComponentName = "TMP_Text"},
imgTime = {},
txtLeftTime = {sComponentName = "TMP_Text"},
txtName = {sComponentName = "TMP_Text"},
imgIcon = {sComponentName = "Image"},
imgElement = {sComponentName = "Image"},
txtCount = {sComponentName = "TMP_Text"},
imgCoin = {sComponentName = "Image"},
goOrigin = {},
txtOrigin = {sComponentName = "TMP_Text"},
txtPrice = {sComponentName = "TMP_Text"},
imgMask = {},
goRestock = {},
txtRestock = {
sComponentName = "TMP_Text",
sLanguageId = "Shop_Restock"
},
goCondition = {},
txtCondition = {sComponentName = "TMP_Text"}
}
ShopGoodsItemCtrl._mapEventConfig = {}
function ShopGoodsItemCtrl:Refresh(mapData)
self:RefreshInfo(mapData)
self:RefreshPrice(mapData)
self:RefreshTime(mapData)
self:RefreshLimit(mapData)
end
function ShopGoodsItemCtrl:RefreshInfo(mapData)
local mapCfg = ConfigTable.GetData_Item(mapData.nItemId)
NovaAPI.SetTMPText(self._mapNode.txtName, mapData.sName)
if mapCfg.Type == GameEnum.itemType.Disc then
self:SetPngSprite(self._mapNode.imgIcon, mapCfg.Icon .. AllEnum.OutfitIconSurfix.Item)
self._mapNode.imgElement.gameObject:SetActive(true)
local mapDiscCfgData = ConfigTable.GetData("Disc", mapData.nItemId)
self:SetAtlasSprite(self._mapNode.imgElement, "12_rare", AllEnum.Star_Element[mapDiscCfgData.EET].icon)
else
self:SetPngSprite(self._mapNode.imgIcon, mapCfg.Icon)
self._mapNode.imgElement.gameObject:SetActive(false)
end
local sPath = AllEnum.FrameType_New.ShopGoods .. AllEnum.FrameColor_New[mapCfg.Rarity]
self:SetAtlasSprite(self._mapNode.imgRare, "12_rare", sPath)
local bLimit = mapData.nMaximumLimit > 0
if bLimit then
NovaAPI.SetTMPText(self._mapNode.txtLeft, orderedFormat(ConfigTable.GetUIText("Shop_Left"), mapData.nMaximumLimit - mapData.nBoughtCount))
else
NovaAPI.SetTMPText(self._mapNode.txtLeft, orderedFormat(ConfigTable.GetUIText("Shop_Left"), ConfigTable.GetUIText("Shop_Unlimited")))
end
NovaAPI.SetTMPText(self._mapNode.txtCount, orderedFormat(ConfigTable.GetUIText("Shop_GoodsItem_Count"), mapData.nItemQuantity))
end
function ShopGoodsItemCtrl:RefreshPrice(mapData)
self:SetSprite_Coin(self._mapNode.imgCoin, mapData.nCurrencyItemId)
NovaAPI.SetTMPText(self._mapNode.txtPrice, mapData.nPrice)
local bSale = mapData.nOriginalPrice > 0
self._mapNode.imgDiscount:SetActive(bSale)
self._mapNode.goOrigin:SetActive(bSale)
if bSale then
NovaAPI.SetTMPText(self._mapNode.txtOrigin, mapData.nOriginalPrice)
end
end
function ShopGoodsItemCtrl:RefreshTime(mapData)
local bTime = mapData.bPurchasTime and mapData.nNextRefreshTime > 0
self._mapNode.imgTime:SetActive(bTime)
if not bTime then
return
end
local sTime = ""
local nRemaining = mapData.nNextRefreshTime - CS.ClientManager.Instance.serverTimeStamp
if nRemaining <= 3600 and 0 < nRemaining then
sTime = ConfigTable.GetUIText("Shop_WithinHour")
elseif 3600 < nRemaining and nRemaining <= 86400 then
sTime = orderedFormat(ConfigTable.GetUIText("Shop_Hour"), math.floor(nRemaining / 3600))
elseif 86400 < nRemaining then
sTime = orderedFormat(ConfigTable.GetUIText("Shop_Day"), math.floor(nRemaining / 86400))
end
NovaAPI.SetTMPText(self._mapNode.txtLeftTime, sTime)
end
function ShopGoodsItemCtrl:RefreshLimit(mapData)
local bMask = not mapData.bPurchasable or not mapData.bPurchasTime or mapData.bSoldOut
self._mapNode.imgMask:SetActive(bMask)
if mapData.bSoldOut then
self._mapNode.goRestock:SetActive(true)
self._mapNode.goCondition:SetActive(false)
return
end
self._mapNode.goRestock:SetActive(false)
self._mapNode.goCondition:SetActive(true)
if mapData.nUnlockPurchaseTime > 0 and mapData.nUnlockPurchaseTime == mapData.nNextRefreshTime then
local sTime = ""
local nRemaining = mapData.nNextRefreshTime - CS.ClientManager.Instance.serverTimeStamp
if nRemaining <= 3600 and 0 < nRemaining then
sTime = ConfigTable.GetUIText("Shop_WithinHourUnLock")
elseif 3600 < nRemaining and nRemaining <= 86400 then
sTime = orderedFormat(ConfigTable.GetUIText("Shop_HourUnLock"), math.floor(nRemaining / 3600))
elseif 86400 < nRemaining then
sTime = orderedFormat(ConfigTable.GetUIText("Shop_DayUnLock"), math.floor(nRemaining / 86400))
end
NovaAPI.SetTMPText(self._mapNode.txtCondition, sTime)
return
end
if not mapData.bPurchasable then
local sCond = ""
if mapData.nPurchaseCondType == GameEnum.shopCond.WorldClassSpecific then
sCond = orderedFormat(ConfigTable.GetUIText("Shop_Cond_WorldClass"), mapData.tbPurchaseCondParams[1])
elseif mapData.nPurchaseCondType == GameEnum.shopCond.ShopPreGoodsSellOut then
sCond = ConfigTable.GetUIText("Shop_Cond_PreGoodsSellOut")
end
NovaAPI.SetTMPText(self._mapNode.txtCondition, sCond)
return
end
end
function ShopGoodsItemCtrl:Awake()
end
function ShopGoodsItemCtrl:OnEnable()
end
function ShopGoodsItemCtrl:OnDisable()
end
function ShopGoodsItemCtrl:OnDestroy()
end
return ShopGoodsItemCtrl
+21
View File
@@ -0,0 +1,21 @@
local ShopPanel = class("ShopPanel", BasePanel)
ShopPanel._tbDefine = {
{
sPrefabPath = "ShopEx/ShopPanel.prefab",
sCtrlName = "Game.UI.ShopEx.ShopCtrl"
}
}
function ShopPanel:Awake()
self.nDefaultId = nil
local tbParam = self:GetPanelParam()
if type(tbParam) == "table" then
self.nDefaultId = tbParam[1]
end
end
function ShopPanel:OnEnable()
end
function ShopPanel:OnDisable()
end
function ShopPanel:OnDestroy()
end
return ShopPanel
+59
View File
@@ -0,0 +1,59 @@
local ShopPopupCtrl = class("ShopPopupCtrl", BaseCtrl)
ShopPopupCtrl._mapNodeConfig = {
TopBar = {
sNodeName = "TopBarPanel",
sCtrlName = "Game.UI.TopBarEx.TopBarCtrl"
},
blur = {
sNodeName = "t_fullscreen_blur_blue"
},
aniBlur = {
sNodeName = "t_fullscreen_blur_blue",
sComponentName = "Animator"
},
btnCloseDatail = {
sNodeName = "snapshot",
sComponentName = "Button",
callback = "OnBtnClick_CloseDetail"
},
Detail = {
sNodeName = "---Detail---",
sCtrlName = "Game.UI.ShopEx.ShopGoodsDetailCtrl"
}
}
ShopPopupCtrl._mapEventConfig = {
ShopCloseDetail = "OnBtnClick_CloseDetail"
}
function ShopPopupCtrl:Open()
self._mapNode.TopBar:CreateCoin({
self.mapData.nCurrencyItemId
}, true)
self._mapNode.blur:SetActive(true)
self._mapNode.Detail:Refresh(self.mapData, self.nShopId)
end
function ShopPopupCtrl:Awake()
local tbParam = self:GetPanelParam()
if type(tbParam) == "table" then
self.mapData = tbParam[1]
self.nShopId = tbParam[2]
end
end
function ShopPopupCtrl:OnEnable()
self:Open()
end
function ShopPopupCtrl:OnDisable()
end
function ShopPopupCtrl:OnDestroy()
end
function ShopPopupCtrl:OnBtnClick_CloseDetail()
if self._mapNode.Detail.gameObject.activeSelf == false then
return
end
self._mapNode.Detail:PlayOutAni()
self._mapNode.aniBlur:SetTrigger("tOut")
self:AddTimer(1, 0.2, function()
EventManager.Hit(EventId.ClosePanel, PanelId.ShopPopupPanel)
end, true, true, true)
EventManager.Hit(EventId.TemporaryBlockInput, 0.2)
end
return ShopPopupCtrl
+17
View File
@@ -0,0 +1,17 @@
local ShopPopupPanel = class("ShopPopupPanel", BasePanel)
ShopPopupPanel._bIsMainPanel = false
ShopPopupPanel._tbDefine = {
{
sPrefabPath = "ShopEx/ShopPopupPanel.prefab",
sCtrlName = "Game.UI.ShopEx.ShopPopupCtrl"
}
}
function ShopPopupPanel:Awake()
end
function ShopPopupPanel:OnEnable()
end
function ShopPopupPanel:OnDisable()
end
function ShopPopupPanel:OnDestroy()
end
return ShopPopupPanel