Files
Endfield-Data/LuaScripts/UI/Panels/ItemTips/ItemTipsCtrl.lua
2025-12-02 20:37:18 +07:00

1471 lines
42 KiB
Lua

local uiCtrl = require_ex('UI/Panels/Base/UICtrl')
local PANEL_ID = PanelId.ItemTips
ItemTipsCtrl = HL.Class('ItemTipsCtrl', uiCtrl.UICtrl)
local LIQUID_EMPTY_CAPACITY_TEXT_ID = "LUA_ITEM_TIPS_LIQUID_INFO_EMPTY_CAPACITY"
local LIQUID_FULL_CAPACITY_TEXT_ID = "LUA_ITEM_TIPS_LIQUID_INFO_FULL_CAPACITY"
local LIQUID_EMPTY_NAME_TEXT_ID = "LUA_ITEM_TIPS_LIQUID_INFO_EMPTY_NAME"
local OBTAIN_WAYS_NORMAL_TITLE_TEXT_ID = "ui_common_obtain_method"
local OBTAIN_WAYS_LIQUID_TITLE_TEXT_ID = "ui_common_tips_liquid_obtain_ways"
local PRODUCT_NORMAL_TITLE_TEXT_ID = "ui_common_tips_main_product"
local PRODUCT_LIQUID_TITLE_TEXT_ID = "ui_common_tips_liquid_main_product"
local UIAutoCloseArea = CS.Beyond.UI.UIAutoCloseArea
ItemTipsCtrl.s_messages = HL.StaticField(HL.Table) << {
[MessageConst.HIDE_ITEM_TIPS] = 'HideItemTips',
[MessageConst.TOGGLE_ITEM_TIPS_AUTO_CLOSE] = 'ToggleItemTipsAutoClose',
[MessageConst.ON_ITEM_COUNT_CHANGED] = 'OnItemCountChanged',
[MessageConst.ON_SYSTEM_DISPLAY_SIZE_CHANGED] = 'OnSystemSizeChange'
}
ItemTipsCtrl.m_itemId = HL.Field(HL.String) << ""
ItemTipsCtrl.m_itemCount = HL.Field(HL.Number) << -1
ItemTipsCtrl.m_instId = HL.Field(HL.Number) << 0
ItemTipsCtrl.m_data = HL.Field(HL.Userdata)
ItemTipsCtrl.m_autoCloseTime = HL.Field(HL.Number) << -1
ItemTipsCtrl.m_stopCheckClose = HL.Field(HL.Boolean) << false
ItemTipsCtrl.m_args = HL.Field(HL.Table)
ItemTipsCtrl.m_slotIndex = HL.Field(HL.Number) << -1
ItemTipsCtrl.m_slotCount = HL.Field(HL.Number) << -1
ItemTipsCtrl.m_productCellCache = HL.Field(HL.Forward("UIListCache"))
ItemTipsCtrl.m_tagCellCache = HL.Field(HL.Forward("UIListCache"))
ItemTipsCtrl.m_isShowBlueprintProduct = HL.Field(HL.Boolean) << true
ItemTipsCtrl.m_closeBinding = HL.Field(HL.Number) << -1
ItemTipsCtrl.m_isTipsClosing = HL.Field(HL.Boolean) << false
ItemTipsCtrl.m_controllerSyncPosCor = HL.Field(HL.Thread)
ItemTipsCtrl.m_lockToggleBindingId = HL.Field(HL.Number) << -1
ItemTipsCtrl.OnCreate = HL.Override(HL.Any) << function(self, arg)
self.view.maskBtn.onClick:AddListener(function()
self:_CloseTips(false)
end)
self.view.placeButton.onClick:AddListener(function()
self:_StartPlace()
end)
self.view.splitButton.onClick:AddListener(function()
self:_ShowSplit()
end)
self.view.clearButton.onClick:AddListener(function()
self:_ShowClearBottle()
end)
self.view.jumpButton.onClick:AddListener(function()
self:_TryJump()
end)
self.view.useButton.onClick:AddListener(function()
self:_UseItem()
end)
self.view.wikiBtn.onClick:AddListener(function()
self:_ShowWiki()
end)
self.view.cantPenetrateBtn.onClick:AddListener(function()
self:_CloseTips(false)
end)
self.view.detailScroll.onValueChanged:AddListener(function()
self:_OnDetailScroll()
end)
self.m_closeBinding = self:BindInputPlayerAction("item_tips_close", function()
self:_CloseTips(false)
end)
UIUtils.bindHyperlinkPopup(self, "ItemTips", self.view.inputGroup.groupId, "hyperlink_show_popup")
self.m_extraSafeAreas = {}
self.m_detailContentTopPadding = self.view.detailContentVerticalLayoutGroup.padding.top
self.m_productCellCache = UIUtils.genCellCache(self.view.productNode.itemCell)
self.m_tagCellCache = UIUtils.genCellCache(self.view.tagInfoNode.tagCell)
self.view.itemObtainWays.view.selectableNaviGroup.canFocusFun = function()
return not self:IsPlayingAnimationOut()
end
self.view.itemObtainWays.view.selectableNaviGroup.onIsFocusedChange:AddListener(function(isFocused)
self:_RefreshControllerKeyHint()
end)
self.view.itemObtainWays.view.selectableNaviGroup.onSetLayerSelectedTarget:RemoveAllListeners()
self.view.itemObtainWays.view.selectableNaviGroup.onSetLayerSelectedTarget:AddListener(function(target)
if NotNull(target) then
self.view.detailScroll:AutoScrollToRectTransform(target.transform, true)
end
end)
if BEYOND_DEBUG then
self:_InitTipsDebugBtn()
else
self.view.debugIDButton.gameObject:SetActive(false)
self.view.countNode.debugAddButton.gameObject:SetActive(false)
end
self.m_lockToggleBindingId = self:BindInputPlayerAction("item_lock_toggle", function()
self.view.lockToggle.view.toggle.isOn = not self.view.lockToggle.view.toggle.isOn
end)
self.view.itemFlagNavGroup.onIsFocusedChange:AddListener(function(isTopLayer)
self.view.itemFlagControllerFocusHintNode.gameObject:SetActive(not isTopLayer)
end)
end
ItemTipsCtrl.ShowItemTips = HL.StaticMethod(HL.Table) << function(args)
local isShowing = UIManager:IsShow(PANEL_ID)
local self = UIManager:AutoOpen(PANEL_ID)
if isShowing then
self:_ClearArgs()
if not self:IsPlayingAnimationOut() then
self.m_cachedArgs = args
self:_CloseTips()
else
if self.m_cachedArgs then
if self.m_cachedArgs.onClose then
self.m_cachedArgs.onClose()
end
end
self.m_cachedArgs = args
end
else
self:_ShowTips(args)
end
end
ItemTipsCtrl.OnSystemSizeChange = HL.Method() << function(self)
if self.m_args then
self:_ShowTips(self.m_args)
end
end
ItemTipsCtrl.m_cachedArgs = HL.Field(HL.Table)
ItemTipsCtrl.HideItemTips = HL.Method() << function(self)
local cachedOnClose
if self.m_cachedArgs then
cachedOnClose = self.m_cachedArgs.onClose
self.m_cachedArgs = nil
end
self:_CloseTips()
if cachedOnClose then
cachedOnClose()
end
end
ItemTipsCtrl.m_autoClose = HL.Field(HL.Boolean) << true
ItemTipsCtrl.ToggleItemTipsAutoClose = HL.Method(HL.Any) << function(self, autoClose)
logger.info("ToggleItemTipsAutoClose", inspect(autoClose))
if type(autoClose) == "table" then
self.m_autoClose = unpack(autoClose)
else
self.m_autoClose = autoClose
end
end
ItemTipsCtrl.m_firstShow = HL.Field(HL.Boolean) << true
ItemTipsCtrl._ShowTips = HL.Method(HL.Table) << function(self, args)
self:_ClearArgs()
self.m_args = args
self.m_cachedArgs = nil
if args.safeArea then
self:_AddItemTipsSafeArea(args.safeArea)
end
if self.m_args.includeInAutoCloseLayer ~= false then
UIAutoCloseArea.AddToAutoCloseLayer(self.view.gameObject)
end
self.m_autoCloseTime = -1
local itemId = args.itemId
local instId = args.instId or 0
self.m_itemCount = args.itemCount or -1
if args.slotIndex then
self.m_slotIndex = args.slotIndex
local itemBundle = GameInstance.player.inventory.itemBag:GetOrFallback(Utils.getCurrentScope()).slots[args.slotIndex]
itemId = itemBundle.id
instId = itemBundle.instId
self.m_slotCount = itemBundle.count
else
self.m_slotIndex = -1
self.m_slotCount = -1
end
self:_RefreshContent(itemId, instId)
if not string.isEmpty(args.prefixDesc) then
self.view.prefixDescInfo.gameObject:SetActiveIfNecessary(true)
self.view.prefixDescTxt.gameObject:SetActiveIfNecessary(true)
self.view.prefixDescTxt.text = args.prefixDesc
else
self.view.prefixDescInfo.gameObject:SetActiveIfNecessary(false)
self.view.prefixDescTxt.gameObject:SetActiveIfNecessary(false)
end
if args.autoClose ~= nil then
self:ToggleItemTipsAutoClose(args.autoClose)
else
self:ToggleItemTipsAutoClose(true)
end
UIManager:SetTopOrder(PANEL_ID)
local isFullScreen = self:_IsFullScreen()
self:ChangeCurPanelBlockSetting(isFullScreen)
InputManagerInst:ToggleBinding(self.m_closeBinding, not DeviceInfo.usingController or isFullScreen)
local State = CS.Beyond.UI.CustomUIStyle.OverrideValidState
self.view.maskBtnCustomUIStyle.overrideValidState = self.m_args.isSideTips and State.ForceNotValid or State.None
self.view.cantPenetrateBtn.gameObject:SetActive(args.notPenetrate == true)
self:PlayAnimationIn()
if args.moveVirtualMouse then
InputManagerInst:MoveVirtualMouseTo(self.view.content.transform, self.uiCamera)
end
self:_RefreshControllerKeyHint()
end
ItemTipsCtrl._RefreshControllerKeyHint = HL.Method() << function(self)
if not DeviceInfo.usingController then
self.view.controllerHintBarCell.gameObject:SetActive(false)
return
end
if not self.m_args then
return
end
self.view.controllerHintBarCell.gameObject:SetActive(true)
local groupIds
if self.view.itemObtainWays.view.selectableNaviGroup.IsTopLayer then
groupIds = { self.view.itemObtainWays.view.inputBindingGroupMonoTarget.groupId }
else
groupIds = { self.view.inputGroup.groupId }
if self.m_args.keyHintGroupIds then
groupIds = lume.concat(groupIds, self.m_args.keyHintGroupIds)
end
end
self.view.controllerHintBarCell:InitControllerHintBarCell({ groupIds = groupIds, }, true)
end
ItemTipsCtrl._IsFullScreen = HL.Method().Return(HL.Boolean) << function(self)
return InputManagerInst.usingController and not self.m_args.isSideTips
end
ItemTipsCtrl._ClearArgs = HL.Method() << function(self)
if self.m_args then
if self.m_args.onClose then
self.m_args.onClose()
self.m_args.onClose = nil
end
if self.m_args.safeArea then
self:_RemoveItemTipsSafeArea(self.m_args.safeArea)
end
end
self.m_args = nil
self.m_itemId = ""
self.m_instId = 0
self.m_data = nil
self.m_slotIndex = -1
self.m_slotCount = -1
end
ItemTipsCtrl.OnShow = HL.Override() << function(self)
self:_RegisterCallback()
end
ItemTipsCtrl.OnClose = HL.Override() << function(self)
self:_ClearArgs()
self:_ClearRegister()
end
ItemTipsCtrl.OnHide = HL.Override() << function(self)
self:_ClearArgs()
self:_ClearRegister()
end
ItemTipsCtrl._Update = HL.Method() << function(self)
self:_CheckShouldAutoClose()
end
ItemTipsCtrl.m_craftCellCache = HL.Field(HL.Forward("UIListCache"))
ItemTipsCtrl._RefreshContent = HL.Method(HL.String, HL.Number) << function(self, itemId, instId)
local data = Tables.itemTable:GetValue(itemId)
local itemType = data.type
local maxBackpackStackCount = data.maxBackpackStackCount
self.m_itemId = itemId
self.m_instId = instId
self.m_data = data
UIUtils.displayItemBasicInfos(self.view, self.loader, itemId, instId)
self.view.icon:InitItemIcon(itemId, true, instId)
if self.view.icon.view.liquidIcon then
self.view.icon.view.liquidIcon.gameObject:SetActive(false)
end
self.view.iconImageBlur:OnChangeSprite()
self.view.itemObtainWays.gameObject:SetActive(true)
self.view.itemObtainWays:InitItemObtainWays(itemId, instId)
self.view.stateCtrl:SetState("default")
self.view.itemDescNode:InitItemDescNode(itemId)
self:_RefreshWeaponNode(itemId, instId, itemType)
self:_RefreshEquipNode(itemId, instId, itemType)
self:_RefreshGemNode(itemId, instId, itemType)
self:_RefreshCountNode(itemId, itemType, data.showAllDepotCount)
self:_RefreshTagInfoNode(itemId, itemType)
self:_RefreshProductNode(itemId, itemType)
self:_RefreshEmptyNode(itemId, itemType)
self:_RefreshPickUpNode(itemId)
self:_RefreshLiquidDischargeNode(itemId)
self:_RefreshLiquidInfoNode(itemId, self.m_itemCount)
self:_RefreshShareNode(itemId)
self.view.tipsLimitedTimeNode:InitTipsLimitedTimeNode(itemId, instId or 0, nil)
self.view.wikiBtn.gameObject:SetActive(self:_GetNeedShowWikiBtn())
local isEquip = itemType == GEnums.ItemType.Equip and instId and instId > 0
local isExp = itemType == GEnums.ItemType.CardExp
local isBusinessCardTopic = itemType == GEnums.ItemType.BusinessCardTopic
local jumpText = ""
if isExp then
jumpText = Language.LUA_EXP_CARD_JUMP
elseif isBusinessCardTopic then
jumpText = Language.LUA_BUSINESS_CARD_TOPIC_JUMP
elseif isEquip then
jumpText = Language.LUA_EQUIP_JUMP
end
if not string.isEmpty(jumpText) then
self.view.jumpButton.text = jumpText
end
local hasBottomButton
local isUseItem, _ = Tables.useItemTable:TryGetValue(itemId)
local count = Utils.getItemCount(itemId)
local canUse = isUseItem and self.m_args.canUse and Utils.isSystemUnlocked(GEnums.UnlockSystemType.ItemUse) and count > 0
if canUse and LuaSystemManager.factory.inTopView then
if UIConst.DISABLED_USE_ITEM_ID_IN_TOP_VIEW[itemId] then
canUse = false
end
end
self.view.useButton.gameObject:SetActiveIfNecessary(canUse)
local isBuilding, buildingId = FactoryUtils.isBuilding(itemId)
local canPlace = self.m_args.canPlace and isBuilding and FactoryUtils.canPlaceBuildingOnCurRegion(buildingId)
local canSplit = self.m_args.canSplit and maxBackpackStackCount > 1 and self.m_slotCount > 1
local canJump = self:_CheckIfCanJump(itemId, itemType, instId)
local canClear = self.m_args.canClear and Tables.fullBottleTable:ContainsKey(itemId) and self.m_itemCount > 0
self.view.placeButton.gameObject:SetActive(canPlace)
self.view.splitButton.gameObject:SetActive(canSplit)
self.view.jumpButton.gameObject:SetActive(canJump)
self.view.bottomController:SetState(canJump and "JumpState" or "NormalState")
self.view.dropButton.gameObject:SetActive(false)
self.view.clearButton.gameObject:SetActive(canClear)
hasBottomButton = canPlace or canSplit or canUse or canJump or canClear
self.view.bottomButtons.gameObject:SetActive(hasBottomButton)
self.view.detailScroll.normalizedPosition = Vector2(0, 1)
self:_OnDetailScroll()
local extraHeight = self.view.basicInfoNode.rect.size.y
if hasBottomButton then
extraHeight = extraHeight + self.view.bottomButtons.transform.rect.size.y
end
self.view.detailContentLayoutElement.enabled = false
LayoutRebuilder.ForceRebuildLayoutImmediate(self.view.detailContent)
local detailContentHeight = self.view.detailContent.rect.size.y
local detailShowHeight = lume.clamp(detailContentHeight, self.view.config.MIN_CONTENT_HEIGHT - extraHeight, self.view.config.MAX_CONTENT_HEIGHT - extraHeight)
self.view.detailScrollLayoutElement.preferredHeight = detailShowHeight
local canScroll = detailContentHeight > detailShowHeight
if canScroll then
self.view.detailContentLayoutElement.minHeight = detailShowHeight + self.m_detailContentTopPadding
self.view.detailContentLayoutElement.enabled = true
LayoutRebuilder.ForceRebuildLayoutImmediate(self.view.detailContent)
end
LayoutRebuilder.ForceRebuildLayoutImmediate(self.view.content)
local padding = self.m_args.padding
if not padding then
padding = {
bottom = 50 + (DeviceInfo.usingController and 50 or 0),
}
end
local notchSize = CS.Beyond.DeviceInfoManager.NotchPaddingInCanvas(self.view.transform).x
padding.left = (padding.left or 0) + notchSize
padding.right = (padding.right or 0) + notchSize
UIUtils.updateTipsPosition(self.view.content, self.m_args.transform, self.view.rectTransform, self.uiCamera, self.m_args.posType, padding)
if self.m_args.isSideTips and DeviceInfo.usingController then
self:_ClearCoroutine(self.m_controllerSyncPosCor)
self.m_controllerSyncPosCor = self:_StartCoroutine(function()
while true do
coroutine.step()
if self.m_args ~= nil then
UIUtils.updateTipsPosition(self.view.content, self.m_args.transform, self.view.rectTransform, self.uiCamera, self.m_args.posType, padding)
end
end
end)
end
local isLockToggleVisible = self.view.lockToggle:InitLockToggle(itemId, instId)
local isTrashToggleVisible = self.view.trashToggle:InitTrashToggle(itemId, instId)
local isItemFlagNaviGroupVisible = isLockToggleVisible and isTrashToggleVisible
InputManagerInst:ToggleBinding(self.m_lockToggleBindingId, isLockToggleVisible and not isItemFlagNaviGroupVisible)
self.view.itemFlagNavGroup.enabled = isItemFlagNaviGroupVisible
self.view.itemFlagControllerFocusHintNode.gameObject:SetActive(isItemFlagNaviGroupVisible)
if BEYOND_DEBUG then
self:_RefreshTipsDebugBtn()
end
end
ItemTipsCtrl._RefreshPickUpNode = HL.Method(HL.String) << function(self, itemId)
local isPickUp, _ = Tables.useItemTable:TryGetValue(itemId)
self.view.pickUpNode.gameObject:SetActive(isPickUp)
end
ItemTipsCtrl._RefreshLiquidDischargeNode = HL.Method(HL.String) << function(self, itemId)
local isLiquid = Tables.liquidTable:ContainsKey(itemId)
local canBeDischarge = FactoryUtils.getLiquidCanBeDischarge(itemId)
self.view.emissionNode.gameObject:SetActiveIfNecessary(isLiquid and canBeDischarge)
self.view.emissionForbidNode.gameObject:SetActiveIfNecessary(isLiquid and not canBeDischarge)
end
ItemTipsCtrl._RefreshWeaponNode = HL.Method(HL.String, HL.Number, HL.Userdata) << function(self, itemId, instId, itemType)
local isWeapon = itemType == GEnums.ItemType.Weapon
if not isWeapon then
return
end
self.view.stateCtrl:SetState("weapon")
UIUtils.displayWeaponInfo(self.view, self.loader, itemId, instId)
end
ItemTipsCtrl._RefreshEquipNode = HL.Method(HL.String, HL.Number, HL.Userdata) << function(self, itemId, instId, itemType)
local isEquip = itemType == GEnums.ItemType.Equip
local isEquipFormula = itemType == GEnums.ItemType.EquipFormula
if not isEquip and not isEquipFormula then
return
end
self.view.stateCtrl:SetState("equip")
if isEquipFormula then
local _, equipFormulaData = Tables.equipFormulaTable:TryGetValue(itemId)
if equipFormulaData then
itemId = equipFormulaData.outcomeEquipId
instId = 0
end
end
UIUtils.displayEquipInfo(self.view, self.loader, itemId, instId)
end
ItemTipsCtrl._RefreshGemNode = HL.Method(HL.String, HL.Number, HL.Userdata) << function(self, itemId, instId, itemType)
local isGem = itemType == GEnums.ItemType.WeaponGem
if not isGem then
return
end
self.view.stateCtrl:SetState("weaponGem")
UIUtils.displayWeaponGemInfo(self.view, self.loader, itemId, instId)
end
ItemTipsCtrl._RefreshCountNode = HL.Method(HL.String, HL.Userdata, HL.Boolean) << function(self, itemId, itemType, showAllDepotCount)
local typeData = Tables.itemTypeTable[itemType:ToInt()]
local forceNoCount = typeData.showCountInTips == false
self.view.countNode.gameObject:SetActive(not forceNoCount)
self.view.countSpace.gameObject:SetActive(not forceNoCount)
if forceNoCount then
return
end
if Utils.isInBlackbox() and not UIManager:IsShow(PanelId.RewardsPopUpForBlackBox) then
self.view.countNode.gameObject:SetActiveIfNecessary(false)
self.view.countSpace.gameObject:SetActiveIfNecessary(false)
return
end
local isPlaceInBag = GameInstance.player.inventory:IsPlaceInBag(itemType)
local isMoney = not isPlaceInBag and GameInstance.player.inventory:IsMoneyType(itemType)
local isAdventureExp = itemType == GEnums.ItemType.AdventureExp
local forceShowOwnCount = self.m_args.forceShowOwnCount
if forceShowOwnCount then
self.view.countNode.allOwnCountText.text = Utils.getItemCount(itemId, true, true)
else
if not isMoney then
if isPlaceInBag then
local bagCount = Utils.getBagItemCount(itemId)
self.view.countNode.bagCountText.text = bagCount
local isWeekRaidItem, weekRaidItemData = Tables.weekRaidItemTable:TryGetValue(itemId)
if isWeekRaidItem then
forceShowOwnCount = true
if not string.isEmpty(weekRaidItemData.convertItemId) then
self.view.countNode.allOwnCountText.text = Utils.getItemCount(weekRaidItemData.convertItemId) + bagCount
else
self.view.countNode.allOwnCountText.text = bagCount
end
else
if showAllDepotCount then
self.view.countNode.allDepotCountText.text = Utils.getAllFacDepotItemCount(itemId)
else
self.view.countNode.depotCountText.text = Utils.getDepotItemCount(itemId)
end
end
else
self.view.countNode.valuableCountText.text = Utils.getDepotItemCount(itemId)
end
else
self.view.countNode.valuableCountText.text = Utils.getItemCount(itemId)
end
end
self.view.countNode.valuableInfoNode.gameObject:SetActiveIfNecessary(not forceShowOwnCount and not isPlaceInBag and not isAdventureExp)
self.view.countNode.depotInfoNode.gameObject:SetActiveIfNecessary(not forceShowOwnCount and isPlaceInBag and not showAllDepotCount)
self.view.countNode.allDepotInfoNode.gameObject:SetActiveIfNecessary(not forceShowOwnCount and isPlaceInBag and showAllDepotCount)
self.view.countNode.bagInfoNode.gameObject:SetActiveIfNecessary(not forceShowOwnCount and isPlaceInBag)
self.view.countNode.allOwnInfoNode.gameObject:SetActiveIfNecessary(forceShowOwnCount)
self.view.countNode.gameObject:SetActiveIfNecessary(true)
self.view.countSpace.gameObject:SetActiveIfNecessary(true)
end
ItemTipsCtrl._RefreshProductNode = HL.Method(HL.String, HL.Userdata) << function(self, itemId, itemType)
local productIds = self:_TryGetProductionItemList(itemId)
if productIds then
self.view.productNode.gameObject:SetActive(true)
local count = #productIds
local isShowMoreDeco = count > self.view.config.MAX_BLUEPRINT_PRODUCT_COUNT
local showCount = lume.clamp(count, 0, self.view.config.MAX_BLUEPRINT_PRODUCT_COUNT)
self.m_productCellCache:Refresh(showCount, function(cell, index)
local productId = productIds[index]
local itemData = Tables.itemTable:GetValue(productId)
UIUtils.setItemSprite(cell.icon, productId, self)
UIUtils.setItemRarityImage(cell.rarityLine, itemData.rarity)
UIUtils.setItemRarityImage(cell.rarityLight, itemData.rarity)
end)
self.view.productNode.moreDeco.transform:SetAsLastSibling()
self.view.productNode.moreDeco.gameObject:SetActive(isShowMoreDeco)
else
self.view.productNode.gameObject:SetActive(false)
end
end
ItemTipsCtrl._RefreshEmptyNode = HL.Method(HL.String, HL.Userdata) << function(self, itemId, itemType)
local isShowEmptyNode = self:_CheckIfShowEmptyNode(itemId, itemType)
self.view.emptyNode.gameObject:SetActive(isShowEmptyNode)
end
ItemTipsCtrl._RefreshTagInfoNode = HL.Method(HL.String, HL.Userdata) << function(self, itemId, itemType)
local isShowTagNode, tagList = self:_TryGetTagList(itemId, itemType)
self.view.tagInfoNode.gameObject:SetActive(isShowTagNode)
if isShowTagNode then
local tagCount = tagList.Count
self.m_tagCellCache:Refresh(math.min(tagCount, self.view.config.MAX_TAG_COUNT), function(cell, index)
local tagId = tagList[CSIndex(index)]
local tagData = Tables.factoryIngredientTagTable:GetValue(tagId)
local isShowGreyBg = not (itemType == GEnums.ItemType.NormalBuilding or itemType == GEnums.ItemType.FuncBuilding)
cell.whiteBG.gameObject:SetActive(not isShowGreyBg)
cell.greyBG.gameObject:SetActive(isShowGreyBg)
cell.text.text = tagData.tagLabel
cell.gameObject.name = "Tag-" .. tagId
end)
end
end
ItemTipsCtrl._RefreshLiquidInfoNode = HL.Method(HL.String, HL.Number) << function(self, itemId, itemCount)
local liquidInfoNode = self.view.liquidInfoNode
liquidInfoNode.gameObject:SetActive(false)
self.view.itemObtainWays.view.obtainTitle.text = Language[OBTAIN_WAYS_NORMAL_TITLE_TEXT_ID]
self.view.productNode.title.text = Language[PRODUCT_NORMAL_TITLE_TEXT_ID]
local isSystemUnlocked = Utils.isSystemUnlocked(GEnums.UnlockSystemType.GeneralAbilityFluidInteract)
if not isSystemUnlocked then
return
end
local isEmptyBottle = Tables.emptyBottleTable:ContainsKey(itemId)
local isFullBottle = Tables.fullBottleTable:ContainsKey(itemId)
if not isEmptyBottle and not isFullBottle then
return
end
liquidInfoNode.emptyIcon.gameObject:SetActive(isEmptyBottle)
liquidInfoNode.icon.gameObject:SetActive(isFullBottle)
liquidInfoNode.emptyLine.gameObject:SetActive(isEmptyBottle)
liquidInfoNode.rarityLine.gameObject:SetActive(isFullBottle)
if isEmptyBottle then
local emptyBottleData = Tables.emptyBottleTable[itemId]
local capacity = emptyBottleData.liquidCapacity
liquidInfoNode.capacityTxt.text = string.format(Language[LIQUID_EMPTY_CAPACITY_TEXT_ID], capacity)
liquidInfoNode.nameTxt.text = Language[LIQUID_EMPTY_NAME_TEXT_ID]
end
if isFullBottle then
local fullBottleData = Tables.fullBottleTable[itemId]
local liquidItemId = fullBottleData.liquidId
local liquidSuccess, liquidItemData = Tables.itemTable:TryGetValue(liquidItemId)
if liquidSuccess then
liquidInfoNode.icon:LoadSprite(UIConst.UI_SPRITE_ITEM, liquidItemData.iconId)
liquidInfoNode.nameTxt.text = liquidItemData.name
local rarityColor = UIUtils.getItemRarityColor(liquidItemData.rarity)
liquidInfoNode.rarityLine.color = rarityColor
self.view.itemObtainWays:InitItemObtainWays(liquidItemId)
self:_RefreshProductNode(liquidItemId, liquidItemData.type)
end
local liquidCount = fullBottleData.liquidCapacity
liquidInfoNode.capacityTxt.text = string.format(Language[LIQUID_FULL_CAPACITY_TEXT_ID], liquidCount)
self.view.itemObtainWays.view.obtainTitle.text = Language[OBTAIN_WAYS_LIQUID_TITLE_TEXT_ID]
self.view.productNode.title.text = Language[PRODUCT_LIQUID_TITLE_TEXT_ID]
end
liquidInfoNode.gameObject:SetActive(true)
end
ItemTipsCtrl._RefreshShareNode = HL.Method(HL.String) << function(self, itemId)
local showShareNode = FactoryUtils.isItemSocialBuilding(itemId)
self.view.shareNode.gameObject:SetActive(showShareNode)
end
ItemTipsCtrl._OnDetailContentSizeChanged = HL.Method() << function(self)
self.view.detailContentLayoutElement.enabled = false
LayoutRebuilder.ForceRebuildLayoutImmediate(self.view.detailContent)
local detailContentHeight = self.view.detailContent.rect.size.y
local detailShowHeight = self.view.detailScrollLayoutElement.preferredHeight
local canScroll = detailContentHeight > detailShowHeight
if canScroll then
self.view.detailContentLayoutElement.minHeight = detailShowHeight + self.m_detailContentTopPadding
self.view.detailContentLayoutElement.enabled = true
LayoutRebuilder.ForceRebuildLayoutImmediate(self.view.detailContent)
end
end
ItemTipsCtrl._UpdateCount = HL.Method() << function(self)
self.view.countNode.depotCountText.text = Utils.getDepotItemCount(self.m_itemId)
self.view.countNode.bagCountText.text = Utils.getBagItemCount(self.m_itemId)
end
ItemTipsCtrl._OnClickObtainCell = HL.Method() << function(self)
end
ItemTipsCtrl._CheckShouldAutoClose = HL.Method() << function(self)
if self:_IsFullScreen() then
return
end
if DeviceInfo.usingController then
return
end
if self.m_autoCloseTime > 0 then
if Time.unscaledTime >= self.m_autoCloseTime then
self:_CloseTips()
return
end
end
if self.m_autoClose then
local hasCloseAction, isClick = self:_HasActionOnOtherArea()
if hasCloseAction and (self.m_args.includeInAutoCloseLayer == false
or UIAutoCloseArea.IsTopAutoCloseLayer(self.view.gameObject)) then
if not isClick then
self:_CloseTips()
else
local isClickUp = InputManager.GetMouseButtonUp(0)
if isClickUp then
self.m_autoCloseTime = Time.unscaledTime
else
if self.m_autoCloseTime <= 0 then
self.m_autoCloseTime = Time.unscaledTime + self.view.config.AUTO_CLOSE_DELAY
end
end
end
end
end
end
ItemTipsCtrl._HasActionOnOtherArea = HL.Method().Return(HL.Boolean, HL.Opt(HL.Boolean)) << function(self)
if self.m_stopCheckClose then
return false
end
local scrolling = math.abs(InputManager.mouseScrollDelta.y) > 0
if (InputManager.anyKeyDown and not InputManagerInst.usingController) or scrolling then
local isInputValidInSafeArea = false
if InputManager.IsLeftMouseDown() then
isInputValidInSafeArea = true
elseif InputManager.GetMouseButton(1) then
isInputValidInSafeArea = true
elseif scrolling then
isInputValidInSafeArea = true
end
if not isInputValidInSafeArea then
return true
else
local canvasSize = self.view.rectTransform.rect.size
local mousePos = InputManager.mousePosition
local isClickSelf = UIUtils.isScreenPosInRectTransform(mousePos, self.view.content, self.uiCamera)
if not isClickSelf then
for rect, _ in pairs(self.m_extraSafeAreas) do
local isSafe = UIUtils.isScreenPosInRectTransform(mousePos, rect, self.uiCamera)
if isSafe then
isClickSelf = true
break
end
end
end
return not isClickSelf, true
end
end
return false
end
ItemTipsCtrl._CloseTips = HL.Method(HL.Opt(HL.Boolean)) << function(self, skipAnim)
if UIManager:IsHide(PANEL_ID) or self.m_isTipsClosing then
return
end
local onClose
if self.m_args then
if self.m_args.includeInAutoCloseLayer ~= false then
UIAutoCloseArea.RemoveFromAutoCloseLayer(self.view.gameObject)
end
onClose = self.m_args.onClose
self.m_args.onClose = nil
end
self:_ClearArgs()
if skipAnim then
self:Hide()
self.m_isTipsClosing = false
if onClose then
onClose()
end
else
self.m_isTipsClosing = true
self:PlayAnimationOutWithCallback(function()
self.m_isTipsClosing = false
if self.m_cachedArgs == nil then
self:Hide()
if onClose then
onClose()
end
else
if onClose then
onClose()
end
self:_ShowTips(self.m_cachedArgs)
end
end)
end
end
ItemTipsCtrl.m_extraSafeAreas = HL.Field(HL.Table)
ItemTipsCtrl._AddItemTipsSafeArea = HL.Method(RectTransform) << function(self, rect)
self.m_extraSafeAreas[rect] = true
end
ItemTipsCtrl._RemoveItemTipsSafeArea = HL.Method(RectTransform) << function(self, rect)
self.m_extraSafeAreas[rect] = nil
end
ItemTipsCtrl.m_updateCor = HL.Field(HL.Thread)
ItemTipsCtrl._RegisterCallback = HL.Method() << function(self)
self.m_updateCor = self:_StartCoroutine(function()
coroutine.step()
while true do
coroutine.step()
if self:IsShow() and not self:IsPlayingAnimationOut() then
self:_Update()
end
end
end)
end
ItemTipsCtrl._ClearRegister = HL.Method() << function(self)
self:_ClearCoroutine(self.m_updateCor)
self.m_updateCor = nil
self:_ClearCoroutine(self.m_controllerSyncPosCor)
self.m_controllerSyncPosCor = nil
end
ItemTipsCtrl.OnItemCountChanged = HL.Method(HL.Any) << function(self, arg)
if string.isEmpty(self.m_itemId) then
return
end
local itemId2DiffCount = unpack(arg)
if itemId2DiffCount:ContainsKey(self.m_itemId) then
self:_UpdateCount()
end
end
ItemTipsCtrl._StartPlace = HL.Method() << function(self)
Notify(MessageConst.FAC_ENTER_BUILDING_MODE, {
itemId = self.m_itemId,
slotIndex = self.m_args.slotIndex,
fromDepot = self.m_args.fromDepot,
fastEnter = true,
skipMainHudAnim = true,
})
self:_CloseTips(true)
end
ItemTipsCtrl._TryJump = HL.Method() << function(self)
local canJump, jumpFunction = self:_CheckIfCanJump(self.m_itemId, self.m_data.type, self.m_instId)
if not canJump then
return
end
jumpFunction(self, self.m_itemId, self.m_instId)
if canJump then
self:_CloseTips(true)
end
end
ItemTipsCtrl._UseItem = HL.Method() << function(self)
if UIUtils.useItemOnTip(self.m_itemId) then
self:_CloseTips(true)
end
end
ItemTipsCtrl._ShowSplit = HL.Method() << function(self)
UIUtils.splitItem(self.m_slotIndex)
self:Hide()
end
ItemTipsCtrl._ShowClearBottle = HL.Method() << function(self)
UIManager:Open(PanelId.ClearBottlePopUp, {
slotIndex = self.m_slotIndex,
fromDepot = self.m_args.fromDepot,
itemId = self.m_itemId,
itemCount = self.m_itemCount,
})
self:Hide()
end
ItemTipsCtrl._ShowWiki = HL.Method() << function(self)
if UIManager:ShouldBlockObtainWaysJump() then
Notify(MessageConst.SHOW_TOAST, Language.LUA_OBTAIN_WAYS_JUMP_BLOCKED)
return
end
Notify(MessageConst.SHOW_WIKI_ENTRY, { itemId = self:_GetShowWikiItemId() })
self:_CloseTips(true)
end
ItemTipsCtrl._GetShowWikiItemId = HL.Method().Return(HL.String) << function(self)
local isFullBottle, fullBottleData = Tables.fullBottleTable:TryGetValue(self.m_itemId)
if isFullBottle then
return fullBottleData.emptyBottleId
end
return self.m_itemId
end
ItemTipsCtrl._GetNeedShowWikiBtn = HL.Method().Return(HL.Boolean) << function(self)
local wikiItemId = self:_GetShowWikiItemId()
return WikiUtils.canShowWikiEntry(wikiItemId)
end
ItemTipsCtrl._TryGetTagList = HL.Method(HL.Any, HL.Any).Return(HL.Boolean, HL.Opt(HL.Any)) << function(self, itemId, itemType)
return UIUtils.tryGetTagList(itemId, itemType)
end
ItemTipsCtrl._CheckIfCanJump = HL.Method(HL.String, HL.Userdata, HL.Opt(HL.Number)).Return(HL.Boolean, HL.Opt(HL.Function)) << function(self, itemId, itemType, instId)
if self.m_args and self.m_args.noJump then
return false
end
if UIManager:ShouldBlockObtainWaysJump() then
return false
end
local _, chestData = Tables.usableItemChestTable:TryGetValue(itemId)
if chestData and chestData.type == GEnums.ItemCaseType.SelfSelectedBP then
return true, self._JumpToBattlePassWeaponCase
end
if itemType == GEnums.ItemType.BusinessCardTopic then
return true, self._JumpToBusinessCardTopic
end
if not instId or instId <= 0 then
return false
end
local isWeapon = itemType == GEnums.ItemType.Weapon
if isWeapon then
local weaponInst = CharInfoUtils.getWeaponByInstId(instId)
if weaponInst ~= nil then
return true, self._JumpToWeapon
end
end
local isWeaponGem = itemType == GEnums.ItemType.WeaponGem
if not isWeaponGem then
return false
end
local gemInst = CharInfoUtils.getGemByInstId(instId)
if not gemInst then
return false
end
local weaponInstId = gemInst.weaponInstId
if not weaponInstId or weaponInstId <= 0 then
return false
end
return true, self._JumpToWeaponGem
end
ItemTipsCtrl._JumpToWeaponGem = HL.Method(HL.String, HL.Number) << function(self, gemTemplateId, gemInstId)
local gemInst = CharInfoUtils.getGemByInstId(gemInstId)
if not gemInst then
return
end
local attachedWeaponInstId = gemInst.weaponInstId
if not attachedWeaponInstId then
return
end
local weaponInst = CharInfoUtils.getWeaponByInstId(attachedWeaponInstId)
if not weaponInst then
return
end
CharInfoUtils.openWeaponInfoBestWay({
weaponTemplateId = weaponInst.templateId,
weaponInstId = weaponInst.instId,
pageType = UIConst.WEAPON_EXHIBIT_PAGE_TYPE.GEM
})
end
ItemTipsCtrl._JumpToWeapon = HL.Method(HL.String, HL.Number) << function(self, weaponTemplateId, weaponInstId)
CharInfoUtils.openWeaponInfoBestWay({
weaponTemplateId = weaponTemplateId,
weaponInstId = weaponInstId,
})
end
ItemTipsCtrl._JumpToBusinessCardTopic = HL.Method(HL.String, HL.Number) << function(self, itemId, instId)
for topicId , topicCfg in pairs(Tables.businessCardTopicTable) do
if topicCfg.itemId == itemId then
UIManager:Open(PanelId.FriendThemeChange, { selectId = topicId })
return
end
end
Notify(MessageConst.SHOW_TOAST, Language.LUA_BUSINESS_CARD_TOPIC_NOT_FOUND)
end
ItemTipsCtrl._JumpToBattlePassWeaponCase = HL.Method(HL.String, HL.Number) << function(self, itemId, instId)
UIManager:Open(PanelId.BattlePassWeaponCase, { itemId = itemId, isPreview = true })
end
ItemTipsCtrl._CheckIfShowEmptyNode = HL.Method(HL.Any, HL.Any).Return(HL.Boolean, HL.Opt(HL.Boolean, HL.Any, HL.Any)) << function(self, itemId, itemType)
local showShareNode = FactoryUtils.isItemSocialBuilding(itemId)
if showShareNode then
return false
end
if itemType == GEnums.ItemType.Material or itemType == GEnums.ItemType.NormalBuilding or itemType == GEnums.ItemType.FuncBuilding then
local isShowTagNode = self:_TryGetTagList(itemId, itemType)
local isLiquidRelated = self:_CheckIsLiquidRelatedBottleItem(itemId)
return not isShowTagNode and not isLiquidRelated
end
local isPickUp, _ = Tables.useItemTable:TryGetValue(itemId)
if isPickUp then
return false
end
if itemType == GEnums.ItemType.EquipFormula then
return false
end
if itemType == GEnums.ItemType.Weapon then
return false
end
if itemType == GEnums.ItemType.WeaponGem then
return true
end
if itemType == GEnums.ItemType.Equip then
return false
end
return true
end
ItemTipsCtrl._TryGetProductionItemList = HL.Method(HL.String).Return(HL.Opt(HL.Table)) << function(self, itemId)
return FactoryUtils.getItemProductItemList(itemId)
end
ItemTipsCtrl._CheckIsLiquidRelatedBottleItem = HL.Method(HL.String).Return(HL.Boolean) << function(self, itemId)
if not Utils.isSystemUnlocked(GEnums.UnlockSystemType.GeneralAbilityFluidInteract) then
return false
end
return Tables.emptyBottleTable:ContainsKey(itemId) or Tables.fullBottleTable:ContainsKey(itemId)
end
ItemTipsCtrl.m_detailContentTopPadding = HL.Field(HL.Number) << 0
ItemTipsCtrl._OnDetailScroll = HL.Method() << function(self)
local y = math.max(0, self.m_detailContentTopPadding - self.view.detailContent.anchoredPosition.y)
local percent = 1 - (y / self.m_detailContentTopPadding)
self.view.contentAnimationWrapper:SampleClipAtPercent("item_tips_scroll", percent)
end
ItemTipsCtrl._ToggleProductContent = HL.Method() << function(self)
self.m_isShowBlueprintProduct = not self.m_isShowBlueprintProduct
self.view.productNode.productContent.gameObject:SetActive(self.m_isShowBlueprintProduct)
self.view.productNode.indicatorOn.gameObject:SetActive(not self.m_isShowBlueprintProduct)
self.view.productNode.indicatorOff.gameObject:SetActive(self.m_isShowBlueprintProduct)
end
if BEYOND_DEBUG then
ItemTipsCtrl._InitTipsDebugBtn = HL.Method() << function(self)
self.view.debugIDButton.gameObject:SetActive(true)
self.view.debugIDButton.onClick:AddListener(function()
Unity.GUIUtility.systemCopyBuffer = self.m_itemId
Notify(MessageConst.SHOW_TOAST, string.format("DEBUG: 已复制ID %s", self.m_itemId))
end)
self.view.countNode.debugAddButton.gameObject:SetActive(true)
self.view.countNode.debugAddButton.onClick:AddListener(function()
local itemData = Tables.itemTable[self.m_itemId]
local isMoney = GameInstance.player.inventory:IsMoneyType(itemData.type)
if isMoney then
local msg = CS.Proto.CS_GM_COMMAND()
msg.Command = "AddMoney " .. self.m_itemId .. " 1000000"
CS.Beyond.Network.NetBus.instance.defaultSender:Send(msg)
Notify(MessageConst.SHOW_TOAST, string.format("DEBUG: 支付宝到账 一百万%s", self.m_data.name))
else
local msg = CS.Proto.CS_GM_COMMAND()
msg.Command = "AddItemToItemBagSystem " .. self.m_itemId .. " 50"
CS.Beyond.Network.NetBus.instance.defaultSender:Send(msg)
Notify(MessageConst.SHOW_TOAST, string.format("DEBUG: 已添加道具 %s 50个", self.m_data.name))
end
end)
self.view.countNode.debugAddButton.onLongPress:AddListener(function()
local itemData = Tables.itemTable[self.m_itemId]
local isMoney = GameInstance.player.inventory:IsMoneyType(itemData.type)
if isMoney then
local msg = CS.Proto.CS_GM_COMMAND()
msg.Command = "AddMoney " .. self.m_itemId .. " 1"
CS.Beyond.Network.NetBus.instance.defaultSender:Send(msg)
Notify(MessageConst.SHOW_TOAST, string.format("DEBUG: 支付宝到账 1 %s", self.m_data.name))
else
local msg = CS.Proto.CS_GM_COMMAND()
msg.Command = "AddItemToItemBagSystem " .. self.m_itemId .. " 1"
CS.Beyond.Network.NetBus.instance.defaultSender:Send(msg)
Notify(MessageConst.SHOW_TOAST, string.format("DEBUG: 已添加道具 %s 1", self.m_data.name))
end
end)
end
ItemTipsCtrl._RefreshTipsDebugBtn = HL.Method() << function(self)
self.view.debugIDButton.gameObject:SetActive(not self.m_args.isSideTips)
self.view.countNode.debugAddButton.gameObject:SetActive(not self.m_args.isSideTips)
end
end
HL.Commit(ItemTipsCtrl)