---@class WBP_SettlementPanel_C:UUserWidget ---@field Button_Back UNewButton ---@field Panel_Avatar UWBP_AvatarFrame_C ---@field Panel_Settlement UCanvasPanel ---@field Panel_Waiting UCanvasPanel ---@field PlayerInfoList UVerticalBox ---@field ScrollBox_SaveItems UScrollBox ---@field TextBlock_BackToLobby UTextBlock ---@field TextBlock_Difficulty UTextBlock ---@field TextBlock_GameDuration UTextBlock ---@field TextBlock_GameIsWin UTextBlock ---@field TextBlock_Status UTextBlock ---@field WidgetSwitcher_Save UWidgetSwitcher ---@field WidgetSwitcher_TitleBG UWidgetSwitcher ---@field ItemClass UClass --Edit Below-- local WBP_SettlementPanel = { bInitDoOnce = false; -- 对象池初始化数量 InitCount = 0, FirstOpen = true; -- 存放数组,如果之后需要改变排序,直接改变即可,不需要在计算一遍 SaveGames = { }, }; function WBP_SettlementPanel:Construct() WBP_SettlementPanel.SuperClass.Construct(self); self:BindEvents(); self.ScrollBox_SaveItems:ClearChildren(); end function WBP_SettlementPanel:Destruct() self:UnBindEvents() if self.CountDownHandle ~= nil then EventSystem.StopTimer(self.CountDownHandle) self.CountDownHandle = nil end end function WBP_SettlementPanel:OnShowPanel() self.Panel_Settlement:SetVisibility(ESlateVisibility.Collapsed) self.Panel_Waiting:SetVisibility(ESlateVisibility.SelfHitTestInvisible) local GameResultData = UGCGameSystem.GameState.GameResultData if GameResultData ~= nil and table.isEmpty(GameResultData) == false then self.Panel_Settlement:SetVisibility(ESlateVisibility.SelfHitTestInvisible) self.Panel_Waiting:SetVisibility(ESlateVisibility.Collapsed) self:ShowResult(GameResultData) self:ShowArchive() else if self.WaitTimerHandle ~= nil then EventSystem.StopTimer(self.WaitTimerHandle) end self.WaitTimerHandle = EventSystem.SetTimerLoop(self, function() local GameResultData = UGCGameSystem.GameState.GameResultData if GameResultData ~= nil and table.isEmpty(GameResultData) == false then self.Panel_Settlement:SetVisibility(ESlateVisibility.SelfHitTestInvisible) self.Panel_Waiting:SetVisibility(ESlateVisibility.Collapsed) self:ShowResult(GameResultData) self:ShowArchive() EventSystem.StopTimer(self.WaitTimerHandle) self.WaitTimerHandle = nil end end, 0.1) end local CountDownRemain = 20.0 self.TextBlock_BackToLobby:SetText(string.format("(%d)返回大厅", math.floor(CountDownRemain))) self.CountDownHandle = EventSystem.SetTimerLoop(UGCGameSystem.GameState, function() CountDownRemain = CountDownRemain - 1 self.TextBlock_BackToLobby:SetText(string.format("(%d)返回大厅", math.floor(CountDownRemain))) if CountDownRemain <= 0 then UE.Log("[WBP_SettlementPanel] Auto Back To Lobby") self:OnButtonBackClicked() end end, 1.0) end -- function WBP_SettlementPanel:InitFromParam(GameResultData) -- self:ShowResult(GameResultData) -- self:ShowArchive(); -- end function WBP_SettlementPanel:BindEvents() self.Button_Back.OnClicked:Add(WBP_SettlementPanel.OnButtonBackClicked, self) end function WBP_SettlementPanel:UnBindEvents() self.Button_Back.OnClicked:Remove(WBP_SettlementPanel.OnButtonBackClicked, self) end function WBP_SettlementPanel:ShowResult(GameResultData) --隐藏主UI local PC = STExtraGameplayStatics.GetFirstPlayerController(self) if PC then PC:CastUIMsg("MainControlPanel_HideAllUI", "ingame"); else UE.Log("[WBP_SettlementPanel:ShowResult] Error: PC is nil!") end --TODO: 游戏成功和失败的显示 self.WidgetSwitcher_TitleBG:SetActiveWidgetIndex(GameResultData.IsWin and 0 or 1) self.TextBlock_GameIsWin:SetText(GameResultData.IsWin and "通关" or "失败") self.TextBlock_Status:SetText(GameResultData.IsWin and "守卫光子鸡" or "淘汰") self.TextBlock_Difficulty:SetText(string.format("难%d", GameResultData.GameDifficulty)) self.TextBlock_GameDuration:SetText(string.format("%ds", GameResultData.GameDuration)) local LocalPlayerState = GameDataManager.GetLocalPlayerState() if LocalPlayerState then self:InitAvatar(LocalPlayerState) end self:InitSettlementPlayerList(GameResultData) end function WBP_SettlementPanel:InitAvatar(InPlayerState) local UID = InPlayerState.UID local IconURL = InPlayerState.IconURL local Gender = InPlayerState.PlatformGender local FrameLevel = InPlayerState.SegmentLevel local PlayerLevel = InPlayerState.PlayerLevel self.Panel_Avatar:InitView(UID, IconURL, Gender, FrameLevel, PlayerLevel, true, true) self.Panel_Avatar:SetPlayerName(InPlayerState.PlayerName) end --初始化结算玩家列表 function WBP_SettlementPanel:InitSettlementPlayerList(GameResultData) if next(GameResultData) == nil then return false end if not UE.IsValid(self.ItemClass) then UE.LogError("[WBP_SettlementPanel:InitSettlementPlayerList] ItemClass is invalid") return false end --根据玩家结算数据,创建对应数量的玩家数据UI条目控件 for i, PlayerResultData in pairs(GameResultData.PlayerResultDatas) do local PlayerListItemClass = self.ItemClass local PlayerListItem = UserWidget.NewWidgetObjectBP(UGCGameSystem.GameState, PlayerListItemClass) if PlayerListItem then self.PlayerInfoList:AddChild(PlayerListItem) PlayerListItem:Init(PlayerResultData) else UE.LogError("[WBP_SettlementPanel:InitSettlementPlayerList] PlayerListItem is nil!") end end end function WBP_SettlementPanel:OnButtonBackClicked() EventSystem.StopTimer(self.CountDownHandle) self.CountDownHandle = nil local PlayerController = STExtraGameplayStatics.GetFirstPlayerController(self) if PlayerController then PlayerController:ExitGame() else UE.Log("[WBP_SettlementPanel:OnButtonBackClicked] PlayerController is nil") end UGCGameSystem.ReturnToLobby() end function WBP_SettlementPanel:OnClickSave() if self.WBP_SettleSave:IsVisible() then self.WBP_SettleSave:SetVisibility(ESlateVisibility.Collapsed); else -- 显示结算存档界面 self.WBP_SettleSave:SetVisibility(ESlateVisibility.SelfHitTestInvisible); -- 初始化 self.WBP_SettleSave:ShowArchive(); end end function WBP_SettlementPanel:ShowArchive() print(string.format("[WBP_SettlementPanel:ShowArchive] 进入")) if self.FirstOpen == false then return end self.FirstOpen = false; -- 这里面就是变化,还是要根据每一个具体显示 local Results = self:CompareArchive(); log_tree("[WBP_SettlementPanel:ShowArchive] Results = ", Results); -- 显示存档,根据顺序进行排列 self:ShowItem_GameClearance(Results.GameClearanceDiff); self:ShowItem_Credit(Results.CreditDiff); self:ShowItem_EasterEggs(Results.EasterEggsDiff); self:ShowItem_Achievement(Results.AchievementDiff); self:ShowItem_GameDrop(Results.GameDropDiff); self:ShowItem_BossDrop(Results.BossDropDiff); print(string.format("[WBP_SettlementPanel:ShowArchive] 显示完全")); -- 设置数据 log_tree("[WBP_SettlementPanel:ShowArchive] self.SaveGames = ", self.SaveGames) self:SetItemInfos(); print(string.format("[WBP_SettlementPanel:ShowArchive] 设置完全")); end function WBP_SettlementPanel:SetItemInfos() if #self.SaveGames == 0 then self.WidgetSwitcher_Save:SetActiveWidgetIndex(0); return; end self.WidgetSwitcher_Save:SetActiveWidgetIndex(1) log_tree("[WBP_SettlementPanel:SetItemInfos] self.SaveGames = ", self.SaveGames) local ChildrenCount = self.ScrollBox_SaveItems:GetChildrenCount() local SaveGameCount = #self.SaveGames if ChildrenCount < SaveGameCount then self:InitObjectPool(SaveGameCount - ChildrenCount) end for i, Info in pairs(self.SaveGames) do self.ScrollBox_SaveItems:GetChildAt(i - 1):SetSaveInfo(Info) self.ScrollBox_SaveItems:GetChildAt(i - 1):SetVisibility(ESlateVisibility.SelfHitTestInvisible) end end -- 返回新增的存档,数据结构如下 -- { -- [Difficult] = { Time1 } -- } --- 例如: --- { --- [10] = { 3, 5 } ---} function WBP_SettlementPanel:GameClearanceDiff(InOld, InLast) local Results = {} -- 记录增量变化 -- 去检查一下 ArchiveTable 中当前的存档 local Func = function(InDiff, InTimes) local ValTable = { [InDiff] = {} } ValTable[InDiff] = {} for i, v in pairs(ArchiveTable.GameClearanceRewards[InDiff]) do if InTimes >= i then table.insert(ValTable[InDiff], i); end end return ValTable; end -- InTable: Results; InAddTable: [Diff] = { Times } local AddResultFunc = function(InAddTable) for i, v in pairs(InAddTable) do Results[i] = v end end for Diff, Times in pairs(InLast) do if InOld[Diff] == nil then -- 说明全部是新的 local NewAdd = Func(Diff, Times) AddResultFunc(NewAdd) else -- 判断当前已经打到第几个阶段了 local OldTable = Func(Diff, InOld[Diff]) local NewTable = Func(Diff, Times) -- 做插值 local DiffTable = table.Diff(OldTable, NewTable) AddResultFunc(DiffTable) end end if table.getCount(Results) == 0 then return nil; end return Results; end function WBP_SettlementPanel:CreditDiff(InOld, InLast) local Results = {} -- 获取积分的最大值 local Func = function(Val) local Max = 0 for i, v in pairs(ArchiveTable.CreditRewards) do if v.Reach >= Val then return i - 1 end Max = i; end return Max; end local Old = Func(InOld) local New = Func(InLast) if Old ~= New then for i = Old + 1, New do table.insert(Results, i) end end if table.getCount(Results) == 0 then return nil; end return Results end function WBP_SettlementPanel:EasterEggsDiff(InOld, InLast) local Results = {} for i, v in pairs(InLast) do if v.Active == true and InOld[i].Active == false then table.insert(Results, i) end end return Results; end -- 成就类型: { Val } function WBP_SettlementPanel:AchievementDiff(InKey, InOld, InLast) -- 做成数组 local MakeArrFunc = function(TheKey) local Ret = {} for i, v in pairs(ArchiveTable.AchievementRewards[TheKey]) do Ret[#Ret + 1] = i; --table.insert(Ret, i) end return Ret; end local Arr = MakeArrFunc(InKey) local Func = function(InArr, Val) local Ret = {} for i, v in pairs(InArr) do if Val >= v then Ret[#Ret + 1] = i; -- 添加进去 end end return Ret; end local OldMax = Func(Arr, InOld) local LastMax = Func(Arr, InLast) local Results = {} -- 判断哪些没有 for Index, AchieveIndex in pairs(LastMax) do if OldMax[Index] == nil then Results[#Results + 1] = Arr[AchieveIndex]; end end if table.getCount(Results) == 0 then return nil; end return Results; end -- 游戏掉落物 -- { [Diff] = { Type: Count } } function WBP_SettlementPanel:GameDropDiff(InOld, InLast) local Results = {} for Diff, Table in pairs(InLast) do if InOld[Diff] ~= nil then for Type, Count in pairs(Table) do local OldVal = InOld[Diff][Type] if OldVal == nil then Results[Diff] = { [Type] = Count } else if Count - OldVal ~= 0 then Results[Diff] = { [Type] = Count - OldVal } end end end else Results[Diff] = Table; end end return Results; end function WBP_SettlementPanel:BossDropDiff(InOld, InLast) -- Table: { Type: Count } local Results = {} for BossName, Table in pairs(InLast) do if InOld[BossName] == nil then Results[BossName] = Table else Results[BossName] = {} for Type, Count in pairs(Table) do local OldVal = InOld[BossName][Type] if OldVal == nil then Results[BossName][Type] = Count else if Count - OldVal ~= 0 then Results[BossName][Type] = Count - OldVal; end end end if table.getCount(Results[BossName]) == 0 then Results[BossName] = nil; end end end if table.getCount(Results) == 0 then Results = nil; end return Results; end --比较前后变化 function WBP_SettlementPanel:CompareArchive() print(string.format("[WBP_SettlementPanel:CompareArchive] 执行")) local BeforeArchive = GameDataManager.GetLocalPlayerState().SavedArchiveData print(string.format("[WBP_SettlementPanel:CompareArchive] BeforeArchive")) print(table.logTree(BeforeArchive)); local LastArchive = GameDataManager.GetLocalPlayerState().GameEndSavedArchiveData; print(string.format("[WBP_SettlementPanel:CompareArchive] LastArchive")) print(table.logTree(LastArchive)); log_tree("[WBP_SettlementPanel:CompareArchive] BeforeArchive = ", BeforeArchive); log_tree("[WBP_SettlementPanel:CompareArchive] LastArchive = ", LastArchive); local Results = {} Results.GameClearanceDiff = self:GameClearanceDiff(BeforeArchive["PlayedGames"], LastArchive["PlayedGames"]) --log_tree("[WBP_SettlementPanel:CompareArchive] Results 1111111 = ", Results) Results.CreditDiff = self:CreditDiff(BeforeArchive["Score"], LastArchive["Score"]) --log_tree("[WBP_SettlementPanel:CompareArchive] Results 2222222 = ", Results) Results.EasterEggsDiff = self:EasterEggsDiff(BeforeArchive["EasterEggs"], LastArchive["EasterEggs"]) --log_tree("[WBP_SettlementPanel:CompareArchive] Results 3333333 = ", Results) -- 成就类 Results.AchievementDiff = {} Results.AchievementDiff["通关"] = self:AchievementDiff("通关", BeforeArchive.GameClearanceTimes, LastArchive.GameClearanceTimes) Results.AchievementDiff["击败"] = self:AchievementDiff("击败", BeforeArchive.TotalBossKilledTimes, LastArchive.TotalBossKilledTimes) Results.AchievementDiff["金币"] = self:AchievementDiff("金币", BeforeArchive.TotalCoinPoint / 10000, LastArchive.TotalCoinPoint / 10000) Results.AchievementDiff["科技点"] = self:AchievementDiff("科技点", BeforeArchive.TotalKillPoint, LastArchive.TotalKillPoint) Results.AchievementDiff["技能"] = self:AchievementDiff("技能", BeforeArchive.TotalSuperSkill, LastArchive.TotalSuperSkill) --Results.AchievementDiff["配件"] = self:AchievementDiff("配件", BeforeArchive.TotalSuperFitting, LastArchive.TotalSuperFitting) Results.AchievementDiff["开箱"] = self:AchievementDiff("开箱", BeforeArchive.TotalUnpackTimes, LastArchive.TotalUnpackTimes) --log_tree("[WBP_SettlementPanel:CompareArchive] Results 4444444 = ", Results) Results.GameDropDiff = self:GameDropDiff(BeforeArchive.GameDropItems, LastArchive.GameDropItems) --log_tree("[WBP_SettlementPanel:CompareArchive] Results 5555555 = ", Results) Results.BossDropDiff = self:BossDropDiff(BeforeArchive.BossDropItems, LastArchive.BossDropItems) --log_tree("[WBP_SettlementPanel:CompareArchive] Results 6666666 = ", Results) -- 精简一下 for i, v in pairs(Results) do if table.isEmpty(v) == true then Results[i] = nil; end end print(string.format("[WBP_SettlementPanel:CompareArchive] Result")) print(table.logTree(Results)); log_tree("[WBP_SettlementPanel:CompareArchive] Results = ", Results) return Results; end function WBP_SettlementPanel:GetTypeValue(InArchive, InNum) local Archive = InArchive if InArchive.Type == nil then local Val = '' for i, v in pairs(InArchive) do Val = self:GetTypeValue(v, InNum) .. '\n' .. Val end return Val end if InNum == nil then InNum = 1 end local Num = Archive.Value * InNum local Type = Archive.Type -- 替换掉 % if string.find(Type, '%%') ~= nil then Type = string.gsub(Type, '%%', '') end local Unit = "" if Archive.Unit == '%' then Unit = '%' Num = Num * 100 end if math.type(Archive.Value) == 'float' then Num = string.format("%.2f", Num) elseif math.type(Archive.Value) == 'integer' then Num = string.format("%d", Archive.Value) end return string.format('%s + %s', Type, Num .. Unit) end -- 初始化对象池 function WBP_SettlementPanel:InitObjectPool(InSize) if InSize == nil then InSize = self.InitCount end -- 先清空 self.ScrollBox_SaveItems:ClearChildren() local ClassPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/UI/ChildWidgets/WBP_SettlementSaveItem.WBP_SettlementSaveItem_C') local ItemClass = UE.LoadClass(ClassPath) for i = 1, InSize do local Item = UserWidget.NewWidgetObjectBP(UGCGameSystem.GameState, ItemClass) -- 添加进去 self.ScrollBox_SaveItems:AddChild(Item) -- 设置隐藏 Item:SetVisibility(ESlateVisibility.Collapsed) end end function WBP_SettlementPanel:ShowItem_GameClearance(InData) -- 存放到数组中 if InData == nil then return end for Diff, TimeTable in pairs(InData) do for i, Times in pairs(TimeTable) do -- 处理 Desc local ItemData = { Type = ArchiveTable.ArchiveType.GameClearance, TextVal = string.format("难%d %d次", Diff, Times), Icon = SaveGameConfigs.Icons.GameClearance, Desc = self:GetTypeValue(ArchiveTable.GameClearanceRewards[Diff][Times]) } table.insert(self.SaveGames, ItemData) end end end function WBP_SettlementPanel:ShowItem_Credit(InData) if InData == nil then return end for i, CreditRewardsIndex in pairs(InData) do local ItemData = { Type = ArchiveTable.ArchiveType.Credit, TextVal = tostring(ArchiveTable.CreditRewards[CreditRewardsIndex].Reach), Icon = SaveGameConfigs.Icons.Score, Desc = self:GetTypeValue(ArchiveTable.CreditRewards[CreditRewardsIndex]["Reward"]) } table.insert(self.SaveGames, ItemData) end end function WBP_SettlementPanel:ShowItem_EasterEggs(InData) if InData == nil then return end log_tree("[WBP_SettlementPanel:ShowItem_EasterEggs] InData = ", InData) for i, v in pairs(InData) do local ItemData = { Type = ArchiveTable.ArchiveType.EasterEggs, Desc = self:GetTypeValue(ArchiveTable.EasterEggs[v]["Reward"]), Icon = SaveGameConfigs.Icons.EasterEggs[v], TextVal = ArchiveTable.EasterEggs[v].Name, } table.insert(self.SaveGames, ItemData) end end function WBP_SettlementPanel:ShowItem_Achievement(InData) if InData == nil then return end for Name, ValTable in pairs(InData) do for i, v in pairs(ValTable) do local ItemData = { Type = ArchiveTable.ArchiveType.Achievement, TextVal = ArchiveTable.AchievementRewards[Name][v].Name, Icon = SaveGameConfigs.Icons.Achievements[Name][v], Desc = self:GetTypeValue(ArchiveTable.AchievementRewards[Name][v].Reward), } table.insert(self.SaveGames, ItemData) end end end -- 表示新增的 function WBP_SettlementPanel:ShowItem_GameDrop(InData) if InData == nil then return end -- Diff: 难度;TypeCountTable: 物品:数量 -- 统计所有的 for Diff, TypeCountTable in pairs(InData) do for Type, Count in pairs(TypeCountTable) do local Name = ArchiveTable.DropGameItemIndex[Type] --if self.SaveGames.GameDrop[Name] == nil then -- self.SaveGames.GameDrop[Name] = {} --end local ItemData = { Type = ArchiveTable.ArchiveType.DropGameItems, TextVal = string.format('难%d %s', Diff, Name), Desc = self:GetTypeValue(ArchiveTable.DropGameItems[Name], Diff * Count), Icon = SaveGameConfigs.Icons.GameDropItems[Name], } table.insert(self.SaveGames, ItemData) end end end function WBP_SettlementPanel:ShowItem_BossDrop(InData) if InData == nil then return end -- 检查新增 local Func = function(Index) for c, d in pairs(ArchiveTable.BossDropItemIndexs) do if Index == d then return c end end end for BossName, Table in pairs(InData) do if table.getCount(Table) == 0 then else for i, v in pairs(Table) do local ItemData = { Desc = self:GetTypeValue(ArchiveTable.BossDropItems[BossName][i].Rewards, v), Icon = SaveGameConfigs.Icons.BossDropItems[BossName][i], Type = ArchiveTable.ArchiveType.DropBossItems, TextVal = string.format('%s之%s', BossName, Func(i)) } table.insert(self.SaveGames, ItemData); end end end end return WBP_SettlementPanel;