5e0d58cfad
EN: 1.2.0.60 CN: 1.2.0.61 JP: 1.2.0.63 KR: 1.2.0.67
477 lines
15 KiB
Lua
477 lines
15 KiB
Lua
local FixedRoguelikeRewardGachaCtrl = class("FixedRoguelikeRewardGachaCtrl", BaseCtrl)
|
||
local GameResourceLoader = require("Game.Common.Resource.GameResourceLoader")
|
||
local ResType = GameResourceLoader.ResType
|
||
local WwiseAudioMgr = CS.WwiseAudioManager.Instance
|
||
FixedRoguelikeRewardGachaCtrl._mapNodeConfig = {
|
||
uieffectBg = {sComponentName = "GameObject"},
|
||
goGacha = {sComponentName = "GameObject"},
|
||
btnClose = {
|
||
sComponentName = "Button",
|
||
callback = "OnBtnClick_Close"
|
||
},
|
||
rtContent = {
|
||
sComponentName = "RectTransform"
|
||
},
|
||
ItemRoot = {
|
||
sComponentName = "RectTransform"
|
||
}
|
||
}
|
||
FixedRoguelikeRewardGachaCtrl._mapEventConfig = {}
|
||
local HULF_PAGE = 6
|
||
local FULL_PAGE = 12
|
||
local FALLIN_TIME = 0.03
|
||
local LINE_SPACE_TIME = 0.1
|
||
local OPEN_R_TIME = 0.2
|
||
local OPEN_SSR_TIME = 1
|
||
local FALLIN_ALL_TIME = 0.5
|
||
local RewardGachaIconType = {
|
||
A = "a",
|
||
B = "b",
|
||
C = "c",
|
||
D = "d"
|
||
}
|
||
function FixedRoguelikeRewardGachaCtrl:ProcessResult(mapResult)
|
||
local tbRarityItem = self:ReallocateRarity(mapResult.tbItem)
|
||
local tbRarityPresents = self:ReallocateRarity(mapResult.tbPresents)
|
||
local tbRarityOutfit = self:ReallocateRarity(mapResult.tbOutfit)
|
||
local tbRarityGacha = mapResult.tbRarityCount
|
||
local tbAllRarity = {}
|
||
for nRarity, _ in pairs(tbRarityGacha) do
|
||
table.insert(tbAllRarity, nRarity)
|
||
end
|
||
table.sort(tbAllRarity, function(a, b)
|
||
return a < b
|
||
end)
|
||
local nAllRarity = #tbAllRarity
|
||
for j = 1, nAllRarity - 1 do
|
||
local nRarity = tbAllRarity[j]
|
||
local nItem = 0
|
||
for _, mapItem in pairs(tbRarityItem[nRarity]) do
|
||
nItem = nItem + mapItem.nCount
|
||
end
|
||
local nPresents = #tbRarityPresents[nRarity]
|
||
local nOutfit = #tbRarityOutfit[nRarity]
|
||
local nNeed = tbRarityGacha[nRarity] - nItem - nPresents - nOutfit
|
||
nNeed = 0 < nNeed and nNeed or 0
|
||
if tbRarityItem[nRarity + 1] and #tbRarityItem[nRarity + 1] > 0 and 0 < nNeed then
|
||
local nCount = #tbRarityItem[nRarity + 1]
|
||
for i = nCount, 1, -1 do
|
||
if nNeed <= 0 then
|
||
break
|
||
end
|
||
local mapItem = tbRarityItem[nRarity + 1][i]
|
||
if nNeed < mapItem.nCount then
|
||
table.insert(tbRarityItem[nRarity], {
|
||
nTid = mapItem.nTid,
|
||
nCount = nNeed
|
||
})
|
||
mapItem.nCount = mapItem.nCount - nNeed
|
||
nNeed = 0
|
||
else
|
||
table.insert(tbRarityItem[nRarity], mapItem)
|
||
table.remove(tbRarityItem[nRarity + 1], i)
|
||
nNeed = nNeed - mapItem.nCount
|
||
end
|
||
end
|
||
end
|
||
if tbRarityPresents[nRarity + 1] and #tbRarityPresents[nRarity + 1] > 0 and 0 < nNeed then
|
||
local nCount = #tbRarityPresents[nRarity + 1]
|
||
for i = nCount, 1, -1 do
|
||
if nNeed <= 0 then
|
||
break
|
||
end
|
||
local mapItem = tbRarityPresents[nRarity + 1][i]
|
||
table.insert(tbRarityPresents[nRarity], mapItem)
|
||
table.remove(tbRarityPresents[nRarity + 1], i)
|
||
nNeed = nNeed - 1
|
||
end
|
||
end
|
||
if tbRarityOutfit[nRarity + 1] and #tbRarityOutfit[nRarity + 1] > 0 and 0 < nNeed then
|
||
local nCount = #tbRarityOutfit[nRarity + 1]
|
||
for i = nCount, 1, -1 do
|
||
if nNeed <= 0 then
|
||
break
|
||
end
|
||
local mapItem = tbRarityOutfit[nRarity + 1][i]
|
||
table.insert(tbRarityOutfit[nRarity], mapItem)
|
||
table.remove(tbRarityOutfit[nRarity + 1], i)
|
||
nNeed = nNeed - 1
|
||
end
|
||
end
|
||
end
|
||
local tbRarityReward = {}
|
||
local tbPresentsToNext = {}
|
||
local tbOutfitToNext = {}
|
||
local tbItemToNext = {}
|
||
for i = 5, 1, -1 do
|
||
local nRarity = i
|
||
if not tbRarityGacha[nRarity] then
|
||
local add_next = function(tbItem, tbNext)
|
||
if not tbItem then
|
||
return
|
||
end
|
||
for _, mapItem in pairs(tbItem) do
|
||
table.insert(tbNext, mapItem)
|
||
end
|
||
end
|
||
add_next(tbRarityPresents[nRarity], tbPresentsToNext)
|
||
add_next(tbRarityOutfit[nRarity], tbOutfitToNext)
|
||
add_next(tbRarityItem[nRarity], tbItemToNext)
|
||
else
|
||
tbRarityReward[nRarity] = {}
|
||
do
|
||
local nItem = #tbRarityItem[nRarity]
|
||
local nPresents = #tbRarityPresents[nRarity]
|
||
local nOutfit = #tbRarityOutfit[nRarity]
|
||
local nHas = nItem + nPresents + nOutfit + #tbPresentsToNext + #tbOutfitToNext + #tbItemToNext
|
||
local bFull = nHas >= tbRarityGacha[nRarity]
|
||
local add_previous = function(tbNext)
|
||
for _, mapItem in pairs(tbNext) do
|
||
table.insert(tbRarityReward[nRarity], mapItem)
|
||
tbRarityGacha[nRarity] = tbRarityGacha[nRarity] - 1
|
||
end
|
||
end
|
||
add_previous(tbPresentsToNext)
|
||
tbPresentsToNext = {}
|
||
add_previous(tbOutfitToNext)
|
||
tbOutfitToNext = {}
|
||
if bFull then
|
||
add_previous(tbItemToNext)
|
||
else
|
||
for _, mapItem in pairs(tbItemToNext) do
|
||
table.insert(tbRarityItem[nRarity], mapItem)
|
||
end
|
||
end
|
||
tbItemToNext = {}
|
||
local bClear = false
|
||
local add_cur = function(tbItem, tbNext)
|
||
for _, mapItem in pairs(tbItem) do
|
||
if 0 < tbRarityGacha[nRarity] then
|
||
table.insert(tbRarityReward[nRarity], mapItem)
|
||
tbRarityGacha[nRarity] = tbRarityGacha[nRarity] - 1
|
||
else
|
||
bClear = true
|
||
end
|
||
if bClear then
|
||
table.insert(tbNext, mapItem)
|
||
end
|
||
end
|
||
end
|
||
add_cur(tbRarityPresents[nRarity], tbPresentsToNext)
|
||
add_cur(tbRarityOutfit[nRarity], tbOutfitToNext)
|
||
if bFull then
|
||
add_cur(tbRarityItem[nRarity], tbItemToNext)
|
||
else
|
||
do
|
||
local tbAfter = self:ReallocateGacha(tbRarityItem[nRarity], tbRarityGacha[nRarity])
|
||
for _, mapItem in pairs(tbAfter) do
|
||
table.insert(tbRarityReward[nRarity], mapItem)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
local tbReward = {}
|
||
for _, nRarity in pairs(tbAllRarity) do
|
||
local tbRandom = self:RandomTable(tbRarityReward[nRarity])
|
||
for _, mapItem in ipairs(tbRandom) do
|
||
table.insert(tbReward, {
|
||
nTid = mapItem.nTid,
|
||
nCount = mapItem.nCount,
|
||
nRarity = nRarity
|
||
})
|
||
end
|
||
end
|
||
return tbReward
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:ReallocateRarity(tbItem)
|
||
local tbRarity = {}
|
||
for i = 1, 5 do
|
||
if not tbRarity[i] then
|
||
tbRarity[i] = {}
|
||
end
|
||
end
|
||
for _, mapItem in pairs(tbItem) do
|
||
local mapCfg = ConfigTable.GetData_Item(mapItem.nTid)
|
||
local nRarity = mapCfg.Rarity
|
||
table.insert(tbRarity[nRarity], mapItem)
|
||
end
|
||
return tbRarity
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:ReallocateGacha(tbItem, nAllGachaCount)
|
||
if nAllGachaCount == nil or nAllGachaCount == 0 then
|
||
return {}
|
||
end
|
||
for _, mapItem in ipairs(tbItem) do
|
||
mapItem.nRarity = ConfigTable.GetData_Item(mapItem.nTid).Rarity
|
||
end
|
||
local comp = function(a, b)
|
||
if a.nRarity ~= b.nRarity then
|
||
return a.nRarity < b.nRarity
|
||
else
|
||
return a.nTid > b.nTid
|
||
end
|
||
end
|
||
table.sort(tbItem, comp)
|
||
local tbAllocation = {}
|
||
local nTypeCount = #tbItem
|
||
local nRemainGacha = nAllGachaCount - nTypeCount
|
||
for i = 1, nTypeCount do
|
||
if not tbAllocation[i] then
|
||
tbAllocation[i] = 0
|
||
end
|
||
end
|
||
local bFail = false
|
||
local nFailTimes = 0
|
||
while 0 < nRemainGacha do
|
||
if nFailTimes == 2 then
|
||
nRemainGacha = 0
|
||
printError("掉落扭蛋分配错误")
|
||
end
|
||
if bFail then
|
||
nFailTimes = nFailTimes + 1
|
||
end
|
||
bFail = true
|
||
for i = 1, nTypeCount do
|
||
if tbItem[i].nCount > tbAllocation[i] + 1 and 0 < nRemainGacha then
|
||
tbAllocation[i] = tbAllocation[i] + 1
|
||
nRemainGacha = nRemainGacha - 1
|
||
bFail = false
|
||
end
|
||
end
|
||
end
|
||
local tbAfter = {}
|
||
for i = 1, nTypeCount do
|
||
local nItemCount = tbItem[i].nCount
|
||
local tbItemCount = {nItemCount}
|
||
for _ = 1, tbAllocation[i] do
|
||
table.sort(tbItemCount, function(a, b)
|
||
return b < a
|
||
end)
|
||
local nMax = tbItemCount[1]
|
||
local nAllocation = math.random(math.ceil(nMax / 4), math.floor(nMax / 2))
|
||
tbItemCount[1] = nMax - nAllocation
|
||
table.insert(tbItemCount, nAllocation)
|
||
end
|
||
for _, value in pairs(tbItemCount) do
|
||
table.insert(tbAfter, {
|
||
nTid = tbItem[i].nTid,
|
||
nCount = value
|
||
})
|
||
end
|
||
end
|
||
return tbAfter
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:RandomTable(tb)
|
||
local tbRandom = {}
|
||
local nCount = #tb
|
||
while 0 < nCount do
|
||
local nRandomIndex = math.random(1, nCount)
|
||
local mapItem = tb[nRandomIndex]
|
||
table.insert(tbRandom, mapItem)
|
||
table.remove(tb, nRandomIndex)
|
||
nCount = nCount - 1
|
||
end
|
||
return tbRandom
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:ProcessListData(tbReward)
|
||
self.tbRewardList = {}
|
||
local nAllRewardCount = #tbReward
|
||
local nFullListCount = math.floor(nAllRewardCount / FULL_PAGE)
|
||
for _ = 1, nFullListCount do
|
||
local tbSubReward = {}
|
||
for _ = 1, FULL_PAGE do
|
||
table.insert(tbSubReward, tbReward[1])
|
||
table.remove(tbReward, 1)
|
||
end
|
||
table.insert(self.tbRewardList, tbSubReward)
|
||
end
|
||
table.insert(self.tbRewardList, tbReward)
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:RefreshListItem(tbReward, bHulfPage)
|
||
local bHasItem = true
|
||
if self.tbGoItem == nil then
|
||
self.tbGoItem = {}
|
||
bHasItem = false
|
||
end
|
||
for key, v in ipairs(tbReward) do
|
||
local nItemId = v.nTid
|
||
local cfgDataItem = ConfigTable.GetData_Item(nItemId)
|
||
local goItem
|
||
if bHasItem then
|
||
goItem = self.tbGoItem[key].go
|
||
elseif bHulfPage then
|
||
goItem = instantiate(self._mapNode.goGacha, self._mapNode.ItemRoot)
|
||
else
|
||
goItem = instantiate(self._mapNode.goGacha, self._mapNode.rtContent)
|
||
end
|
||
local tr = goItem.transform
|
||
local imgFrame = tr:Find("goIcon/imgFrame"):GetComponent("Image")
|
||
local imgIcon = tr:Find("goIcon/imgFrame/imgIcon"):GetComponent("Image")
|
||
local imgFull = tr:Find("imgFull"):GetComponent("Image")
|
||
local imgSplitB = tr:Find("goSplit/imgSplitB"):GetComponent("Image")
|
||
local imgSplitC = tr:Find("goSplit/imgSplitB/imgSplitC"):GetComponent("Image")
|
||
local imgSplitD = tr:Find("goSplit/imgSplitD"):GetComponent("Image")
|
||
local txtCount = tr:Find("goIcon/imgFrame/ItemCount"):GetComponent("TMP_Text")
|
||
self:SetAtlasSprite(imgFrame, "12_rare", AllEnum.FrameType_New.Item .. AllEnum.FrameColor_New[cfgDataItem.Rarity], true)
|
||
if cfgDataItem.Type == GameEnum.itemType.Outfit or cfgDataItem.Type == GameEnum.itemType.Disc then
|
||
self:SetPngSprite(imgIcon, cfgDataItem.Icon .. AllEnum.OutfitIconSurfix.Item)
|
||
else
|
||
self:SetPngSprite(imgIcon, cfgDataItem.Icon)
|
||
end
|
||
self:SetPngSprite(imgFull, "UI/big_sprites/" .. string.format(AllEnum.RewardGachaType[v.nRarity], RewardGachaIconType.A))
|
||
self:SetPngSprite(imgSplitB, "UI/big_sprites/" .. string.format(AllEnum.RewardGachaType[v.nRarity], RewardGachaIconType.B))
|
||
self:SetPngSprite(imgSplitC, "UI/big_sprites/" .. string.format(AllEnum.RewardGachaType[v.nRarity], RewardGachaIconType.C))
|
||
self:SetPngSprite(imgSplitD, "UI/big_sprites/" .. string.format(AllEnum.RewardGachaType[v.nRarity], RewardGachaIconType.D))
|
||
NovaAPI.SetTMPText(txtCount, v.nCount > 1 and "×" .. v.nCount or "")
|
||
if not bHasItem then
|
||
table.insert(self.tbGoItem, {
|
||
go = goItem,
|
||
bSSR = cfgDataItem.Rarity == GameEnum.itemRarity.SSR
|
||
})
|
||
else
|
||
self.tbGoItem[key].bSSR = cfgDataItem.Rarity == GameEnum.itemRarity.SSR
|
||
end
|
||
NovaAPI.SetCanvasGroupAlpha(tr:GetComponent("CanvasGroup"), 0)
|
||
goItem:SetActive(true)
|
||
end
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:PlayListAni(nPageCount, bLast, bOnePage, callback)
|
||
local nLine = math.ceil(nPageCount / HULF_PAGE)
|
||
local nLastLine = math.fmod(nPageCount, HULF_PAGE)
|
||
if nLastLine == 0 then
|
||
nLastLine = HULF_PAGE
|
||
end
|
||
self.sequence = DOTween.Sequence()
|
||
if nLine == 1 then
|
||
local nTime = 0
|
||
if bOnePage then
|
||
nTime = FALLIN_ALL_TIME / nLastLine
|
||
else
|
||
nTime = FALLIN_TIME
|
||
end
|
||
for i = 1, nLastLine do
|
||
self.sequence:AppendCallback(function()
|
||
NovaAPI.SetCanvasGroupAlpha(self.tbGoItem[i].go.transform:GetComponent("CanvasGroup"), 1)
|
||
self.tbGoItem[i].go:GetComponent("Animator"):Play("gacha_fall_in")
|
||
if i == 1 then
|
||
if nLastLine == 1 then
|
||
WwiseAudioMgr:PlaySound("ui_roguelike_gacha_fall_1")
|
||
elseif nLastLine == 2 then
|
||
WwiseAudioMgr:PlaySound("ui_roguelike_gacha_fall_2")
|
||
elseif 2 < nLastLine and nLastLine <= 6 then
|
||
WwiseAudioMgr:PlaySound("ui_roguelike_gacha_fall_3")
|
||
end
|
||
end
|
||
end)
|
||
self.sequence:AppendInterval(nTime)
|
||
end
|
||
elseif nLine == 2 then
|
||
local nTime = 0
|
||
if bOnePage then
|
||
nTime = FALLIN_ALL_TIME / nPageCount
|
||
else
|
||
nTime = FALLIN_TIME
|
||
end
|
||
for i = 1, HULF_PAGE do
|
||
self.sequence:AppendCallback(function()
|
||
NovaAPI.SetCanvasGroupAlpha(self.tbGoItem[i].go.transform:GetComponent("CanvasGroup"), 1)
|
||
self.tbGoItem[i].go:GetComponent("Animator"):Play("gacha_fall_in")
|
||
if i == 1 then
|
||
WwiseAudioMgr:PlaySound("ui_roguelike_gacha_fall_4")
|
||
end
|
||
end)
|
||
self.sequence:AppendInterval(nTime)
|
||
end
|
||
self.sequence:AppendInterval(LINE_SPACE_TIME)
|
||
for i = HULF_PAGE + 1, HULF_PAGE + nLastLine do
|
||
self.sequence:AppendCallback(function()
|
||
NovaAPI.SetCanvasGroupAlpha(self.tbGoItem[i].go.transform:GetComponent("CanvasGroup"), 1)
|
||
self.tbGoItem[i].go:GetComponent("Animator"):Play("gacha_fall_in")
|
||
end)
|
||
self.sequence:AppendInterval(nTime)
|
||
end
|
||
end
|
||
for i = 1, nPageCount do
|
||
self.sequence:AppendCallback(function()
|
||
if self.tbGoItem[i].bSSR then
|
||
WwiseAudioMgr:PlaySound("ui_roguelike_gacha_specialOpen")
|
||
else
|
||
WwiseAudioMgr:PlaySound("ui_roguelike_gacha_commonOpen")
|
||
end
|
||
end)
|
||
self.sequence:AppendInterval(0.05)
|
||
self.sequence:AppendCallback(function()
|
||
if self.tbGoItem[i].bSSR then
|
||
self.tbGoItem[i].go:GetComponent("Animator"):Play("gacha_open_ssr")
|
||
else
|
||
self.tbGoItem[i].go:GetComponent("Animator"):Play("gacha_open_r")
|
||
end
|
||
end)
|
||
self.sequence:AppendInterval(self.tbGoItem[i].bSSR and OPEN_SSR_TIME or OPEN_R_TIME)
|
||
end
|
||
self.sequence:AppendInterval(bLast and 1 or 0.5)
|
||
self.sequence:Append(self._mapNode.rtContent:DOAnchorPos(Vector2(0, 1000), 0.3))
|
||
for i = 1, nPageCount do
|
||
self.sequence:AppendCallback(function()
|
||
NovaAPI.SetCanvasGroupAlpha(self.tbGoItem[i].go.transform:GetComponent("CanvasGroup"), 0)
|
||
end)
|
||
end
|
||
function self.sequence.onComplete()
|
||
callback()
|
||
end
|
||
self.sequence:SetUpdate(true)
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:ShowReward(mapResult)
|
||
local tbReward = self:ProcessResult(clone(mapResult))
|
||
if #tbReward == 0 then
|
||
self:OnBtnClick_Close(nil, false)
|
||
return
|
||
end
|
||
local nListCount = math.ceil(#tbReward / FULL_PAGE)
|
||
self:ProcessListData(tbReward)
|
||
self.gameObject:SetActive(true)
|
||
self:ShowList(nListCount)
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:ShowList(nListCount)
|
||
local nShowOrder = 0
|
||
local function func_ShowList()
|
||
nShowOrder = nShowOrder + 1
|
||
if nShowOrder > nListCount then
|
||
self:OnBtnClick_Close(nil, false)
|
||
return
|
||
end
|
||
local bHulfPage = nListCount == 1 and #self.tbRewardList[1] <= HULF_PAGE
|
||
local bOnePage = nListCount == 1
|
||
self:RefreshListItem(self.tbRewardList[nShowOrder], bHulfPage)
|
||
self:PlayListAni(#self.tbRewardList[nShowOrder], nShowOrder == nListCount, bOnePage, func_ShowList)
|
||
end
|
||
func_ShowList()
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:Awake()
|
||
self.gameObject:SetActive(false)
|
||
self.tbGoItem = nil
|
||
self.tbRewardList = nil
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:OnEnable()
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:OnDisable()
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:OnDestroy()
|
||
end
|
||
function FixedRoguelikeRewardGachaCtrl:OnBtnClick_Close(btn, bNeedStop)
|
||
if self.sequence then
|
||
self.sequence:Kill()
|
||
end
|
||
if bNeedStop then
|
||
WwiseAudioMgr:PlaySound("ui_roguelike_gacha_allStop")
|
||
end
|
||
self.gameObject:SetActive(false)
|
||
self.tbGoItem = nil
|
||
self.tbRewardList = nil
|
||
delChildren(self._mapNode.rtContent)
|
||
EventManager.Hit("CloseRewardGacha")
|
||
end
|
||
return FixedRoguelikeRewardGachaCtrl
|