---@class WBP_Bag_C:UAEUserWidget ---@field CanvasPanel_Buttons UHorizontalBox ---@field CanvasPanel_Operation UCanvasPanel ---@field GeneralSlide_Select UWBP_GeneralSlide_C ---@field Guide_Item_1 UCanvasPanel ---@field Guide_Item_2 UCanvasPanel ---@field Guide_Item_3 UCanvasPanel ---@field Guide_Item_4 UCanvasPanel ---@field Guide_Item_5 UCanvasPanel ---@field Guide_Item_6 UCanvasPanel ---@field Header_Bag UWBP_WidgetHeader_C ---@field HorizontalBox_ItemList UHorizontalBox ---@field OperationButton_Replace UWBP_OperationIcon_C ---@field OperationButton_Reset UWBP_OperationIcon_C ---@field TextBlock_Replace UTextBlock ---@field TextBlock_Reset UTextBlock ---@field TextBlock_Stone UTextBlock ---@field WBP_DropItemWidget UWBP_DropItemWidget_C ---@field WBP_FittingItemInfo UWBP_FittingItemInfo_C ---@field WBP_GenerateAllButton UWBP_GenerateAllButton_C ---@field WBP_GenerateInfo UWBP_GenerateInfo_C --Edit Below-- local WBP_Bag = { bInitDoOnce = false; -- 保存一下数据内容:就是背包中的数据,需要同步的时候改变即可 ItemList = {}, -- 可以通过Id查找到对应的行列,数据类型; {UI, UI, UI, UI} -- 存放所有 Item 的引用 ItemWidgetList = {}, -- 选择三个物品 {{数据, UI}, {数据, UI}, {数据, UI}} SelectedItemList = {}, -- 第一个选择的类型 BagOperateType = EBagOperateType.None, --默认 CurrentItemType = EItemType.SkillBook, OwningPawn = nil, PlayerState = nil, BagWeaponItemClass = nil, AddWeaponTimeHandler = nil, WeaponItemWidgetClass = nil, SelectSkillId = 0; }; function WBP_Bag:Construct() self.Header_Bag:Construct() WBP_Bag.SuperClass.Construct(self) self:BindEvents() self:InitData() --设置基础数据(显示第一个元素的数据) self.WBP_FittingItemInfo:SetVisibility(ESlateVisibility.Collapsed) end function WBP_Bag:OnShowPanel() self:UnbindEvents() self:BindEvents() self:InitData() --设置基础数据(显示第一个元素的数据) self.WBP_FittingItemInfo:SetVisibility(ESlateVisibility.Collapsed) end function WBP_Bag:OnClosePanel() for i = 21, 28 do NewPlayerGuideManager:RemoveGuide(i) end -- 关闭界面 UIManager:ClosePanel(EUIType.UseSkill) end function WBP_Bag:BindEvents() EventSystem:AddListener(EventType.UpdateItemList, WBP_Bag.OnUpdateItemList, self) EventSystem:AddListener(EventType.UpdateStones, WBP_Bag.UpdateResetStone, self) EventSystem:AddListener(EventType.ShowGeneralSlideWidget, WBP_Bag.OnShowGeneralSlideWidget, self) EventSystem:AddListener(EventType.BagOperation, WBP_Bag.OnBagOperate, self) EventSystem:AddListener(EventType.CancelBagOperation, WBP_Bag.OnCancelBagOperation, self) EventSystem:AddListener(EventType.SelectedItem, WBP_Bag.OnSelectedItem, self) EventSystem:AddListener(EventType.SendGeneralSlideNum, WBP_Bag.OnSendGeneralSlideNum, self) EventSystem:AddListener(EventType.ClickTitle, WBP_Bag.OnClickTitle, self) EventSystem:AddListener(EventType.ShowItemDescribe, WBP_Bag.OnShowItemDescribe, self) end function WBP_Bag:Destruct() self:UnbindEvents() end function WBP_Bag:UnbindEvents() EventSystem:RemoveListener(EventType.UpdateItemList, WBP_Bag.OnUpdateItemList, self) EventSystem:RemoveListener(EventType.UpdateStones, WBP_Bag.UpdateResetStone, self) EventSystem:RemoveListener(EventType.ShowGeneralSlideWidget, WBP_Bag.OnShowGeneralSlideWidget, self) EventSystem:RemoveListener(EventType.BagOperation, WBP_Bag.OnBagOperate, self) EventSystem:RemoveListener(EventType.CancelBagOperation, WBP_Bag.OnCancelBagOperation, self) EventSystem:RemoveListener(EventType.SelectedItem, WBP_Bag.OnSelectedItem, self) EventSystem:RemoveListener(EventType.SendGeneralSlideNum, WBP_Bag.OnSendGeneralSlideNum, self) EventSystem:RemoveListener(EventType.ClickTitle, WBP_Bag.OnClickTitle, self) EventSystem:RemoveListener(EventType.ShowItemDescribe, WBP_Bag.OnShowItemDescribe, self) end function WBP_Bag:InitData() self:ListBagItems() self:SetOwningPawn() self:SetIsDrop(false) self.WeaponItemWidgetClass = UE.LoadClass(UGCGameSystem.GetUGCResourcesFullPath('Asset/UI/ChildWidgets/WBP_BagWeaponItem.WBP_BagWeaponItem_C')) -- 设置 Title local ButtonsCount = self.CanvasPanel_Buttons:GetChildrenCount() for i = 1, ButtonsCount do -- 注意此处是从 0 开始的 self.CanvasPanel_Buttons:GetChildAt(i - 1):SetClick(false) end -- 检查一下当前点击的 self.CanvasPanel_Buttons:GetChildAt(0):SetClick(true) -- 将第一个变回去 for i = 1, 6 do self.CanvasPanel_Buttons:GetChildAt(i - 1):SetClick(i - 1 == self.CurrentItemType) end self:UpdateItemMap(self.CurrentItemType) local PS = GameDataManager.GetLocalPlayerState() PS:OnRep_OwnerWeapons() -- 试一下相机旋转 --UGCGameSystem.SetLookInputEventEnable(GameDataManager.GetLocalPlayerController(), false, true) self:UpdateResetStone(nil) end function WBP_Bag:ClearBag() self.ItemList = {} -- 再将所有ItemWidget 清空 self:ClearListBagItems() end function WBP_Bag:UpdateItemMap(InItemType) for i = 22, 28 do NewPlayerGuideManager:RemoveGuide(i) end -- 寻找当前控制的玩家 print(string.format("[WBP_Bag:UpdateItemMap] 执行")) self:ClearBag() -- 清空一下数组 if UE.IsValid(self.OwningPawn) == false or self.OwningPawn == nil then self:SetOwningPawn() end local PC = GameDataManager.GetLocalPlayerController() local ItemMap = PC:GetItemMapByItemType(InItemType) -- i是Id,v是数量 for i, v in pairs(ItemMap) do local Item = { ItemID = i, ItemCount = v } -- 在最后面插入 -- 判断当前数据量 table.insert(self.ItemList, Item) end self:SortItemList(self.ItemList) --设置数据 -- Replace 置换石 self:UpdateStone(EItemType.SubstituteStone, self.TextBlock_Replace) -- Reset 重铸石 self:UpdateStone(EItemType.ScouringStone, self.TextBlock_Reset) self:FillWithData(InItemType, self.ItemList) end function WBP_Bag:UpdateResetStone(InNum) if InNum == nil then InNum = self:GetStoneCount(EItemType.SubstituteStone) if InNum == nil then InNum = 0 end end self.TextBlock_Stone:SetText(string.format("置换石:%d", InNum)) end function WBP_Bag:SortItemList(InList) table.sort(InList, function(a, b) local a_type = GetItemQualityLevel(a.ItemID) local b_type = GetItemQualityLevel(b.ItemID) local _is_type_ = a_type == b_type if _is_type_ then if a.ItemCount == b.ItemCount then return a.ItemID > b.ItemID end return a.ItemCount > b.ItemCount end return a_type > b_type end) end function WBP_Bag:GetStoneCount(InType) local PC = GameDataManager.GetLocalPlayerController() local Stones = PC:GetItemMapByItemType(InType) local ItemCount = 0 if Stones ~= nil then for _, v in pairs(Stones) do ItemCount = ItemCount + v end end return ItemCount end function WBP_Bag:UpdateStone(InType, InItem) InItem:SetText(tostring(self:GetStoneCount(InType))) end function WBP_Bag:SetOwningPawn() self.OwningPawn = GameDataManager.GetLocalPlayerPawn() print(string.format("[WBP_Bag:SetOwningPawn] OwnerName = %s", KismetSystemLibrary.GetObjectName(self.OwningPawn))) end function WBP_Bag:FindItemCountById(InItemId) local PC = GameDataManager.GetLocalPlayerController() local Count = PC:FindItemCount(GetItemTypeByItemId(InItemId), InItemId) return Count end function WBP_Bag:ListBagItems() -- 依次获取 self.ItemWidgetList = {} -- 其实一共24个 local ChildrenCount = self.HorizontalBox_ItemList:GetChildrenCount() for i = 1, ChildrenCount do local ItemList = self.HorizontalBox_ItemList:GetChildAt(i - 1) for j = 1, ItemList:GetChildrenCount() do table.insert(self.ItemWidgetList, ItemList:GetChildAt(j - 1)) end end end function WBP_Bag:ClearListBagItems() for i = 1, #self.ItemWidgetList do self.ItemWidgetList[i]:CloseWidget() end end -- 说明一下 Arr 中包含的数据 -- 再UI中是从上往下进行操作的 -- {{id, count}, {id, count}, ...},该数组必定包含全部配件,如果没有的话就是空的 -- SingleItem 表示一个具体的配件对象 function WBP_Bag:FillWithData(InType, DataArr) -- 首先清空所有 if InType == EItemType.SkillBook then local ActiveSkillNum = 0 for i = 1, #self.ItemWidgetList do if i <= #DataArr then ActiveSkillNum = ActiveSkillNum + 1 self.ItemWidgetList[i]:SetFittingItemData(DataArr[i]) else self.ItemWidgetList[i]:CloseWidget() end end if ActiveSkillNum > 0 then NewPlayerGuideManager:TriggerGuide(22) end return end local ListArr = {} for i = 1, #DataArr do local Data = DataArr[i] local WeaponId = GetItemWeaponTypeByItemId(Data.ItemID) if ListArr[WeaponId] == nil then ListArr[WeaponId] = {} end table.insert(ListArr[WeaponId], Data) end ---- 在此处根据不同类型,塞入不同数据 for i = 1, self.HorizontalBox_ItemList:GetChildrenCount() do local Widget = self.HorizontalBox_ItemList:GetChildAt(i - 1) local Data = ListArr[i] if Data == nil then for j = 1, Widget:GetChildrenCount() do Widget:GetChildAt(j - 1):CloseWidget() end else for j = 1, Widget:GetChildrenCount() do if j <= #Data then Widget:GetChildAt(j - 1):SetFittingItemData(Data[j]) else Widget:GetChildAt(j - 1):CloseWidget() end end end end end -- 通过 Id 找到对应的 WidgetItem function WBP_Bag:GetFittingItemById(InId) for _, v in pairs(self.ItemWidgetList) do if v:GetItemData().ItemID ~= nil and v:GetItemData().ItemID == InId then return v end end return nil end function WBP_Bag:Clear() for i = 1, self.HorizontalBox_ItemList:GetChildrenCount() do local Item = self.HorizontalBox_ItemList:GetChildAt(i - 1) for j = 1, Item:GetChildrenCount() do Item:GetChildAt(j - 1):Clear() end end end -- 显示对应 UI function WBP_Bag:OnShowGeneralSlideWidget(InOperateType, InData) -- 往里面设置数据 self.GeneralSlide_Select:SetSlideValue(InData) self.GeneralSlide_Select:SetOperateType(InOperateType) self.GeneralSlide_Select:SetVisibility(ESlateVisibility.Visible) end function WBP_Bag:OnBagOperate(InType) -- 首先判断一下是否已经点击过其他按钮了 if self.BagOperateType ~= EBagOperateType.None then -- 将其他按钮变回去 for i = 1, 4 do if i ~= InType then self.CanvasPanel_Operation:GetChildAt(i - 1):SetDefaultText() end end if self.BagOperateType == EBagOperateType.Generate then self.WBP_GenerateInfo:Clear() self.WBP_GenerateInfo:SetVisibility(ESlateVisibility.Collapsed) end self.BagOperateType = EBagOperateType.None end -- 分发事件 print(string.format("开始操作:%d", InType)) if InType == EBagOperateType.Generate then --显示框 self.WBP_GenerateInfo:SetVisibility(ESlateVisibility.Visible) --初始化一下 self.WBP_GenerateInfo:Clear() end self.BagOperateType = InType end function WBP_Bag:OnCancelBagOperation(InType) print(string.format("取消操作:%d", InType)) self:CloseOperation(InType) self.WBP_GenerateInfo:OnClickCancel() end -- 这里面是单个 Item 的数据{Id, count} function WBP_Bag:OnSelectedItem(InData) -- 这里处理的是具体选择的数据 if self.BagOperateType == EBagOperateType.None then return elseif self.BagOperateType == EBagOperateType.Generate then self:SelectGenerateItem(InData) elseif self.BagOperateType == EBagOperateType.Drop then -- 判断此时 if InData.ItemCount == 1 then self:OnSendGeneralSlideNum(EBagOperateType.Drop, InData) else self:SelectDropItem(InData) end elseif self.BagOperateType == EBagOperateType.Sell then self:SelectSellItem(InData) elseif self.BagOperateType == EBagOperateType.Reset then -- 置换 -- 不弹框,仅置换第一个,如果背包满了,那就丢到地上 if InData.ItemCount == 1 then self:OnSendGeneralSlideNum(EBagOperateType.Reset, InData) else self:SelectResetItem(InData) end end end function WBP_Bag:SelectGenerateItem(InData) --添加到物品中 self.WBP_GenerateInfo:AddItem(InData) end function WBP_Bag:SelectDropItem(InData) -- 弹框 self:OnShowGeneralSlideWidget(EBagOperateType.Drop, InData) end function WBP_Bag:SelectSellItem(InData) self:OnShowGeneralSlideWidget(EBagOperateType.Sell, InData) end function WBP_Bag:SetIsDrop(IsDrop) if IsDrop then self.WBP_DropItemWidget:SetVisibility(ESlateVisibility.Visible); else self.WBP_DropItemWidget:SetVisibility(ESlateVisibility.Collapsed); end end function WBP_Bag:SelectResetItem(InData) --此时谈一个框吧 -- 首先判断当前置换石的个数 if InData == nil then return end local PC = GameDataManager.GetLocalPlayerController() local Item = PC:GetItemMapByItemType(EItemType.SubstituteStone) -- 32000 local StoneCount = 0 for _, v in pairs(Item) do StoneCount = v end if StoneCount <= 0 then return end --选取一个小的 if InData.ItemCount > StoneCount then InData.ItemCount = StoneCount end self:OnShowGeneralSlideWidget(EBagOperateType.Reset, InData) end function WBP_Bag:GetOperateType() return self.BagOperateType end -- 这是当点击确认操作的时候执行的操作,传进来是一个 数据 function WBP_Bag:OnSendGeneralSlideNum(InOperateType, InData) self.GeneralSlide_Select:SetVisibility(ESlateVisibility.Collapsed) print(string.format("[WBP_Bag:OnSendGeneralSlideNum] OperateType = %d", InOperateType)) local PC = GameDataManager.GetLocalPlayerController() local Pawn = GameDataManager.GetLocalPlayerPawn(); if InOperateType == EBagOperateType.None then return elseif InOperateType == EBagOperateType.Drop then if not Pawn.IsInArena then UIManager:ShowGeneralNotice("在练功房不能丢弃~") return end local DropPos = VectorHelper.Sub(self.OwningPawn:K2_GetActorLocation(), {X = 0, Y = 0, Z = 10}) EventSystem:SendEvent(EventType.SpawnDropItem, DropPos, self.OwningPawn:K2_GetActorRotation(), -1, InData) -- 从背包中移除一个,再刷新当前背包即可 local ItemData = {} ItemData[InData.ItemID] = - InData.ItemCount UnrealNetwork.CallUnrealRPC(PC, PC, "ServerRPC_DiscardItems", ItemData) self:UpdateItemMap(self.CurrentItemType) elseif self.BagOperateType == EBagOperateType.Sell then UnrealNetwork.CallUnrealRPC(PC, PC, "ServerRPC_SellItem", InData) elseif self.BagOperateType == EBagOperateType.Reset then -- 置换 UnrealNetwork.CallUnrealRPC(PC, PC, "ServerRPC_ResetItem", InData) end self:CloseOperation(InOperateType) end function WBP_Bag:OnClickTitle(InFittingType) -- 根据 Item 筛选一下 -- 先将现在的变换一下 self.CanvasPanel_Buttons:GetChildAt(self.CurrentItemType):SetClick(false) if self.CurrentItemType == EItemType.SkillBook then UIManager:HidePanel(EUIType.UseSkill) end self.CurrentItemType = InFittingType self.CanvasPanel_Buttons:GetChildAt(self.CurrentItemType):SetClick(true) self:UpdateItemMap(InFittingType) end function WBP_Bag:OnUpdateItemList(InShow) -- 当显示了再传递 if InShow then self:UpdateItemMap(self.CurrentItemType) else if self:IsVisible() then self:UpdateItemMap(self.CurrentItemType) end end self:UpdateResetStone(nil) end function WBP_Bag:OnShowItemDescribe(InData, InShow) if InShow then print(string.format("[WBP_Bag:OnShowItemDescribe] 执行了该方法,其中 Id = %d, Count = %d", InData.ItemID, InData.ItemCount)) self.WBP_FittingItemInfo:SetInfoItemData(InData, self) self.WBP_FittingItemInfo:SetVisibility(ESlateVisibility.SelfHitTestInvisible) else self.WBP_FittingItemInfo:SetVisibility(ESlateVisibility.Collapsed) end end --重点 function WBP_Bag:CloseOperation(InType) print(string.format('[WBP_Bag:CloseOperation] Type = %d', InType)) self.WBP_FittingItemInfo:SetVisibility(ESlateVisibility.Collapsed) self.WBP_GenerateInfo:SetVisibility(ESlateVisibility.Collapsed) self.CanvasPanel_Operation:GetChildAt(InType - 1):SetDefaultText() self.BagOperateType = EBagOperateType.None end -- 一键合成 function WBP_Bag:GenerateAllItem() -- 传入一个 类型,然后进行合成 local PC = GameDataManager.GetLocalPlayerController() UnrealNetwork.CallUnrealRPC(PC, PC, "ServerRPC_GenerateAllItem", self.CurrentItemType) if self.BagOperateType == EBagOperateType.Generate then -- 关闭 self.CanvasPanel_Operation:OnClickTitle() end UIManager:ClosePanel(EUIType.UseSkill) end function WBP_Bag:GetSelectSkillSlotsXY(InItemWidget) local SelectIndex = 0 for i = 1, #self.ItemWidgetList do if self.ItemWidgetList[i] == InItemWidget then SelectIndex = i break end end local Y = SelectIndex % 6 local X = SelectIndex // 4 return {X = X, Y = Y} end function WBP_Bag:GetAdd() end function WBP_Bag:ShowSelectSkill(IsFullSkill, InFittingData, InPosition) self:InitSelectSkill(InFittingData.ItemID) local CanvasSlot = self.WBP_SelectSkillSlots.Slot CanvasSlot:SetPosition({ X = InPosition.X, Y = InPosition.Y }) self.WBP_SelectSkillSlots:SetVisibility(ESlateVisibility.SelfHitTestInvisible) end function WBP_Bag:HideSelectSkill() UIManager:ClosePanel(EUIType.UseSkill) end function WBP_Bag:OnMouseMove(MyGeometry, MouseEvent) end function WBP_Bag:InitSelectSkill(InId) print(string.format('[WBP_SelectSkillSlots:InitData] 初始化Id = %d', InId)) self.SelectSkillId = InId local PC = GameDataManager.GetLocalPlayerController() local InitiativeSkillSlots = PC:GetInitiativeSkillSlots() if #InitiativeSkillSlots < 3 then -- 此时是 select Button self.WidgetSwitcher_Main:SetActiveWidgetIndex(1) self.WBP_SkillSelectButton:SetSkillId(self.SkillItemId) else self.WidgetSwitcher_Main:SetActiveWidgetIndex(0) self:FillSkillDatas() end end function WBP_Bag:FillSkillDatas() print(string.format('[WBP_SelectSkillSlots:FillDatas] 填充数据')) local PC = GameDataManager.GetLocalPlayerController() local InitiativeSkillSlots = PC:GetInitiativeSkillSlots() print(string.format('[WBP_SelectSkillSlots:FillDatas] 主动技能数量:%d', #InitiativeSkillSlots)) for i = 1, #InitiativeSkillSlots do local Slot = InitiativeSkillSlots[i] if i <= 3 then local ItemId = PC.ActiveSkillNameList[Slot].SkillName * 100 + PC.ActiveSkillNameList[Slot].SkillLevel * 10 + 20000 self.HorizontalBox_Skills:GetChildAt(i - 1):SetLastItemId(ItemId) end end end function WBP_Bag:OnMouseButtonDown(MyGeometry, PointerEvent) WBP_Bag.SuperClass:OnMouseButtonDown(MyGeometry, PointerEvent) UIManager:HidePanel(EUIType.UseSkill) end --当关闭界面的时候执行的函数 function WBP_Bag:OnCloseWidget() UIManager:HidePanel(EUIType.UseSkill) end return WBP_Bag;