PGRData/Script/matrix/xui/xuiturntable/XUiTurntableMain.lua

618 lines
22 KiB
Lua
Raw Normal View History

2024-09-01 22:49:41 +02:00
local XUiGridTurntableProgressReward = require("XUi/XUiTurntable/XUiGridTurntableProgressReward")
local Tweening = CS.DG.Tweening
local Quaternion = CS.UnityEngine.Quaternion
local TurntableAngleOffset = CS.XGame.ClientConfig:GetInt("TurntableAngleOffset")
---@class XUiTurntableMain : XLuaUi
---@field _Control XTurntableControl
local XUiTurntableMain = XLuaUiManager.Register(XLuaUi, "UiTurntableMain")
function XUiTurntableMain:OnAwake()
self:RegisterClickEvent(self.BtnTask, handler(self, self.OnBtnTaskClick))
self:RegisterClickEvent(self.BtnOne, handler(self, self.OnOneTurntableClick))
self:RegisterClickEvent(self.BtnTen, handler(self, self.OnTenTurntableClick))
self:RegisterClickEvent(self.BtnDetails, handler(self, self.OnBtnRecordClick))
self:RegisterClickEvent(self.BtnSkip, handler(self, self.OnPopUpClick))
self:RegisterClickEvent(self.PanelObtainpointsTips1, handler(self, self.OnBtnObtainClick))
self:RegisterClickEvent(self.PanelObtainpointsTips2, handler(self, self.OnBtnObtainClick))
end
function XUiTurntableMain:OnStart()
self._LinePool = {}
self._SectorsPool = {}
self._BoxPool = {}
self._EffectPool = {}
self:InitCompnent()
self:InitActivityInfo()
self:InitProgress()
self:UpdateTurntable()
self:UpdateTurntableButton()
self:UpdateRedPoint()
self:UpdateBtnSkip()
self:OnBtnObtainClick()
end
function XUiTurntableMain:OnGetEvents()
return { XEventId.EVENT_FINISH_TASK, XEventId.EVENT_TASK_SYNC }
end
function XUiTurntableMain:OnNotify(evt, ...)
self:UpdateRedPoint()
end
function XUiTurntableMain:InitCompnent()
self.TopController = XUiHelper.NewPanelTopControl(self, self.TopControlWhite, handler(self, self.OnBtnCloseClick),handler(self,self.OnBtnMainClick))
local itemId, _ = self._Control:GetTurntableCost()
local itemCfg = XDataCenter.ItemManager.GetItem(itemId)
if itemCfg then -- 道具过期
if not self.AssetPanel then
self.AssetPanel = XUiHelper.NewPanelActivityAsset({ itemId }, self.PanelSpecialTool)
else
self.AssetPanel:Refresh({ itemId })
end
XDataCenter.ItemManager.AddCountUpdateListener(itemId, function()
self:UpdateTurntableButton()
end, self)
self.PanelSpecialTool.gameObject:SetActiveEx(true)
else
self.PanelSpecialTool.gameObject:SetActiveEx(false)
end
self.BtnSkip:SetButtonState(CS.UiButtonState.Normal)
self.PanelForbidClick.gameObject:SetActiveEx(false)
end
function XUiTurntableMain:InitActivityInfo()
self:RemoveTimer()
self:CountDown()
self.Timer = XScheduleManager.ScheduleForever(function()
self:CountDown()
end, XScheduleManager.SECOND, 0)
end
function XUiTurntableMain:InitProgress()
if not self._rewards then
---@type table<number, XUiGridTurntableProgressReward>
self._rewards = {}
end
local idx = 0
local rewards = self._Control:GetProgressRewards()
for i = #rewards, 1, -1 do
local cell = i == #rewards and self.RewardRoot or XUiHelper.Instantiate(self.RewardRoot, self.RewardRoot.parent)
self._rewards[i] = XUiGridTurntableProgressReward.New(cell, self)
self._rewards[i]:Init(i, rewards[i][1], rewards[i][2])
if self._rewards[i]:GetIsGain() then
idx = idx + 1
end
end
self:UpdateProgressBar()
self:ScrollTo(idx, #rewards)
end
function XUiTurntableMain:UpdateBtnSkip()
self._IsJump = self._Control:GetSkipAnimationValue()
self.BtnSkip:SetButtonState(self._IsJump and CS.UiButtonState.Select or CS.UiButtonState.Normal)
end
function XUiTurntableMain:UpdateTurntableButton()
self._CostItemId, self._OneCoseNum = self._Control:GetTurntableCost()
local icon = XDataCenter.ItemManager.GetItemBigIcon(self._CostItemId)
local itemCount = XDataCenter.ItemManager.GetCount(self._CostItemId)
self.BtnOne:SetNameByGroup(0, XUiHelper.GetText("TurntableRotateTimes", 1))
self.BtnOne:SetNameByGroup(1, itemCount >= self._OneCoseNum and string.format("×%s", self._OneCoseNum) or string.format("<color='#FF0F0F'>×%s</color>", self._OneCoseNum))
self.BtnOne:SetRawImage(icon)
local remain = self._Control:RemainingItemsCount()
local drawNum = self._Control:GetMaxDrawNum()
local isOver = self._Control:IsGoodsGone()
self._MultiTimes = (remain >= drawNum or isOver) and drawNum or remain
self._TenCostNum = self._MultiTimes * self._OneCoseNum
self.BtnTen:SetNameByGroup(0, XUiHelper.GetText("TurntableRotateTimes", self._MultiTimes))
self.BtnTen:SetNameByGroup(1, itemCount >= self._TenCostNum and string.format("×%s", self._TenCostNum) or string.format("<color='#FF0F0F'>×%s</color>", self._TenCostNum))
self.BtnTen:SetRawImage(icon)
end
function XUiTurntableMain:UpdateRedPoint()
local isRed = self._Control:CanTaskRewardGain(1) or self._Control:CanTaskRewardGain(2)
self.BtnTask:ShowReddot(isRed)
end
function XUiTurntableMain:UpdateTurntable()
local goods = {}
local totalAverage = 0
local totalAngle = 0
local isOver = self._Control:IsGoodsGone()
self._IdMap = {}
self._EffectPool = {}
self._Config = self._Control:GetTurntableRewards()
for _, config in pairs(self._Config) do
local hasGainTimes = self._Control:GetItemGainTimes(config.Id)
local remindTimes = isOver and config.CanGainTimes or config.CanGainTimes - hasGainTimes
if remindTimes > 0 then
table.insert(goods, { config.Id, config.InitialAngle })
self._IdMap[config.Id] = #goods
else
totalAverage = totalAverage + config.InitialAngle
end
totalAngle = totalAngle + config.InitialAngle
end
-- 如果策划配置错误 全部角度加起来不是360° 则log提示
if totalAngle ~= 360 then
XLog.Error("角度配置错误了,总角度是" .. totalAngle .. ",不是360°")
end
-- 已经抽取完的道具的角度要平均到其他道具上面
if totalAverage > 0 then
local average = totalAverage / #goods
for i, _ in ipairs(goods) do
goods[i][2] = goods[i][2] + average
end
end
table.sort(goods, function(a, b)
return a[1] < b[1]
end)
self._LightMap = {}
---@type number[]
self._RotationTb = {}
self._RotateOffect = 360 - self.PanleRing.localEulerAngles.z -- 大转盘本身有角度
local rotation = 270
for i, info in ipairs(goods) do
local light = {}
local angle = info[2]
local cfg = self._Control:GetTurntableById(info[1])
-- 设置扇形
local sector = self._SectorsPool[i]
if not sector then
sector = i == 1 and self.Sector or XUiHelper.Instantiate(self.Sector, self.Sector.parent)
self._SectorsPool[i] = sector
end
local fillAmount = angle / 360
self:SetSector(sector, cfg, fillAmount, rotation, isOver, light)
-- 设置扇形边线
local line = self._LinePool[i]
if not line then
line = i == 1 and self.ImgLine or XUiHelper.Instantiate(self.ImgLine, self.ImgLine.parent)
self._LinePool[i] = line
end
self:SetLine(line, rotation)
-- 设置文本和道具
local box = self._BoxPool[i]
if not box then
box = i == 1 and self.PanelIcon or XUiHelper.Instantiate(self.PanelIcon, self.PanelIcon.parent)
self._BoxPool[i] = box
end
local boxRotation = rotation - angle / 2 - 180
self:SetItem(box, cfg, boxRotation, isOver)
-- 指针经过时高亮
light.startRotation = rotation
light.endRotation = rotation - angle
table.insert(self._LightMap, light)
rotation = rotation - angle
self._RotationTb[i] = rotation
end
-- 隐藏
for i = #goods + 1, #self._SectorsPool do
self._SectorsPool[i].gameObject:SetActiveEx(false)
end
local idx = #goods <= 1 and 1 or #goods + 1 -- 只有1种道具时不需要显示边线
for i = idx, #self._LinePool do
self._LinePool[i].gameObject:SetActiveEx(false)
end
for i = #goods + 1, #self._BoxPool do
self._BoxPool[i].gameObject:SetActiveEx(false)
end
self.BoxArrow.localRotation = Quaternion.Euler(0, 0, 0)
self.TxtTimes.text = XUiHelper.GetText("TurntableTimes", self._Control:GetRotateTimes())
self.RawImageZz.gameObject:SetActiveEx(isOver)
end
function XUiTurntableMain:SetSector(sector, cfg, fillAmount, rotation, isOver, light)
sector.gameObject:SetActiveEx(true)
local uiObject = {}
XTool.InitUiObjectByUi(uiObject, sector)
uiObject.Sector.localRotation = Quaternion.Euler(0, 0, rotation)
local showSectors = {}
showSectors[XEnumConst.Turntable.RewardType.Main] = uiObject.RingHuang
showSectors[XEnumConst.Turntable.RewardType.Height] = uiObject.RingZi
showSectors[XEnumConst.Turntable.RewardType.Simple] = uiObject.RingLan
local lights = {}
lights[XEnumConst.Turntable.RewardType.Main] = uiObject.RingHuangLight
lights[XEnumConst.Turntable.RewardType.Height] = uiObject.RingZiLight
lights[XEnumConst.Turntable.RewardType.Simple] = uiObject.RingLanLight
local masks = {}
masks[XEnumConst.Turntable.RewardType.Main] = uiObject.RingHuangKong
masks[XEnumConst.Turntable.RewardType.Height] = uiObject.RingZiKong
masks[XEnumConst.Turntable.RewardType.Simple] = uiObject.RingLanKong
for type, img in pairs(showSectors) do
if type == cfg.RewardType then
if isOver then
img.gameObject:SetActiveEx(false)
else
img.gameObject:SetActiveEx(true)
end
img.fillAmount = fillAmount
else
img.gameObject:SetActiveEx(false)
end
end
for type, img in pairs(lights) do
if type == cfg.RewardType then
img.fillAmount = fillAmount
end
img.gameObject:SetActiveEx(false)
end
for type, img in pairs(masks) do
if type == cfg.RewardType then
if isOver then
img.gameObject:SetActiveEx(true)
else
img.gameObject:SetActiveEx(false)
end
img.fillAmount = fillAmount
else
img.gameObject:SetActiveEx(false)
end
end
light.imgCircle = lights[cfg.RewardType]
end
function XUiTurntableMain:SetLine(line, rotation)
line.gameObject:SetActiveEx(true)
line.localRotation = Quaternion.Euler(0, 0, rotation - 180)
end
function XUiTurntableMain:SetItem(box, cfg, boxRotation, isOver)
box.gameObject:SetActiveEx(true)
box.localRotation = Quaternion.Euler(0, 0, boxRotation)
local isMain = cfg.RewardType == XEnumConst.Turntable.RewardType.Main
local uiObject = {}
XTool.InitUiObjectByUi(uiObject, box)
local grid = XUiGridCommon.New(self, isMain and uiObject.Grid256NewBig or uiObject.Grid256NewSmall)
local itemId, itemCount = self._Control:GetItemByRewardId(cfg.RewardId)
local costNum = isOver and 0 or self._Control:GetItemGainTimes(cfg.Id)
local rewardData = XRewardManager.CreateRewardGoods(itemId, itemCount)
grid:Refresh(rewardData)
grid.ImgQuality.gameObject:SetActiveEx(false)
grid:SetName("")
grid:SetProxyClickFunc(function()
self:OnShowItemTip(rewardData)
end)
if isMain then -- 部分道具Icon中心点不对 直接旋转的话位置会有问题 所以这里旋转它的父物体
uiObject.IconDajiangBig.localRotation = Quaternion.Euler(0, 0, self._RotateOffect - boxRotation)
else
uiObject.IconDajiangSmall.localRotation = Quaternion.Euler(0, 0, self._RotateOffect - boxRotation)
end
uiObject.TxtNum.transform.localRotation = Quaternion.Euler(0, 0, self._RotateOffect - boxRotation)
uiObject.TxtNum.text = string.format("×%s", cfg.CanGainTimes - costNum)
uiObject.TxtNum.gameObject:SetActiveEx(not isMain)
uiObject.Grid256NewBig.gameObject:SetActiveEx(isMain)
uiObject.Grid256NewSmall.gameObject:SetActiveEx(not isMain)
uiObject.IconDajiangBig.gameObject:SetActiveEx(isMain)
uiObject.IconDajiangSmall.gameObject:SetActiveEx(not isMain)
if isMain then
self._EffectPool[cfg.Id] = uiObject.PanelEffectBig
else
self._EffectPool[cfg.Id] = uiObject.PanelEffectSmall
end
end
function XUiTurntableMain:UpdateProgress()
for _, reward in pairs(self._rewards) do
reward:Update()
end
self:UpdateProgressBar()
end
function XUiTurntableMain:UpdateProgressBar()
local rewards = self._Control:GetProgressRewards()
local space = self.RewardRoot.sizeDelta.y
local totalHeight = space * (#rewards - 1) + 60
local ratio = 60 / totalHeight -- 第一部分比其他的短
local min = rewards[1][2]
local max = rewards[#rewards][2]
local times = self._Control:GetRotateTimes()
local value = 0
if times <= min then
value = times / min * ratio
else
value = (times - min) / (max - min) * (1 - ratio) + ratio
end
self.ImgProgress.fillAmount = value
end
function XUiTurntableMain:ScrollTo(idx, total)
local cellHeight = self.RewardRoot.sizeDelta.y
local scrollHeight = cellHeight * total - self.View.sizeDelta.y
self.ScrollView.verticalNormalizedPosition = math.min(1, idx * cellHeight / scrollHeight)
end
function XUiTurntableMain:OnShowItemTip(data)
if self._IsTweening then
return
end
XLuaUiManager.Open("UiTip", data)
end
function XUiTurntableMain:OnBtnStartClick(isTen)
if self._IsTweening then
return
end
if self._Control:IsGoodsGone() then
XUiManager.TipError(XUiHelper.GetText("TurntableNoItemTip"))
return
end
local ownItemCount = XDataCenter.ItemManager.GetCount(self._CostItemId)
local spendCount = isTen and self._TenCostNum or self._OneCoseNum
if ownItemCount < spendCount then
local itemName = XDataCenter.ItemManager.GetItemName(self._CostItemId)
XUiManager.TipError(XUiHelper.GetText("MoeWarDailyVoteItemNotEnoughTip", string.format("【%s】", itemName)))
return
end
local count = isTen and self._MultiTimes or 1
self._Control:RequestDrawReward(count, function(records)
self:StartRotate(records)
end)
end
function XUiTurntableMain:StartRotate(records)
self:OnTurntableStart()
local dim = nil
local dimRewardId = nil
for _, v in pairs(records) do
local cfg = self._Control:GetTurntableById(v.Id)
if not dim and cfg.RewardType == XEnumConst.Turntable.RewardType.Main then
dimRewardId = v.Id
dim = self._IdMap[dimRewardId]
end
end
if not dim then
dimRewardId = records[1].Id
dim = self._IdMap[dimRewardId]
end
local cur = dim == 1 and self._RotationTb[#self._RotationTb] or self._RotationTb[dim - 1]
local next = dim == 1 and self._RotationTb[dim] - 360 or self._RotationTb[dim]
local range = math.floor(math.abs(cur - next))
local random
if range > TurntableAngleOffset * 2 then
random = math.ceil(next) + math.random(TurntableAngleOffset, range - TurntableAngleOffset)
else
random = math.ceil(next) + math.random(0, range)
end
local rotation = 180 + random - 360 * 8
if self._IsJump then
self:PlayEndEffect(records, dimRewardId)
self:OnTurntableEndUpdate()
else
self.BoxArrow:DOLocalRotate(CS.UnityEngine.Vector3(0, 0, rotation), 6, Tweening.RotateMode.FastBeyond360):SetEase(Tweening.Ease.OutQuart):OnUpdate(function()
self:ShowLight() -- 指针所指区域高亮
end):OnComplete(function()
self:PlayEndEffect(records, dimRewardId)
self:OnTurntableEndUpdate()
self:PlayEndAnimation()
end)
self:PlayStartAnimation()
end
end
function XUiTurntableMain:PlayStartAnimation()
self.Spine = self.PanelSpine:LoadSpinePrefab(self.PanelSpine.AssetUrl):GetComponent("SkeletonGraphic")
if self.Spine then
self.Spine.AnimationState:SetAnimation(0, "idle2", true)
end
self:PlayAnimation("ChoukaShake")
end
function XUiTurntableMain:PlayEndAnimation()
if self.Spine then
self.Spine.AnimationState:SetAnimation(0, "idle", true)
end
end
function XUiTurntableMain:PlayEndEffect(records, dim)
self._IsTweening = false
local effectPanel = self._EffectPool[dim]
if effectPanel then
effectPanel.gameObject:SetActiveEx(true)
self._EffectTimer = XScheduleManager.ScheduleOnce(function()
effectPanel.gameObject:SetActiveEx(false)
self:OnTurntableEnd(records)
end, 1000)
else
self:OnTurntableEnd(records)
end
if self.RawImageLight then
self._ImgShowTimer = XScheduleManager.ScheduleOnce(function()
self.RawImageLight.gameObject:SetActiveEx(true)
self._ImgHideTimer = XScheduleManager.ScheduleOnce(function()
self.RawImageLight.gameObject:SetActiveEx(false)
end, 900)
end, 100)
end
end
function XUiTurntableMain:OnTurntableEndUpdate()
self:UpdateProgress()
self:UpdateTurntableButton()
self:UpdateRedPoint()
end
function XUiTurntableMain:OnTurntableStart()
self._IsTweening = true
self.BtnSkip.enabled = false
self.PanelForbidClick.gameObject:SetActiveEx(true)
self:SetIsRewardCanGain()
end
function XUiTurntableMain:OnTurntableEnd(records)
self.BtnSkip.enabled = true
self.PanelForbidClick.gameObject:SetActiveEx(false)
self:ShowRewardTip(records)
self:UpdateTurntable()
self:SetIsRewardCanGain()
end
function XUiTurntableMain:SetIsRewardCanGain()
for _, v in pairs(self._rewards) do
v:SetForbidGain(self._IsTweening)
end
end
function XUiTurntableMain:ShowLight()
if not self._IsTweening then
return
end
local rotation = self.BoxArrow.localEulerAngles.z - 180
if rotation < 0 then
rotation = rotation + 360
end
for _, v in ipairs(self._LightMap) do
local isShow = false
if v.startRotation > 0 and v.endRotation < 0 then
isShow = v.startRotation >= rotation or 360 + v.endRotation < rotation
elseif v.startRotation < 0 and v.endRotation < 0 then
isShow = 360 + v.startRotation >= rotation and 360 + v.endRotation < rotation
else
isShow = v.startRotation >= rotation and v.endRotation < rotation
end
v.imgCircle.gameObject:SetActiveEx(isShow)
end
end
function XUiTurntableMain:ShowRewardTip(records)
local isBigTip = #records > 5
local list = isBigTip and self.ListBig or self.ListSmall
local panel = isBigTip and self.PanelSettllement01 or self.PanelSettllement02
local nameStr = isBigTip and "UiTurntableBig" or "UiTurntableSmall"
self:RefreshTemplateGrids(self.GridGain, records, list, nil, nameStr, function(grid, data)
self:InitReward(grid, data)
end)
panel.gameObject:SetActiveEx(true)
end
function XUiTurntableMain:InitReward(grid, data)
local param = XGoodsCommonManager.GetGoodsShowParamsByTemplateId(data.RewardGoods.TemplateId)
grid.RImgIcon:SetRawImage(param.BigIcon)
grid.TxtScore.text = "×" .. data.RewardGoods.Count
local cfg = self._Control:GetTurntableById(data.Id)
grid.EffectHight.gameObject:SetActiveEx(cfg.RewardType == XEnumConst.Turntable.RewardType.Main)
XUiHelper.SetQualityIcon(self, grid.ImgQuality, param.Quality)
if param.Site and param.Site ~= XEquipConfig.EquipSite.Weapon then
grid.PanelSite.gameObject:SetActiveEx(true)
grid.TxtSite.text = "0" .. param.Site
else
grid.PanelSite.gameObject:SetActiveEx(false)
end
end
function XUiTurntableMain:OnBtnCloseClick()
if self._IsTweening then
return
end
self:Close()
end
function XUiTurntableMain:OnBtnMainClick()
if self._IsTweening then
return
end
XLuaUiManager.RunMain()
end
function XUiTurntableMain:OnOneTurntableClick()
self:OnBtnStartClick(false)
end
function XUiTurntableMain:OnTenTurntableClick()
self:OnBtnStartClick(true)
end
function XUiTurntableMain:OnBtnRecordClick()
if self._IsTweening then
return
end
if not XLuaUiManager.IsUiShow("UiTurntableLog") then
self:OpenOneChildUi("UiTurntableLog", self)
end
self:FindChildUiObj("UiTurntableLog"):Refresh(true)
end
function XUiTurntableMain:OnBtnTaskClick()
if self._IsTweening then
return
end
if not XLuaUiManager.IsUiShow("UiTurntableTask") then
self:OpenOneChildUi("UiTurntableTask", self)
end
self:FindChildUiObj("UiTurntableTask"):Refresh(true)
end
function XUiTurntableMain:OnPopUpClick()
self._IsJump = self.BtnSkip:GetToggleState()
self._Control:SaveSkipAnimationValue(self._IsJump)
end
function XUiTurntableMain:OnBtnObtainClick()
self.PanelSettllement01.gameObject:SetActiveEx(false)
self.PanelSettllement02.gameObject:SetActiveEx(false)
end
function XUiTurntableMain:OnDestroy()
self._LinePool = {}
self._SectorsPool = {}
self._BoxPool = {}
self._IsTweening = false
self:RemoveTimer()
self._Control:SignDontShow72hoursRedPoint()
end
function XUiTurntableMain:RemoveTimer()
if self.Timer then
XScheduleManager.UnSchedule(self.Timer)
end
if self._EffectTimer then
XScheduleManager.UnSchedule(self._EffectTimer)
end
if self._ImgShowTimer then
XScheduleManager.UnSchedule(self._ImgShowTimer)
end
if self._ImgHideTimer then
XScheduleManager.UnSchedule(self._ImgHideTimer)
end
self.Timer = nil
self._EffectTimer = nil
self._ImgShowTimer = nil
self._ImgHideTimer = nil
end
function XUiTurntableMain:CountDown()
local time = self._Control:EndTime()
if time > 0 then
self.TxtTime.text = XUiHelper.GetText("TurntableTime", XUiHelper.GetTime(time, XUiHelper.TimeFormatType.CHATEMOJITIMER))
else
XLog.Debug("大转盘活动结束,自动关闭界面.")
self:Close()
end
end
return XUiTurntableMain