GameEndManager = LuaClass("GameEndManager") GameEndManager.HasTriggered = false function GameEndManager:Init() self.HasTriggered = false EventSystem:AddListener(EventType.OnSendGameEnd, GameEndManager.OnReceiveGameEnd, self) end function GameEndManager:OnReceiveGameEnd(EndReason) if self.HasTriggered then return end self.HasTriggered = true local GameState = UGCGameSystem.GameState GameState.GameStage = EGameStage.GameEnd GameState.GameEndTimeStamp = GameplayStatics.GetRealTimeSeconds(GameState) local NoticeStr = "" if EndReason == "LastBossDefeated" then GameState:SetIsGameWin(true) NoticeStr = "已击败最终首领,游戏胜利!" elseif EndReason == "TimeOut" then GameState:SetIsGameWin(false) NoticeStr = "时间已耗尽,游戏失败!" elseif EndReason == "ChickenDead" then GameState:SetIsGameWin(false) NoticeStr = "光子鸡被击败,游戏结束!" elseif EndReason == "AllPlayerExited" then GameState:SetIsGameWin(false) NoticeStr = "所有玩家已退出游戏,游戏自动结算!" end NoticeTipsTools.MulticastGeneralNoticeTips(NoticeStr, true, 3.0) UE.Log("[GameEndManager][OnReceiveGameEnd] NoticeStr: %s", NoticeStr) self:ClearAllMonsters() self:SendGameResultData() self:SendUGCModeBattleResult() UGCGameSystem.SendModeCustomEvent("GameEnd") end function GameEndManager:ClearAllMonsters() local GameState = UGCGameSystem.GameState if not GameState then return end local AllSpawners = GameState:GetAllSpawners() for _, Spawner in pairs(AllSpawners) do local SpawnedMonsters = Spawner.SpawnedMonsters for _, Monster in pairs(SpawnedMonsters) do if Monster ~= nil and UE.IsValid(Monster) and Monster:IsAlive() then Monster:K2_DestroyActor() end end Spawner.SpawnedMonsters = {} Spawner.IsActivate = false end end --发送游戏结算 function GameEndManager:SendGameResultData() print(string.format("[GameEndManager:SendGameResultData] 执行")) local GameState = UGCGameSystem.GameState if not GameState then return false end local GameResultData = {}; GameResultData.IsWin = GameState:GetIsGameWin() GameResultData.GameDifficulty = GameState.GameDifficulty GameResultData.GameDuration = GameState:GetGameDuration() GameResultData.PlayerResultDatas = {} SoundManager.MulticastPlaySound2D(GameResultData.IsWin and 1 or 2) local GameTotalDamage = 0.0 for PlayerKey, DamageInfoList in pairs(UGCGameSystem.GameState.PlayerDamageList) do for BossID, DamageValue in pairs(DamageInfoList) do GameTotalDamage = GameTotalDamage + DamageValue end end local PlayerStates = UGCGameSystem.GetAllPlayerState(false); UE.Log("[GameEndManager][SendGameResultData] PlayerState Count=%d", table.getCount(PlayerStates)) --获取所有玩家信息并汇总 for i, PlayerState in ipairs(PlayerStates) do if PlayerState then print(string.format('[GameEndManager][SendGameResultData] 序号: %d', i)) local PlayerResultData = {} local PlayerGlobalSaveData = {} PlayerResultData.UID = PlayerState.UID PlayerResultData.PlayerKey = PlayerState.PlayerKey PlayerResultData.PlayerName = PlayerState.PlayerName PlayerResultData.Level = PlayerState.Level PlayerResultData.CombatPoint = PlayerState.CombatPoint PlayerResultData.Gender = PlayerState.PlatformGender -- 计算 PlayerState里面的存档数据 PlayerGlobalSaveData.UID = PlayerState.UID PlayerState.ArchiveData.GameTimes = PlayerState.ArchiveData.GameTimes + 1 -- 判断一下当前有多少个技能 local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerState.PlayerKey) --local AddCount = 0; --log_tree(string.format("[Action_GameEnd:SendGameResultData] PlayerKey = %d PC.ItemMap[5] = ", PlayerState.PlayerKey), PC.ItemMap[5]) --for c, v in pairs(PC.ItemMap[5]) do -- if GetItemQualityLevel(c) == EQualityType.Super then -- AddCount = AddCount + v; -- end --end -- 判断当前装备了几个技能 --local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerState.PlayerKey); -- Slot: SkillInst --log_tree(string.format("[Action_GameEnd:SendGameResultData] PlayerKey = %d Pawn.SkillSystemComponent.SlotToSkillList = ", PlayerState.PlayerKey), Pawn.SkillSystemComponent.SlotToSkillList) --for k, v in pairs(Pawn.SkillSystemComponent.SlotToSkillList) do -- if v.SkillLevel - 1 == EQualityType.Super then -- AddCount = AddCount + 1 -- end --end --PlayerState.ArchiveData.TotalSuperSkill = PlayerState.ArchiveData.TotalSuperSkill + AddCount; -- 阉割版 if GameResultData.IsWin then -- 阉割版 --PlayerState.ArchiveData.GameClearanceTimes = PlayerState.ArchiveData.GameClearanceTimes + 1 PlayerResultData.Score = 10 + GameState.GameDifficulty * 1 -- 此处计算游戏通关掉落 -- 阉割版 if PlayerState.ArchiveData.GameDropItems == nil then PlayerState.ArchiveData.GameDropItems = {} PlayerState.ArchiveData.GameDropItems[GameState.GameDifficulty] = {} end -- 遍历查找对应数据 local NextDropIndex = 0 local TotalCount = table.getCount(PlayerState.ArchiveData.GameDropItems[GameState.GameDifficulty]) local Temp = {1, 2, 3, 4, 5} if TotalCount > 0 then if TotalCount >= 5 then NextDropIndex = 6 -- 表示掉落碎片 Temp = {} else if table.getCount(PlayerState.ArchiveData.GameDropItems[GameState.GameDifficulty]) == 5 then -- 说明已经满了 NextDropIndex = 6; else local RemovePos = {} for d, v in pairs(PlayerState.ArchiveData.GameDropItems[GameState.GameDifficulty]) do table.insert(RemovePos, d) end for c = 1, #RemovePos, -1 do table.remove(Temp, RemovePos[c]); end end end end if NextDropIndex == 0 then NextDropIndex = Temp[math.random(1, #Temp)] if PlayerState.ArchiveData.GameDropItems[GameState.GameDifficulty] == nil then PlayerState.ArchiveData.GameDropItems[GameState.GameDifficulty] = {} end PlayerState.ArchiveData.GameDropItems[GameState.GameDifficulty][NextDropIndex] = 1 else if PlayerState.ArchiveData.GameDropItems[GameState.GameDifficulty][NextDropIndex] == nil then PlayerState.ArchiveData.GameDropItems[GameState.GameDifficulty][NextDropIndex] = 1 else PlayerState.ArchiveData.GameDropItems[GameState.GameDifficulty][NextDropIndex] = 1 + PlayerState.ArchiveData.GameDropItems[GameState.GameDifficulty][NextDropIndex] end end log_tree("[GameEndManager:SendGameResultData] PlayerState.ArchiveData = ", PlayerState.ArchiveData); else print(string.format("[GameEndManager][SendGameResultData] 游戏输了")) -- 失败积分 PlayerResultData.Score = PlayerState.KillCount.Boss * 2 end print(string.format('[GameEndManager][SendGameResultData] 开始记录存档数据')) PlayerState.ArchiveData.Score = PlayerResultData.Score + PlayerState.ArchiveData.Score; PlayerState.ArchiveData.TotalCoinPoint = PlayerState.ArchiveData.TotalCoinPoint + PlayerState.CoinPoint.Total PlayerState.ArchiveData.TotalKillPoint = PlayerState.ArchiveData.TotalKillPoint + PlayerState.KillPoint.Total PlayerState.ArchiveData.GameTimes = PlayerState.ArchiveData.GameTimes + 1 if GameResultData.IsWin then if PlayerState.ArchiveData.PlayedGames[GameState.GameDifficulty] == nil then PlayerState.ArchiveData.PlayedGames[GameState.GameDifficulty] = 0 end PlayerState.ArchiveData.PlayedGames[GameState.GameDifficulty] = PlayerState.ArchiveData.PlayedGames[GameState.GameDifficulty] + 1 ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](PlayerState, 2); end -- 判断一下一共有多少个通关的 local Times = 0; for c, v in pairs(PlayerState.ArchiveData.PlayedGames) do Times = Times + v; end PlayerState.ArchiveData.GameClearanceTimes = Times; local TotalDamage = 0.0 local DamageInfoList = UGCGameSystem.GameState.PlayerDamageList[PlayerState.PlayerKey] for BossID, DamageValue in pairs(DamageInfoList) do TotalDamage = TotalDamage + DamageValue end -- TODO: 临时数据 PlayerResultData.IsMVP = false PlayerResultData.TotalDamage = TotalDamage PlayerResultData.DamagePercent = GameTotalDamage > 0 and TotalDamage / GameTotalDamage or 0 if GameResultData.IsWin then ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](PlayerState, 5, PlayerResultData.DamagePercent) ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](PlayerState, 8) end log_tree("[GameEndManager][SendGameResultData] PlayerState.ArchiveData = ", PlayerState.ArchiveData) table.insert(GameResultData.PlayerResultDatas, PlayerResultData); -- 同步一下属性 UnrealNetwork.CallUnrealRPC(PC, PC, "Client_UpdateArchiveData", PlayerState.ArchiveData); else UE.Log("[GameEndManager][SendGameResultData] Error: PlayerState is nil!") end end table.sort(GameResultData.PlayerResultDatas,function(a,b) return a.DamagePercent > b.DamagePercent end) if GameResultData.IsWin then GameResultData.PlayerResultDatas[1].IsMVP = true -- 积分 GameResultData.PlayerResultDatas[1].Score = GameResultData.PlayerResultDatas[1].Score + 2 local PS = UGCGameSystem.GetPlayerStateByUID(GameResultData.PlayerResultDatas[1].UID) PS.ArchiveData.Score = PS.ArchiveData.Score + 2 end -- 保存玩家数据到云端 GameState:SavePlayersData(nil) GameState.GameResultData = GameResultData UnrealNetwork.RepLazyProperty(UGCGameSystem.GameState, "GameResultData") --EventSystem:SendEvent(EventType.GameEnd, GameResultData); UnrealNetwork.CallUnrealRPC_Multicast(UGCGameSystem.GameState ,"Client_MulticastRPC_SendEvent", EventType.GameEnd, GameResultData); end --UGC模式结算,发送至后台记录 function GameEndManager:SendUGCModeBattleResult() local PlayerStates = UGCGameSystem.GetAllPlayerState(false) UE.Log("[GameEndManager][SendUGCModeBattleResult] #PlayerStates[%d]", #PlayerStates) for i, PlayerState in ipairs(PlayerStates) do if PlayerState then UGCGameSystem.SendPlayerSettlement(PlayerState.PlayerKey); else UE.Log("[GameEndManager][SendUGCModeBattleResult] Error: PlayerState is nil!") end end end return GameEndManager;