diff --git a/SoloKing/Script/Blueprint/UGCPlayerPawn.lua b/SoloKing/Script/Blueprint/UGCPlayerPawn.lua index 6f77e698..c5099499 100644 --- a/SoloKing/Script/Blueprint/UGCPlayerPawn.lua +++ b/SoloKing/Script/Blueprint/UGCPlayerPawn.lua @@ -28,7 +28,7 @@ function UGCPlayerPawn:ReceivePossessed(NewController) end ---@return bool 是否开启掉落盒子 -function UGCPlayerPawn:IsSkipSpawnDeadTombBox(EventInstigater) return DefaultSettings.EnableDeadBox; end +function UGCPlayerPawn:IsSkipSpawnDeadTombBox(EventInstigator) return DefaultSettings.EnableDeadBox; end ----------------------------------------- 玩家伤害处理 ----------------------------------------- @@ -134,10 +134,6 @@ end ---@param slot ESurviveWeaponPropSlot ---@overload fun(slot:ESurviveWeaponPropSlot) OnEquipWeapon function UGCPlayerPawn:OnEquipWeapon(slot) - --UGCLogSystem.Log("[UGCPlayerPawn:OnEquipWeapon] slot = %s, ESurviveWeaponPropSlot.SWPS_HandProp = %d", tostring(slot), ESurviveWeaponPropSlot.SWPS_HandProp); - --if slot == ESurviveWeaponPropSlot.SWPS_HandProp then - -- UGCLogSystem.Log("[UGCPlayerPawn:OnEquipWeapon] 切换成拳头") - --end UGCEventSystem.SendEvent(EventTypes.PlayerChangeWeapon, self, slot, UGCWeaponManagerSystem.GetWeaponBySlot(self, slot)); end @@ -148,15 +144,6 @@ function UGCPlayerPawn:OnPostGetWeapon(Weapon) --- 绑定 delegate if ItemTool.IsShootWeapon(Weapon) then - --- 客户端 - --Weapon.OnBulletNumChangeDelegate:Add(function() - -- UGCLogSystem.Log("[UGCPlayerPawn:OnPostGetWeapon] 子弹数量改变"); - --end, self); - -- - --Weapon.OnWeaponShootDelegate:Add(function() - -- UGCLogSystem.Log("[UGCPlayerPawn:OnPostGetWeapon] 武器开火") - --end, self); - Weapon.OnDSBulletNumChangeDelegate:Add(self.OnBulletNumChanged, self); end end @@ -219,6 +206,30 @@ function UGCPlayerPawn:UpdateSlotWeapons(Weapons) end self:AddAllTelescopes(); self:CheckSlotWeapons(); + + self:ResetAllParts(); +end + +UGCPlayerPawn.ResetPartsTimer = nil; + +--- 重新设置所有的配件 +function UGCPlayerPawn:ResetAllParts() + if self.ResetPartsTimer then + Timer.RemoveTimer(self.ResetPartsTimer); + self.ResetPartsTimer = nil; + end + self.ResetPartsTimer = Timer.InsertTimer(1, function() + for i, Socket in pairs(ShootWeaponEnums) do + local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(self, Socket); + if Weapon ~= nil and UE.IsValid(Weapon) and ItemTool.IsShootWeapon(Weapon) then + local WeaponID = Weapon:GetWeaponItemID(); + local CurrMap = ItemTool.GetWeaponPartMap(Weapon); + local TrueConfig = ArchiveTable[self.PlayerKey].Weapons[WeaponID] + ItemTool.ReuseWeaponParts(Weapon, TrueConfig); + end + end + self.ResetPartsTimer = nil; + end); end function UGCPlayerPawn:AddAllTelescopes() @@ -268,6 +279,7 @@ function UGCPlayerPawn:CheckHasSlotWeapon(Slot, WeaponID) local DefineID = Weapon:GetItemDefineID(); ItemTool.RemoveWeapon(self, Weapon); ItemTool.AddWeaponItem(self, WeaponID, 1, true, EFillBulletType.ClipInfinite); + self:ResetAllParts(); end UGCPlayerPawn.CurrBulletNum = -1; diff --git a/SoloKing/Script/Global/Mini/MiniGameConfig.lua b/SoloKing/Script/Global/Mini/MiniGameConfig.lua deleted file mode 100644 index c212b7d2..00000000 --- a/SoloKing/Script/Global/Mini/MiniGameConfig.lua +++ /dev/null @@ -1,185 +0,0 @@ -require('Script.Global.Table.WeaponTable') ---- 用到的都放在这 -MiniGameMapType = { - SoloKing = 1, -- 和平大乱斗模式 -}; - ---- 是否随机地图 -Mini_RandomMap = false; - ---- 整体进程 ----@type MiniGameState -MiniGameState = { - NON_START = 1, -- 还未开始 - SELECT_GAMES = 2, -- 选择地图截断 - MINI_PREPARE = 3, -- 玩法准备阶段 - --MINI_GAMING = 4, -- 进入玩法游戏阶段 - ROUND_PREPARE = 4, -- 回合准备阶段 - ROUND_GAMING = 5, -- 回合游玩阶段 - ROUND_END = 6, -- 回合结束阶段 - MINI_END = 7, -- 玩法结束阶段 - ENDED = 8, -- 游戏结束阶段 -}; - ---- 小游戏的各种时间 -MiniGameTimes = { - Active = 1, -- 游戏激活时间,游戏激活时间结束后进入游戏阶段 - Prepare = 35, -- 每个玩法准备时间 - RoundPrepare = 2, -- 玩法单个回合开启时间到正式开启时间 - RoundGameTime = -4 * 60, - RoundEnd = 5, -- 玩法单个回合结束到下一个回合开启的时间 - MiniGameEnd = 0, -- 一个玩法结束的时候到下一个小游戏或者游戏结束的时间 - End = 200; -- 结束的时候执行 -}; - -GameStateTimes = { - GangUp = { - SelectMapTime = 12; - } -} - ---- 玩法配置 ---- 可以重写玩法的时间:在单个玩法配置中添加 MiniGameTimes = { Prepare = xxx, } 这种形式即可 -MiniGameConfig = MiniGameConfig or { - [MiniGameMapType.SoloKing] = { - Script = "Solo", -- 会执行的代码文件 - Map = { - -- 按热度排序 - MapName = { - ['Map_SLXLC'] = 1, - ['Map_SMDJ'] = 1, - ['Map_HDDJ'] = 1, - ['Map_JCK'] = 1, - ['Map_DBL'] = 1, - ['Map_SCL'] = 1, - ['Map_NewYear'] = 2, - ['Map_DC'] = 2, - }, - ShowName = "单挑王", -- 显示名称 - }, - --- 小游戏回合次数,如果 <= 1 表示当前游戏只支持单局,且条件为自动设置。 - RoundTimes = 7, - --- 初始给的武器,下面每一条都是要添加的一个初始物品 - InitArmors = { - [1] = EArmorType.Armor3, - [2] = EHelmetType.Helmet3, - [3] = EBagType.Bag1, - }, - InitMedication = { - { "大包", 1, }, -- 10 - { "绷带", 5, }, -- 2 * Num - { "可乐", 3, }, -- 4 * Num - }, - --- 延迟一会后再给的物品 - DelayWeapons = { - { "手榴弹", 1, }, -- 18 - { "烟雾弹", 1, }, -- 14 - { "震爆弹", 1, }, -- 14 - }, - - --- 地图新增物品 - MapAddedItem = { - ['Map_JCK'] = { - { "燃烧瓶", 1 }, - }, - ['Map_DBL'] = { - { "燃烧瓶", 1 }, - }, - ['Map_SCL'] = { - { "燃烧瓶", 1 }, - }, - }, - - --- 游戏参数,会自动展开,如果想要表结构,需要再嵌套一层表 - Params = { - SelectWeaponCount = 7, -- 可以选择武器的个数 - RespawnTime = 2, -- 玩家复活的时间,现在用不到 - KillHealing = 0, -- 击杀可以回复的血量 - KillTimes = 2, -- 击杀多少次当前回合 - ResetTime = 3, -- 重置时间 - SelectMapTime = 8, -- 选择地图时间,正式开始前这么长时间就不允许再选择了 - - EnableInsult = false; -- 是否开启鞭尸 - - DefaultWeapon = 101004, -- 默认初始武器 - - --- 加分方式 - AddFunc = function(Diff, Current, NeedOther) - local Add = 20 - Diff / 100; - Add = math.ceil(Add); - if Add < 5 then Add = 5; end - if Add > 30 then Add = 30; end - - if NeedOther then - if Current < 2200 then - Add = Add + math.random(4, 5); - elseif Current < 3000 then - Add = Add + math.random(1, 2); - --else - -- Add = Add + math.random(0, 1); - end - end - return Add; - end, - - --- 扣分方式 - ReduceFunc = function(Diff, Current) - local Reduce = -20 + Diff / 100; - Reduce = math.floor(Reduce); - if Reduce > -5 then Reduce = -5 end - if Reduce < -30 then Reduce = -30; end - return Reduce; - end, - - SpecialWeapon = { - [EWeaponTypeNew.EWeaponTypeNew_SingleShotSniper] = { - InitArmors = { - [1] = EArmorType.Armor2, - [2] = EHelmetType.Helmet2, - }, - }, - [EWeaponTypeNew.EWeaponTypeNew_Crossbow] = { - InitArmors = { - [1] = EArmorType.Armor2, - [2] = EHelmetType.Helmet2, - }, - }, - [EWeaponTypeNew.EWeaponTypeNew_Melee] = { - InitArmors = { - [1] = EArmorType.Armor1, - [2] = EHelmetType.Helmet1, - }, - }, - } - }; - }, -}; - -GameModeConfig = {} --- 由于顺序问题 这里不可以跳数字 -GameModeConfig.EGameModeType = { - DefaultMode = 1; - GangUpMode = 2; -- 休闲模式 -}; - -GameModeConfig.GameModeInfo = { - [GameModeConfig.EGameModeType.DefaultMode] = { - Name = "经典模式"; - Feature = "·经典和平,双方武器一致。\n·武器从武器池中随机抽取。"; - }, - [GameModeConfig.EGameModeType.GangUpMode] = { - Name = "休闲模式"; - Feature = "·回合武器可自选!\n·不掉分!"; - -- 时间配置 - MiniGameTimes = { - Active = 2, -- 游戏激活时间,游戏激活时间结束后进入游戏阶段 - Prepare = 15, -- 每个玩法准备时间 - RoundPrepare = 2, -- 玩法单个回合开启时间到正式开启时间 - RoundEnd = 5, -- 玩法单个回合结束到下一个回合开启的时间 - MiniGameEnd = 0, -- 一个玩法结束的时候到下一个小游戏或者游戏结束的时间 - End = 50; -- 结束的时候执行 - }, - }, -} - -return MiniGameConfig; \ No newline at end of file diff --git a/SoloKing/Script/Global/Mini/MiniManager.lua b/SoloKing/Script/Global/Mini/MiniManager.lua deleted file mode 100644 index c25be25a..00000000 --- a/SoloKing/Script/Global/Mini/MiniManager.lua +++ /dev/null @@ -1,821 +0,0 @@ -MiniManager = {}; - ----@private string 这是玩家选择的地图,按从前往后开始游玩 -MiniManager.ScriptPath = "Script.Global.Mini.Script.Mini_"; ----@type table 当前所有玩家选择的地图 -MiniManager.SelectMaps = {}; ----@type FMiniGameMapIndex 当前选择的地图 -MiniManager.CurrSelectMap = nil; ----@type UGCGameState_C 默认是 GameSate,如果不是可以在具体实例里面实现对应方法 -MiniManager.Owner = nil; ----@type MiniGameMode 当前小玩法的具体实现,统一入口出口管理 -MiniManager.CurrMiniMode = nil; ----@type int32 目标小游戏数量,低于这个数量会自动添加到这个数量 -MiniManager.TargetMiniGameCount = 1; ----@type MiniGameState 模式状态,可以在本实例和 CurrMiniMode 中获取 -MiniManager.State = 0; ----@type table 玩家数据 -MiniManager.PlayerData = {}; ----@type table 小游戏需要同步的数据,会自动执行 OnRep_xxx 函数 -MiniManager.MiniInfo = {}; - -MiniManager.TimerHandlers = nil; - ------------------------------------ 主要函数 ----------------------------------- - ---- 这是游戏启动,做一些初始化的操作即可 -function MiniManager:Init(InOwner) - UGCLogSystem.Log("[MiniManager:ReceiveBeginPlay] 执行成功 self = %s", tostring(self)); - self.Owner = InOwner; - if MiniGameConfig == nil then - require('Script.Global.Mini.MiniGameConfig'); - UGCLogSystem.LogTree(string.format("[MiniManager:Init] MiniGameConfig ="), MiniGameConfig); - end - if DefaultSettings.EnableTest then - for i, v in pairs(MiniGameConfig) do - v.RoundTimes = 1; - end - - MiniGameTimes.RoundGameTime = -500; - end - UGCEventSystem.AddListener(EventTypes.ClientAlready, self.OnClientAlready, self) - - if IsServer then - self:SetState(MiniGameState.SELECT_GAMES); - - GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t) - o:OnMiniGameTimeCount(t); - end, 1, MiniGameTimes.Active, self.OnGameStart); - else - -- 执行客户端逻辑 - self:MakeCachedMiniInfo(); - end - - -- 组装一下具体函数 - self:MakeRepProps(); -end - -function MiniManager:MakeRepProps() - local Func = function(...) return { ... }; end - local Props = Func(self:GetReplicatedProperties()); - if self.Props == nil then self.Props = {}; end - for i, v in pairs(Props) do self.Props[v] = true; end - UGCLogSystem.LogTree(string.format("[MiniManager:MakeRepProps] self.Props ="), self.Props); -end - -function MiniManager:IsRepProp(InName) - if self.Props == nil then self.Props = {}; end - return self.Props[InName] == true; -end - ---- 本身需要同步的数据放进来 -function MiniManager:GetReplicatedProperties() - return "State" - , "SelectMaps" - , "CurrSelectMap" -end - ---- 客户端准备好了,此时开始有 ServerTime -function MiniManager:OnClientAlready() - -- 显示 - if IsClient then - UGCLogSystem.Log("[MiniManager:OnGameBegin] 显示 UI") - end - - table.func(self.CurrMiniMode, "OnClientAlready") -end - ---- UI已经准备好了 -function MiniManager:OnUIAlready() - table.func(self.CurrMiniMode, "OnUIAlready") -end - ---- 准备结束 -function MiniManager:OnPrepareEnd() - if IsServer then - UGCLogSystem.Log("[MiniManager:OnPrepareEnd] 执行") - self:SetMiniInfo(); - UGCGameSystem.SendModeCustomEvent("CheckPlayers"); - end - table.func(self.CurrMiniMode, "OnPrepareEnd") - self:OnMiniRoundPrepare(); -end - -function MiniManager:SendRPC(InRPCName, ...) - UGCLogSystem.Log("[MiniManager:SendRPC] InRPCName = %s", InRPCName); - self.Owner:SendMiniGameRPC(InRPCName, ...); -end - ---- 在游戏进行之前执行 ----@param InTime int32 从游戏开始到游戏正式开始的倒计时 -function MiniManager:OnBeforeGameStart(InTime) - UGCLogSystem.Log("[MiniManager:OnBeforeGameStart] InTime = %s", tostring(InTime)); - if InTime == 1 then - -- 玩家死亡重生 - UE.ResetGame1(0.5, function() - GameState:ResetKill(); - end); - end -end - ---- 游戏正式开始 -function MiniManager:OnGameStart() - UGCLogSystem.Log("[MiniManager:OnGameStart] 执行") - if IsServer then - -- 检查当前选择的地图是否小于对应数量,如果小于,那么就随机选择为选择的 - -- 获取选择了的 - for i, v in pairs(MiniGameConfig) do - table.insert(self.SelectMaps, i); - end - UGCLogSystem.LogTree(string.format("[MiniManager:OnGameStart] SelectMaps ="), self.SelectMaps) - -- 表示如果第一个加载不成,那么就依次完后加载,直到全部加载都不行 - local bSuccess = false; - repeat bSuccess = self:LoadMiniGame() until bSuccess or table.isEmpty(self.SelectMaps); - if not bSuccess then - UGCLogSystem.Log("[MiniManager:OnGameStart] 游戏结束") - self:OnGameEnd(); - end - else - WidgetManager:ShowPanel(WidgetConfig.EUIType.Main, false); - end -end - -function MiniManager:OnGameEnd() - UGCLogSystem.Log("[MiniManager:OnGameEnd] 游戏结束") - if IsServer then - self:SetState(MiniGameState.ENDED); - LuaQuickFireEvent("GameEnd", GameState); - else - -- 显示结算界面 - UGCLogSystem.Log("[MiniManager:OnGameEnd] GameWinner = %s", tostring(self.MiniInfo.GameWinner)); - UGCLogSystem.LogTree(string.format("[MiniManager:OnGameEnd] RoundWinners ="), self.MiniInfo.RoundWinners) - SoloKingGameWinner = self.MiniInfo.GameWinner; - SoloKingRoundWinner = self.MiniInfo.RoundWinners; - UGCLogSystem.Log("[MiniManager:OnGameEnd] 显示 GameEnd 界面"); - if not WidgetManager:IsVisiblePanel(WidgetConfig.EUIType.GameEnd) then - WidgetManager:ShowPanel(WidgetConfig.EUIType.GameEnd, false, self.MiniInfo.GameWinner, self.MiniInfo.RoundWinners); - WidgetManager:ClosePanel(WidgetConfig.EUIType.Main); - end - end -end - ----@param InMiniType MiniGameMapType Mini 游戏类型,只会在客户端存在 -function MiniManager:LoadMiniGame(InMiniType) - if MiniGameConfig == nil then - require('Script.Global.Mini.MiniGameConfig'); - end - if IsServer then - self:SetState(MiniGameState.MINI_PREPARE); - self:AllPlayerDead(); - UGCLogSystem.Log("[MiniManager:LoadMiniGame] 执行") - if table.isEmpty(self.SelectMaps) then return false; end - UGCLogSystem.Log("[MiniManager:LoadMiniGame] 开始执行流程") - self.CurrSelectMap = self.SelectMaps[1]; - if self.CurrSelectMap == nil then return false; end - table.remove(self.SelectMaps, 1); - -- 加载 CurrMiniMode - UGCLogSystem.Log("[MiniManager:LoadMiniGame] 加载 Mini Mode") - self.CurrMiniMode = require(self.ScriptPath .. MiniGameConfig[self.CurrSelectMap].Script); - if self.CurrMiniMode == nil then return false; end - if not table.func(self.CurrMiniMode, "Init", self) then return false; end - -- 发送到客户端表示当前已经同步了 - self.Owner:SelectMiniType(self.CurrSelectMap); - UGCLogSystem.Log("[MiniManager:LoadMiniGame] Mini Mode 加载成功") - self:CurrMiniModeInit(); - if self.CurrMiniMode.RoundTimes == nil then self.CurrMiniMode.RoundTimes = 1; end - self:SetRoundTimes(self.CurrMiniMode.RoundTimes); - -- 这个是玩法的小局准备 - local Times = MiniGameConfig[self.CurrSelectMap].MiniGameTimes - local Time = 0; - if Times ~= nil and Times.Prepare ~= nil then - Time = Times.Prepare; - else - Time = MiniGameTimes.Prepare; - end - UGCLogSystem.Log("[MiniManager:LoadMiniGame] Time = %s", tostring(Time)) - self.TimerHandlers = GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t) - UGCLogSystem.Log("[MiniManager:LoadMiniGame] Time Internal = %s", tostring(t)); - o:OnMiniGameTimeCount(t); - end, 1, Time, self.OnPrepareEnd); - - UGCLogSystem.Log("[MiniManager:LoadMiniGame] 全部加载完成") - return true; - else - UGCLogSystem.Log("[MiniManager:LoadMiniGame] 客户端加载") - self.CurrSelectMap = InMiniType; - self.CurrMiniMode = require(self.ScriptPath .. MiniGameConfig[self.CurrSelectMap].Script); - if self.CurrMiniMode == nil then return ; end - table.func(self.CurrMiniMode, "Init", self); - self:CurrMiniModeInit(); - -- 检查是否有数据啊 - if UGCGameSystem.GameState then - UGCGameSystem.GameState:OnRep_MiniInfo(); - end - end -end - ---- 服务器客户端初始化的共同操作 -function MiniManager:CurrMiniModeInit() - --- 默认设置一些变量供使用或者驱动 - self.CurrMiniMode.Owner = self; - self.CurrMiniMode.MapIndex = self.CurrSelectMap; - self.CurrMiniMode.CreateTime = UE.GetServerTime(); - self.CurrMiniMode.bGameEnd = false; - self.CurrMiniMode.bRoundEnd = false; - self.CurrMiniMode.RoundTimes = MiniGameConfig[self.CurrSelectMap].RoundTimes; -- 当前回合数 - self.CurrMiniMode.TotalRoundTimes = MiniGameConfig[self.CurrSelectMap].RoundTimes; -- 总回合数 - self.CurrMiniMode.bCanRespawn = MiniGameConfig[self.CurrSelectMap].bCanRespawn; -- 是否可以重生 - GlobalMiniType = self.CurrSelectMap; - GlobalMiniMode = self.CurrMiniMode - - for i, v in pairs(self.MiniInfo) do - if type(v) == 'table' then - self.CurrMiniMode[i] = TableHelper.DeepCopyTable(v); - else - self.CurrMiniMode[i] = v; - end - end - - if not table.isEmpty(MiniGameConfig[self.CurrSelectMap].Params) then - for i, v in pairs(MiniGameConfig[self.CurrSelectMap].Params) do self.CurrMiniMode[i] = v; end - end - - UGCLogSystem.Log("[MiniManager:CurrMiniModeInit] 开始加载地图") - -- 加载 Tick - GlobalTickTool:AddTick(self.CurrMiniMode, self.CurrMiniMode.OnTick, nil, function(o) - return not (o.bEnableTick == false); - end); - -- 进入准备 - table.func(self.CurrMiniMode, "OnPrepare"); -end - -function MiniManager:UnLoadMiniGame() - -- 先取消上一个的 - if IsServer then - if self.CurrMiniMode ~= nil then - GlobalTickTool:RemoveTickByOwner(self.CurrMiniMode); - -- 然后赶紧除去地图并且加载 - self:UnLoadMap(); - end - end -end - -function MiniManager:OnMiniGameTimeCount(InVal) - if IsServer then - if InVal == nil then InVal = 0; end - InVal = math.floor(InVal); - --- 执行 - GameState:OnGameProgress_Tick(InVal); - end - if self.CurrMiniMode then - self.CurrMiniMode.CurrTimeCount = InVal; - end - table.func(self.CurrMiniMode, "OnCountTime", InVal) -end - -function MiniManager:OnMiniGameEnd() - UGCLogSystem.Log("[MiniManager:OnMiniGameEnd] ") - local Times = MiniGameConfig[self.CurrSelectMap].MiniGameTimes; - local Time = 0; - if Times and Times.MiniGameEnd then - Time = Times.MiniGameEnd; - else - Time = MiniGameTimes.MiniGameEnd; - end - -- 从小局中取出来 - GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t) - o:OnMiniGameTimeCount(t); - end, 1, Time, self.OnMiniGameSwitch); - self:SetState(MiniGameState.MINI_END); - self.MiniInfo.Scores = table.func(self.CurrMiniMode, "GetScore") - self.MiniInfo.Winner = self.CurrMiniMode.GameWinner; - table.func(self.CurrMiniMode, "OnGameEnd", self.MiniInfo.Scores); - self:SetMiniInfo(); -end - -function MiniManager:ClearMiniMode() - UGCLogSystem.Log("[MiniManager:ClearMiniMode] 执行销毁") - self.PlayerData = nil; - self.SelectMaps = nil; -end - ---- 切换到下一个 MiniGame -function MiniManager:OnMiniGameSwitch() - -- 检查是否还有下一个了 - UGCLogSystem.Log("[MiniManager:OnMiniGameSwitch] 执行") - if table.isEmpty(self.SelectMaps) then - self:OnGameEnd(); - return ; - end - self:UnLoadMiniGame(); - self:LoadMiniGame(); -end - -function MiniManager:SetState(InState) - if IsServer then - UGCLogSystem.Log("[MiniManager:SetState] CurrState = %s", TableHelper.printEnum(MiniGameState, InState)); - self.State = InState; - self.MiniInfo.State = InState; - self:SetMiniInfo(); - table.func(self.CurrMiniMode, 'SetState', InState); - if self.CurrMiniMode ~= nil then - self.CurrMiniMode.State = InState; - end - GameState:SetMiniState(InState); - end - -- 全局的状态 - GlobalMiniState = self.State; -end - -function MiniManager:SetRoundTimes(InTimes) - if IsServer then - self.MiniInfo.RoundTimes = InTimes; - self:SetMiniInfo(); - if self.CurrMiniMode ~= nil then - self.CurrMiniMode.RoundTimes = InTimes; - end - end -end - -function MiniManager:OnRep_RoundTimes(InOld) - if self.CurrMiniMode ~= nil then - self.CurrMiniMode.RoundTimes = self.MiniInfo.RoundTimes; - end -end - -function MiniManager:OnRep_State(InOld) - UGCLogSystem.Log("[MiniManager:OnRep_State] self.State = %s, StateName = %s", tostring(self.MiniInfo.State), TableHelper.printEnum(MiniGameState, self.State)); - self.State = self.MiniInfo.State; - --if self.CurrMiniMode then - -- self.CurrMiniMode.State = self.State; - --end - UGCEventSystem.SendEvent(EventTypes.MiniStateChange, self.State); - if self.State == MiniGameState.MINI_PREPARE then - elseif self.State == MiniGameState.ROUND_PREPARE then - self:OnPrepareEnd(); - elseif self.State == MiniGameState.ROUND_GAMING then - self:OnMiniRoundFormalStart(); - elseif self.State == MiniGameState.ROUND_END then - self:OnMiniRoundEnd(); - elseif self.State == MiniGameState.MINI_END then - self:OnMiniGameEnd(); - elseif self.State == MiniGameState.ENDED then - self:OnGameEnd(); - end - GlobalMiniState = self.State; -end - ---- 设置同步 MiniInfo, -function MiniManager:SetMiniInfo() - self.Owner:SetMiniInfo(self.MiniInfo); -end - ---- 设置游戏数据 ----@vararg -function MiniManager:SetGameInfo(InName, InInfo) - UGCLogSystem.LogTree(string.format("[MiniManager:SetGameInfo] InInfo ="), InInfo) - if type(InInfo) == 'table' then - self.MiniInfo[InName] = TableHelper.DeepCopyTable(InInfo); - else - self.MiniInfo[InName] = InInfo; - end - self:SetMiniInfo(); -end - --- 给予子模块的数据同步 -function MiniManager:DOREPONCE(Name) - if self.CurrMiniMode then - self:SetGameInfo(Name, self.CurrMiniMode[Name]); - end -end - ------------------------------------ 地图函数 ----------------------------------- - -MiniManager.CurrLoadMapName = nil; - -function MiniManager:RandomSelectMap() - local MapNames = MiniGameConfig[self.CurrSelectMap].Map.MapName; - local MapName = ""; - if type(MapNames) == 'table' then - local Total = 0; - local Maps = {}; - for Name, Rate in pairs(MapNames) do - if type(Name) == 'string' then - Total = Total + Rate; - table.insert(Maps, { - Name = Name, - Rate = Rate, - }); - elseif type(Name) == 'int32' then - Total = Total + 1; - table.insert(Maps, { - Name = Rate, - Rate = 1, - }) - end - end - local MapCount = table.getCount(Maps); - if Total == 0 then - -- 从这两个中随机一个 - MapName = Maps[math.random(MapCount)].Name; - else - local Num = KismetMathLibrary.RandomFloat() - local RandomNum = Num * Total; - for i = 1, table.getCount(Maps) do - RandomNum = RandomNum - Maps[i].Rate; - if RandomNum <= 0 then - MapName = Maps[i].Name; - break ; - end - end - end - elseif type(MapNames) == 'string' then - MapName = MapNames; - end - return MapName; -end - ---- 加载地图 -function MiniManager:LoadMap(InIndex) - UGCLogSystem.Log("[MiniManager:LoadMap] 执行") - if InIndex == nil then InIndex = self.CurrSelectMap end - if self.HadLoadMap == InIndex then return ; end - -- 检查当前是什么东西,如果是随机的话 - local MapName = table.func(self.CurrMiniMode, "SelectMapName", InIndex); - if MapName == nil or string.len(MapName) == 0 then - MapName = self:RandomSelectMap(); - end - - UGCLogSystem.Log("[MiniManager:LoadMap] LoadMap = %s", MapName); - - self.CurrLoadMapName = MapName; - UGCLogSystem.Log("[MiniManager:LoadMap] 执行 END"); - self.Owner:LoadMap(MapName); - self.HadLoadMap = InIndex; -end - ---- 完成加载地图 -function MiniManager:OnMapLoadComplete() - UGCLogSystem.Log("[MiniManager:OnMapLoadComplete] 地图加载完成") - if IsServer then - UE.ResetGame(0.5); - end - self:OnMapLoaded(); -end - ---- 加载地图 -function MiniManager:OnMapLoaded() - UGCLogSystem.Log("[MiniManager:OnMapLoaded] 加载地图成功") - table.func(self.CurrMiniMode, "OnAlready"); -end - ---- 卸载地图 -function MiniManager:UnLoadMap() - -- 然后过一会再重新加载地图 - self.Owner:UnloadMap({ self.CurrLoadMapName }); - self.HadLoadMap = nil; -end - -function MiniManager:OnMapUnLoadedComplete() - UGCLogSystem.Log("[MiniManager:OnMapUnLoadedComplete] 异步卸载地图完成") -end - ---- 玩家选择地图 -function MiniManager:OnPlayerSelectMap(InPlayer, InMapIndex) - if IsServer then - table.insert(self.SelectMaps, InMapIndex); - -- 发送 RPC - self:SendRPC("OnPlayerSelectMap", self.SelectMaps) - else - UGCEventSystem.SendEvent(EventTypes.MiniGame_SelectMap, self.SelectMaps); - end -end - ------------------------------------ 回合函数 ----------------------------------- ---- 开启小局 -function MiniManager:OnMiniRoundPrepare() - -- 小局次数 - 1 - if IsServer then - self:LoadMap(self.CurrSelectMap); - local Times = MiniGameConfig[self.CurrSelectMap].MiniGameTimes; - local Time = (Times == nil or Times.Prepare == nil) and MiniGameTimes.RoundPrepare or Times.Prepare; - GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t) - local InTime = t; - if Time > 0 then InTime = Time - t end - o:OnMiniGameTimeCount(InTime) - self:OnBeforeGameStart(t); - end, 1, Time, self.OnMiniRoundFormalStart); - self.CurrMiniMode.RoundTimes = self.CurrMiniMode.RoundTimes - 1; - self.CurrMiniMode.bRoundEnd = false; - self:SetState(MiniGameState.ROUND_PREPARE); - self:SetRoundTimes(self.CurrMiniMode.RoundTimes); - else - -- 看看是否要执行什么 - end - table.func(self.CurrMiniMode, "OnRoundStart", self:GetCurrRoundTimes()); - if self.CurrMiniMode then - self.CurrMiniMode.RoundEndTime = 0; - end -end - ---- 小局正式开始 -function MiniManager:OnMiniRoundFormalStart() - -- 这是正式开启了 - UGCLogSystem.Log("[MiniManager:OnMiniRoundFormalStart] 正式开始游戏") - if self.CurrMiniMode then - self.CurrMiniMode.RoundStartTime = UE.GetServerTime(); - end - if IsServer then - -- 启动计时,让小游戏有一个时限 - local TotalTime = MiniGameTimes.RoundGameTime; - GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t) - local InTime = t; - if TotalTime > 0 then InTime = TotalTime - t end - o:OnMiniGameTimeCount(InTime); - end, 1., math.abs(TotalTime), self.OnMiniRoundEnd, function(o) - return o.CurrMiniMode.bGameEnd or o.CurrMiniMode.bRoundEnd; - end); - - self:SetState(MiniGameState.ROUND_GAMING); - -- 解除玩家封禁状态 - UE.ClearSceneObjects(); - else - -- 是否显示 “回合正式开始!” - end - table.func(self.CurrMiniMode, "OnRoundFormalStart", self:GetCurrRoundTimes(), self.CurrMiniMode.RoundStartTime); -end - -function MiniManager:OnMiniRoundEnd() - if self.State == MiniGameState.ROUND_GAMING then - if self.CurrMiniMode.bGameEnd == false and self.CurrMiniMode.bRoundEnd == false then - table.func(self.CurrMiniMode, "OnTimeExhausted", self.State) - end - end - -- 通知结束了 - UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] 结束") - self.CurrMiniMode.RoundEndTime = UE.GetServerTime(); - local Winner = 0; - if IsServer then - local Times = MiniGameConfig[self.CurrSelectMap].MiniGameTimes; - local Time = 0; - if Times and Times.RoundEnd then - Time = Times.RoundEnd; - else - Time = MiniGameTimes.RoundEnd; - end - - UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] RoundTimes = %d", self.CurrMiniMode.RoundTimes) - UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] bGameEnd = %s", tostring(self.CurrMiniMode.bGameEnd)) - if self.CurrMiniMode.RoundTimes <= 0 or self.CurrMiniMode.bGameEnd then - UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] 回合结束") - GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t) - o:OnMiniGameTimeCount(t); - end, 1, Time, self.OnMiniGameEnd); - else - -- 继续 - -- 开始计时 - UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] 下一小局开始") - GlobalTickTool:AddInternalCount(self, function(o, dt, ServerTime, t) - o:OnMiniGameTimeCount(t); - end, 1, Time, self.OnMiniRoundPrepare); - end - if table.hasFunc(self.CurrMiniMode, 'GetRoundWinner') then - self.MiniInfo.RoundWinner = table.func(self.CurrMiniMode, "GetRoundWinner", self:GetCurrRoundTimes()); - end - Winner = self.MiniInfo.RoundWinner; - table.func(self.CurrMiniMode, "OnRoundEnd", self:GetCurrRoundTimes(), Winner, self.CurrMiniMode.RoundEndTime - self.CurrMiniMode.RoundStartTime); - UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] Winner = %s", tostring(Winner)) - self:SetState(MiniGameState.ROUND_END); - else - -- 显示回合成功或者失败,执行到此一定可以拿到Winner是谁 - -- 直接获取 Winner - Winner = self.MiniInfo.RoundWinner - UGCLogSystem.Log("[MiniManager:OnMiniRoundEnd] RoundWinner = %s", tostring(Winner)); - table.func(self.CurrMiniMode, "OnRoundEnd", self:GetCurrRoundTimes(), Winner, self.CurrMiniMode.RoundEndTime - self.CurrMiniMode.RoundStartTime); - end -end - ------------------------------------ 玩家函数 ----------------------------------- ---- 当添加玩家的时候执行 -function MiniManager:OnPlayerLogin(InPlayerKey) - UGCLogSystem.Log("[MiniManager:OnPlayerLogin] 玩家:%d 登录", InPlayerKey); - table.func(self.CurrMiniMode, "OnPlayerLogin", InPlayerKey); - -- 获取玩家的排位分 - UGCRankSystem.GetUGCRank(InPlayerKey); -end - -function MiniManager:OnPlayerLeave(InPlayerKey) - UGCLogSystem.Log("[MiniManager:OnPlayerLeave] 玩家:%d 登出", InPlayerKey); - table.func(self.CurrMiniMode, "OnPlayerLeave", InPlayerKey); -end - ----@param PlayerStartList table> ----@param Controller UGCPlayerController_C -function MiniManager:SelectPlayerStart(PlayerStartList, Controller) - return table.func(self.CurrMiniMode, 'SelectPlayerStart', PlayerStartList, Controller); -end - ---- S & C 玩家在加载好之后进行的初始化操作 -function MiniManager:OnPawnInit(Pawn) - if IsServer then - --UGCLogSystem.LogTree(string.format("[MiniManager:OnPawnInit] GameConfig ="), MiniGameConfig); - UGCLogSystem.Log("[MiniManager:OnPawnInit] self.CurrSelectMap = %s", tostring(self.CurrSelectMap)) - if self.CurrSelectMap == nil then return ; end - local InitArmors = MiniGameConfig[self.CurrSelectMap].InitArmors; - local InitMedication = MiniGameConfig[self.CurrSelectMap].InitMedication; - table.func(self.CurrMiniMode, 'OnPawnInit', Pawn, InitArmors, InitMedication); - else - table.func(self.CurrMiniMode, 'OnPawnInit', Pawn); - end -end - ---- 当玩家死亡 ----@param DeadPlayerKey PlayerKey ----@param KillerPlayerKey PlayerKey -function MiniManager:OnPlayerDead(DeadPlayerKey, KillerPlayerKey) - table.func(self.CurrMiniMode, 'OnPlayerDead', DeadPlayerKey, KillerPlayerKey); - if IsServer then - -- 发送 RPC - self:SendRPC("OnPlayerDead", DeadPlayerKey, KillerPlayerKey); - end -end - -function MiniManager:OnPlayerRespawn(InPlayerKey) - table.func(self.CurrMiniMode, "OnPlayerRespawn", InPlayerKey) -end - -function MiniManager:OnPlayerPossessed(Pawn, NewController) - -- 检查是否有初始武器,如果有,那么直接添加 - UGCLogSystem.Log("[MiniManager:OnPlayerPossessed] 执行") - table.func(self.CurrMiniMode, "OnPlayerPossessed", Pawn, NewController); -end - ---- 仅在服务器存在 -function MiniManager:OnPlayerInjury(PlayerKey, CauserKey, DamageInfo) - UGCLogSystem.LogTree(string.format("[MiniManager:OnPlayerInjury] DamageInfo ="), DamageInfo) - table.func(self.CurrMiniMode, "OnPlayerInjury", PlayerKey, CauserKey, DamageInfo); -end - ----@param InPawn UGCPlayerPawn_C ----@param Weapon ASTExtraWeapon -function MiniManager:OnPlayerGetWeapon(InPawn, Weapon) - if self.CurrMiniMode then - table.func(self.CurrMiniMode, "OnPlayerGetWeapon", InPawn, Weapon); - end -end - ---- 射击导致子弹数量发生改变 ----@param PlayerKey PlayerKey 玩家 Key ----@param WeaponID int32 武器 ID ----@param PreCount int32 射击前数量 ----@param CurrCount int32 当前数量 -function MiniManager:OnBulletNumChange(PlayerKey, WeaponID, PreCount, CurrCount) - table.func(self.CurrMiniMode, "OnBulletNumChange", PlayerKey, WeaponID, PreCount, CurrCount); -end - ------------------------------------- 获取函数 ------------------------------------ ---- 获取当前模式 -function MiniManager:GetCurrentMode() return self.CurrMiniMode; end ---- 获取当前地图名 -function MiniManager:GetCurrLevel() return MiniGameConfig[self.CurrSelectMap].Map.MapName; end ---- 获取当前显示地图名称 -function MiniManager:GetShowName() return MiniGameConfig[self.CurrSelectMap].Map.ShowName; end ---- 获取当前是第几回合 -function MiniManager:GetCurrRoundTimes() - if table.isEmpty(MiniGameConfig) or self.CurrSelectMap == nil or table.isEmpty(MiniGameConfig[self.CurrSelectMap]) then - return 1; - end - if MiniGameConfig[self.CurrSelectMap].RoundTimes == nil then - return 1; - else - return MiniGameConfig[self.CurrSelectMap].RoundTimes - self.CurrMiniMode.RoundTimes; - end -end - ---- 获取总的回合数 -function MiniManager:GetTotalRoundTimes() - if table.isEmpty(MiniGameConfig) or self.CurrSelectMap == nil or table.isEmpty(MiniGameConfig[self.CurrSelectMap]) then - return 1; - end - if MiniGameConfig[self.CurrSelectMap].RoundTimes == nil then - return 1; - else - return MiniGameConfig[self.CurrSelectMap].RoundTimes - end -end - ------------------------------------- 给予函数 ------------------------------------ ---- 所有玩家死亡 -function MiniManager:AllPlayerDead() - for i, v in pairs(UGCGameSystem.GetAllPlayerPawn()) do - if v:IsAlive() then v:K2_DestroyActor(); end - end -end - ---- 所有玩家重生 -function MiniManager:AllPlayerRespawn(InTime) - self:AllPlayerDead(); - UGCEventSystem.SetTimer(self.Owner, function() - for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do - UGCGameSystem.RespawnPlayer(v.PlayerKey); - end - end, InTime); -end - ----@param InPawn UGCPlayerPawn_C ----@param InState EPawnState -function MiniManager:SetPawnState(InPawn, InState, IsSet) - if IsSet then - UGCPawnSystem.EnterPawnState(InPawn, InState) - else - UGCPawnSystem.LeavePawnState(InPawn, InState) - end -end - ---- 这个需要放在 GameState 中进行更改 -function MiniManager:DOREPONCE(k, v) - self.Owner[k] = v; - DOREPONCE(self.Owner, k); -end - -MiniManager.CachedMiniInfo = {}; - ---- 缓存一份 -function MiniManager:MakeCachedMiniInfo() - if self.CachedMiniInfo.State == nil then - self.CachedMiniInfo.State = MiniGameState.NON_START; - end -end - ---- 属性同步,对比是否不同,只有不同的会进行 OnRep_ 否则就不会进行。 -function MiniManager:OnRep_MiniInfo(InOld) - --UGCLogSystem.LogTree(string.format("[MiniManager:OnRep_MiniInfo] self.MiniInfo ="), self.MiniInfo) - --UGCLogSystem.LogTree(string.format("[MiniManager:OnRep_MiniInfo] self.CachedMiniInfo Begin ="), self.CachedMiniInfo) - for i, v in pairs(self.MiniInfo) do - -- 如果发生改变再执行对应的 OnRep - if type(v) == 'table' then - -- 比较一下这两者有什么不同 - if not table.compare(v, self.CachedMiniInfo[i]) then - -- 更新一下 - UGCLogSystem.Log("[MiniManager:OnRep_MiniInfo] 相同变量 Index = %s", tostring(i)); - if self:IsRepProp(tostring(i)) then - self[i] = v; - table.func(self, "OnRep_" .. tostring(i), self.CachedMiniInfo[i]); - end - if self.CurrMiniMode ~= nil then - self.CurrMiniMode[i] = TableHelper.DeepCopyTable(v); - table.func(self.CurrMiniMode, "OnRep_" .. tostring(i), self.CachedMiniInfo[i]); - end - end - else - if self.CachedMiniInfo[i] ~= v then - if self:IsRepProp(tostring(i)) then - self[i] = v; - table.func(self, "OnRep_" .. tostring(i), self.CachedMiniInfo[i]); - end - if self.CurrMiniMode ~= nil then - self.CurrMiniMode[i] = v; - table.func(self.CurrMiniMode, "OnRep_" .. tostring(i), self.CachedMiniInfo[i]); - end - end - end - UGCLogSystem.Log("[MiniManager:OnRep_MiniInfo] Index = %s", i); - self.CachedMiniInfo[i] = nil; - --UGCLogSystem.LogTree(string.format("[MiniManager:OnRep_MiniInfo] self.CachedMiniInfo ="), self.CachedMiniInfo) - end - --UGCLogSystem.LogTree(string.format("[MiniManager:OnRep_MiniInfo] self.CachedMiniInfo End ="), self.CachedMiniInfo) - -- 检查是否有多余的 - for i, v in pairs(self.CachedMiniInfo) do - if self.MiniInfo[i] == nil then - if self:IsRepProp(tostring(i)) then - self[tostring(i)] = nil; - table.func(self, "OnRep_" .. tostring(i), v); - end - if self.CurrMiniMode ~= nil then - self.CurrMiniMode[tostring(i)] = nil; - table.func(self.CurrMiniMode, "OnRep_" .. tostring(i), v); - end - UGCLogSystem.Log("[MiniManager:OnRep_MiniInfo] 执行冗余的 Index = %s", tostring(i)); - end - UGCLogSystem.Log("[MiniManager:OnRep_MiniInfo] 冗余的 Index = %s", tostring(i)); - end - - -- 设置上去进行缓存 - self.CachedMiniInfo = TableHelper.DeepCopyTable(self.MiniInfo); - --UGCLogSystem.LogTree(string.format("[MiniManager:OnRep_MiniInfo] self.CachedMiniInfo Final ="), self.CachedMiniInfo) -end - ---- 获取内部数据 -function MiniManager:GetMiniInfo(InName) - if self.CurrMiniMode then - local Item = table.func(self.CurrMiniMode, "GetMiniInfo", InName); - if Item ~= nil then return Item; end - return self.CurrMiniMode[InName]; - end - return nil; -end - -function MiniManager:UpdateInternalCount(InCount) - UGCLogSystem.Log("[MiniManager:UpdateInternalCount] self.TimerHandlers = %s", tostring(self.TimerHandlers)); - GlobalTickTool:UpdateInternalCountByHandle(self.TimerHandlers, InCount); -end \ No newline at end of file diff --git a/SoloKing/Script/Global/Mini/Script/Mini_Solo.lua b/SoloKing/Script/Global/Mini/Script/Mini_Solo.lua deleted file mode 100644 index 58b211e6..00000000 --- a/SoloKing/Script/Global/Mini/Script/Mini_Solo.lua +++ /dev/null @@ -1,2124 +0,0 @@ -local Mini_Solo = {}; - -Mini_Solo.RoundWinner = nil; ---- 游戏获胜者 -Mini_Solo.GameWinner = nil; -Mini_Solo.GameLoser = nil; - ----@class RoundWinnerInfo ----@field Winner PlayerKey ----@field Time float ----@field Weapon ItemId ----@field Score RoundWinnerScore - ----@class RoundWinnerScore ----@field Winner int32 ----@field Loser int32 - ----@class MiniSolo_RankScore ----@field PlayerKey PlayerKey ----@field Current int32 ----@field Add int32 ----@field AddHide int32 ----@field HideScore int32 - ----@type table -Mini_Solo.RoundWinners = {}; ----@type table> 玩家选择的武器 -Mini_Solo.SelectWeapons = {}; -Mini_Solo.Damages = {}; ----@type table -Mini_Solo.RoundDeadTimes = {}; ---- @type table> -Mini_Solo.Disables = {}; ----@type table -Mini_Solo.RankScores = {}; -Mini_Solo.DeadCount = 0; -Mini_Solo.CurrTimeCount = 0; -- 可以直接拿到的倒计时 -Mini_Solo.TotalKDA = {}; ---- 模式 -Mini_Solo.ModeType = nil; -Mini_Solo.IsLobbyTeam = false; - ---- 参数在 MiniGameConfig 中的 Params 中写,此时可以写软资源的异步加载 -function Mini_Solo:Init(Manager, ...) - UGCLogSystem.Log("[Mini_Solo:Init] 执行") - if IsServer then - PoisonManager = require("Script.Blueprint.SceneObj.Poison.PoisonManager"); - end - self.ModeType = GameModeConfig.EGameModeType.DefaultMode; - return true; -end - ---- 在 Init 执行之后调用, -function Mini_Solo:OnPrepare() - -- 显示 UI - if IsServer then - self:LoadArchive(); - else - self:ShowSelectWeaponUI(); - UGCVoiceManagerSystem.SetGlobalVoiceRadius(1000 * 100); - end -end - -function Mini_Solo:LoadArchive() - -- 从存档中加载 Disables - if IsServer then - for i, PC in pairs(UGCGameSystem.GetAllPlayerController(false)) do - local PlayerKey = PC.PlayerKey - self.TotalKDA[PlayerKey] = {}; - if table.isEmpty(self.Disables[PlayerKey]) then - if self.Disables[PlayerKey] == nil then self.Disables[PlayerKey] = {}; end - if ArchiveTable[PlayerKey] and ArchiveTable[PlayerKey].Disables then - for Type, Enable in pairs(ArchiveTable[PlayerKey].Disables) do - self.Disables[PlayerKey][Type] = Enable; - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:LoadArchive] ArchiveData.Disables ="), self.Disables) - end - --- 使用默认 - for Type, Info in pairs(DisableInfo) do - if self.Disables[PlayerKey][Type] == nil and Info.Enable then - self.Disables[PlayerKey][Type] = false; - end - end - end - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:LoadArchive] self.Disables ="), self.Disables) - end -end - -function Mini_Solo:ShowSelectWeaponUI() - if IsClient then - if self.State <= MiniGameState.ROUND_PREPARE then - if LocalIsGlobalSpectator then - if not WidgetManager:IsVisiblePanel(WidgetConfig.EUIType.AllWeapon_Spectator) then - UGCLogSystem.Log("[Mini_Solo:ShowSelectWeaponUI] 显示观战界面"); - WidgetManager:ShowPanel(WidgetConfig.EUIType.AllWeapon_Spectator, false, self.SelectWeaponCount, self.PlayerSelectMaps); - end - -- 隐藏一下 OBUI - else - if not WidgetManager:IsVisiblePanel(WidgetConfig.EUIType.AllWeapon) then - UGCLogSystem.Log("[Mini_Solo:ShowSelectWeaponUI] 显示所有武器界面"); - WidgetManager:ShowPanel(WidgetConfig.EUIType.AllWeapon, false, self.SelectWeaponCount, self.PlayerSelectMaps); - --- 显示段位继承 UI - end - if not WidgetManager:IsVisiblePanel(WidgetConfig.EUIType.ShowRankInheritance) then - self:ShowRankInheritanceUI(); - end - end - end - end -end - -function Mini_Solo:OnClientAlready() - if IsServer then - for _, PS in pairs(UGCGameSystem.GetAllPlayerController(false)) do - self.PlayerSelectMaps[PS.PlayerKey] = ArchiveTable[PS.PlayerKey].LastSelectMap; - end - -- 保存一个随机的 - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnClientAlready] PlayerSelectMaps ="), self.PlayerSelectMaps) - GameState:SetMiniInitData("RandomMapName", self.PlayerSelectMaps); - self:DOREPONCE("PlayerSelectMaps"); - - -- 开启队伍判断 - UGCGameSystem.SendModeCustomEvent("ChangeTeamID"); - - self:LoadArchive(); - self:DOREPONCE("Disables"); - else - self:ShowSelectWeaponUI(); - end -end - -function Mini_Solo:OnUIAlready() - UGCLogSystem.Log("[Mini_Solo:OnUIAlready] 执行"); - if IsClient then - -- 此时和平精英已经准备就绪了 - UGCVoiceManagerSystem.SetGlobalVoiceRadius(1000 * 100); - self:ShowSelectWeaponUI(); - end -end - -Mini_Solo.PrepareEnd_Once = false; - -function Mini_Solo:OnPrepareEnd() - UGCLogSystem.Log("[Mini_Solo:OnPrepareEnd] 执行") - if self.PrepareEnd_Once then return ; end - self.PrepareEnd_Once = true; - if IsClient then - -- 关闭界面 - UGCEventSystem.SetTimer(GameState, function() - WidgetManager:ClosePanel(WidgetConfig.EUIType.AllWeapon); - WidgetManager:ClosePanel(WidgetConfig.EUIType.ShowRankInheritance); - WidgetManager:ClosePanel(WidgetConfig.EUIType.AllWeapon_Spectator); - - if table.isEmpty(self.RoundWinners) then - WidgetManager:ShowPanel(WidgetConfig.EUIType.ShowPK, false) - end - end, 0.5); - UGCEventSystem.SetTimer(GameState, function() - UGCLogSystem.Log("[Mini_Solo:OnPrepareEnd] EnableShovel = %s", tostring(GameState.EnableShovel)); - WidgetManager:ShowPanel(WidgetConfig.EUIType.TipSlidingTackle, false, GameState.EnableShovel) - end, 3); - else - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPrepareEnd] SelectWeapons First"), self.SelectWeapons) - if self.ModeType == GameModeConfig.EGameModeType.DefaultMode then - -- 记录一下玩家选择的 - for PlayerKey, List in pairs(self.SelectWeapons) do - for i, WeaponId in pairs(List) do self:AddSelectWeaponsArchive(PlayerKey, WeaponId, 1, 1); end - end - - if table.isEmpty(self.SelectWeapons) then - -- 直接匹配所有的枪械,然后选择局数个 - if table.isEmpty(WeaponIdTable) then GetWeaponIdTable() end - for i = 1, self.TotalRoundTimes do table.insert(self.SelectWeapons, WeaponIdTable[i]); end - else - if table.getCount(self.SelectWeapons) == 1 then - -- 选择他选择的所有枪械 - local Table = {}; - local TempWeapons = {}; - for i, v in pairs(self.SelectWeapons) do - for c, d in pairs(v) do - Table[d] = true; - table.insert(TempWeapons, d); - end - end - -- 然后再看够不够,不够差多少 - self.SelectWeapons = TempWeapons; - table.Shuffle(WeaponIdTable); - local Count = self.TotalRoundTimes - table.getCount(Table); - UGCLogSystem.Log("[Mini_Solo:OnPrepareEnd] Count = %d", Count); - if Count > 0 then - for i, v in pairs(WeaponIdTable) do - if Table[v] == nil then - table.insert(self.SelectWeapons, v); - Count = Count - 1; - if Count <= 0 then break ; end - end - end - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPrepareEnd] SelectWeapons ="), self.SelectWeapons) - else - --- 保存一下当前选择的武器 - for PlayerKey, Info in pairs(UE.GetAccountInfo()) do - local Config = self.SelectWeapons[PlayerKey] - -- 保存一下选择的武器 - if Config then - ArchiveTable[PlayerKey].LastSelectWeapons = TableHelper.DeepCopyTable(Config); - end - end - - -- 找到都选择了的,这些进行全部加入,然后再混合两边各选择一些 - local Keys = table.getKeys(self.SelectWeapons); - local SameTables = table.intersection(self.SelectWeapons[Keys[1]], self.SelectWeapons[Keys[2]]); - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPrepareEnd] SameTables ="), SameTables) - local SameMap = {}; - for i, v in pairs(SameTables) do SameMap[v] = true; end - - -- 去除相同的,遗留不同的 - local Table = {}; - for PlayerKey, v in pairs(self.SelectWeapons) do - for c, d in pairs(v) do - Table[d] = true; - if SameMap[d] then v[c] = nil; end - end - end - - -- 检查剩下的够不够所需的,如果够了,从中选择,不够的话那就全部加入再添加即可 - local WeaponCount = 0; - local PlayerWeapons = {}; - - for i, v in pairs(self.SelectWeapons) do - if PlayerWeapons[i] == nil then PlayerWeapons[i] = {}; end - for c, d in pairs(v) do - WeaponCount = WeaponCount + 1; - table.insert(PlayerWeapons[i], d); - end - end - - local AddWeapons = {}; - local CountNum = #PlayerWeapons[Keys[1]]; - if not table.isEmpty(PlayerWeapons[Keys[1]]) then - for i = 1, CountNum do - for c = 1, #Keys do - if PlayerWeapons[Keys[c]][i] then table.insert(AddWeapons, PlayerWeapons[Keys[c]][i]); end - end - end - end - - if Keys[2] then - if #PlayerWeapons[Keys[2]] > CountNum then - for i = CountNum + 1, #PlayerWeapons[Keys[2]] do - table.insert(AddWeapons, PlayerWeapons[Keys[2]][i]); - end - end - end - - -- 如果刚好够了,就全部加入 - local NeedCount = self.TotalRoundTimes - table.getCount(SameTables) - UGCLogSystem.Log("[Mini_Solo:OnPrepareEnd] NeedCount = %d", NeedCount); - - UGCLogSystem.Log("[Mini_Solo:OnPrepareEnd] WeaponCount = %d", WeaponCount); - if WeaponCount == NeedCount then - for i = 1, #AddWeapons do table.insert(SameTables, AddWeapons[i]); end - elseif WeaponCount < NeedCount then - for i, v in pairs(AddWeapons) do table.insert(SameTables, v); end - table.Shuffle(WeaponIdTable); - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPrepareEnd] WeaponIdTable ="), WeaponIdTable); - for i, v in pairs(WeaponIdTable) do - if Table[v] == nil then - table.insert(SameTables, v); - if table.getCount(SameTables) == self.TotalRoundTimes then break ; end - end - end - else - -- 从中选择 剩下的 - for i = 1, NeedCount do table.insert(SameTables, AddWeapons[i]); end - end - self.SelectWeapons = SameTables; - end - end - end - - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPrepareEnd] SelectWeapons"), self.SelectWeapons) - - self:DOREPONCE("SelectWeapons"); -- 再次同步 - - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPrepareEnd] Disables ="), self.Disables) - -- 先保存一下玩家设置的 - local DisTable = {}; - for PlayerKey, Table in pairs(self.Disables) do - local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey); - ArchiveTable[PC.PlayerKey].Disables = {}; - for Type, Enable in pairs(Table) do ArchiveTable[PC.PlayerKey].Disables[Type] = Enable; end - - for Type, Enable in pairs(Table) do - if Enable then DisTable[Type] = (DisTable[Type] or 0) + 1; end - end - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPrepareEnd] DisTable ="), DisTable) - local PCCount = table.getCount(UGCGameSystem.GetAllPlayerController(false)); - - --- 检查地图 - local DelayWeapons = MiniGameConfig[self.Owner.CurrSelectMap].DelayWeapons - if self.ModeType == GameModeConfig.EGameModeType.DefaultMode then - local MapName = GameState.LoadMapName; - UGCLogSystem.Log("[Mini_Solo:OnPrepareEnd] MapName = " .. tostring(MapName)); - local MapAddedItem = MiniGameConfig[MiniGameMapType.SoloKing].MapAddedItem[MapName]; - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPrepareEnd] MapAddedItem ="), MapAddedItem) - if MapAddedItem ~= nil then - for i, v in pairs(DelayWeapons) do - if v[2] ~= nil and v[2] > 0 and v[1] == '手榴弹' then - table.insert(DelayWeapons, MapAddedItem[1]); - break ; - end - end - end - else - table.insert(DelayWeapons, { "燃烧瓶", 1 }); - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPrepareEnd] DelayWeapons ="), MiniGameConfig[self.Owner.CurrSelectMap].DelayWeapons); - - for Type, Count in pairs(DisTable) do - if Count == PCCount then - -- 开始执行 - if Type == EDisableType.Grenade then - for i, v in pairs(DelayWeapons) do - if v[1] == '手榴弹' or v[1] == '燃烧瓶' then v[2] = 0; end - end - elseif Type == EDisableType.SmokeBomb then - for i, v in pairs(DelayWeapons) do - if v[1] == '烟雾弹' then - v[2] = 0; - break ; - end - end - elseif Type == EDisableType.FlashBang then - for i, v in pairs(DelayWeapons) do - if v[1] == '震爆弹' then - v[2] = 0; - break ; - end - end - elseif Type == EDisableType.Shovel2 then - -- 设置无法滑铲 - UGCLogSystem.Log("[Mini_Solo:OnPrepareEnd] 禁止滑铲") - GameMode.bIsOpenShovelingAbility = true; - GameState.bIsOpenShovelingAbility = true; - GameState.EnableShovel = true; - end - end - end - end -end - -function Mini_Solo:OnCountTime(InTime) - if self.State < MiniGameState.ROUND_GAMING then - if IsClient then - UGCLogSystem.Log("[Mini_Solo:OnCountTime] SelectMapTime = %s", tostring(self.SelectMapTime)); - if InTime >= self.SelectMapTime then - WidgetManager:GetPanel(WidgetConfig.EUIType.AllWeapon, function(Widget) - Widget:UpdateSelectCountDown(InTime - self.SelectMapTime); - end) - elseif InTime == self.SelectMapTime - 1 then - -- 切换过去 - WidgetManager:GetPanel(WidgetConfig.EUIType.AllWeapon, function(Widget) - table.func(Widget, "SetSelectMapEnable", false); - table.func(Widget, "SwitchSelectMap"); - end) - end - - if LocalIsGlobalSpectator then - UGCLogSystem.Log("[Mini_Solo:OnCountTime] 当前是观战玩家") - if not WidgetManager:IsVisiblePanel(WidgetConfig.EUIType.AllWeapon_Spectator) then - UGCLogSystem.Log("[Mini_Solo:OnCountTime] 显示出来观战 UI") - WidgetManager:ShowPanel(WidgetConfig.EUIType.AllWeapon_Spectator, false, self.SelectWeaponCount, self.PlayerSelectMaps); - end - end - else - -- 开始加载 - if InTime == self.SelectMapTime - 1 then - self:GotoSelectMap(); - end - end - end -end - -function Mini_Solo:GotoSelectMap() - if GameState ~= nil and GameState.LoadMapName ~= nil then return end - self.Owner:LoadMap(); - - local CurrMap = self.Owner.CurrLoadMapName; - UGCLogSystem.Log("[Mini_Solo:GotoSelectMap] 执行 MapName = %s", tostring(CurrMap)); - -- 记录一下玩家选择的地图 - for i, PC in pairs(UGCGameSystem.GetAllPlayerController(false)) do - local PlayerKey = PC.PlayerKey; - if ArchiveTable[PlayerKey].SelectMaps == nil then ArchiveTable[PlayerKey].SelectMaps = {}; end - local Map = self.PlayerSelectMaps[PlayerKey] - if Map ~= nil then - ArchiveTable[PlayerKey].SelectMaps[Map] = (ArchiveTable[PlayerKey].SelectMaps[Map] or 0) + 1 - if ArchiveTable[PlayerKey].NoSelectMaps == nil then ArchiveTable[PlayerKey].NoSelectMaps = {}; end - if CurrMap then - if Map ~= CurrMap then - -- 这是未选择过的Map - ArchiveTable[PlayerKey].NoSelectMaps[Map] = (ArchiveTable[PlayerKey].NoSelectMaps[Map] or 0) + 1; - else - -- 清空该项 - ArchiveTable[PlayerKey].NoSelectMaps[Map] = (ArchiveTable[PlayerKey].NoSelectMaps[Map] or 0) - 3; - if ArchiveTable[PlayerKey].NoSelectMaps[Map] < 0 then ArchiveTable[PlayerKey].NoSelectMaps[Map] = 0; end - end - end - end - ArchiveTable[PlayerKey].LastSelectMap = Map or ArchiveTable[PlayerKey].LastSelectMap; - end -end - -function Mini_Solo:OnTimeExhausted(InState) - if IsServer then - -- 说明是时间耗尽了 - if InState == MiniGameState.ROUND_GAMING then - UGCLogSystem.Log("[Mini_Solo:OnTimeExhausted] 时间耗尽,进行计算谁获胜了"); - -- 计算谁获胜了 - local Count = table.getCount(self.RoundDeadTimes); - UGCLogSystem.Log("[Mini_Solo:OnTimeExhausted] Count = %s", tostring(Count)); - if Count == 2 then - local Table = {}; - for i, v in pairs(self.RoundDeadTimes) do - table.insert(Table, { - PlayerKey = i; - Times = v; -- 死亡次数 - }); - end - table.sort(Table, function(a, b) - return a.Times < b.Times; - end) - -- 判断是否一致 - if Table[1].Times == Table[2].Times then - self.RoundWinner = self:CheckTimeExhausted() - else - self.RoundWinner = Table[1].PlayerKey; - end - elseif Count == 1 then - -- 查看谁死了,另一个人就是获胜方 - local RoundLoser = nil; - for i, v in pairs(self.RoundDeadTimes) do - if v > 0 then RoundLoser = i; end - end - if RoundLoser then - for i, v in pairs(UE.GetAccountInfo()) do - if i ~= RoundLoser then self.RoundWinner = i; end - end - end - else - -- 一次都没死过 - self.RoundWinner = self:CheckTimeExhausted(); - end - - UGCLogSystem.Log("[Mini_Solo:OnTimeExhausted] 执行 RoundWinner = %s", tostring(self.RoundWinner)); - - if self.RoundWinner ~= nil then - local Loser = nil; - for i, v in pairs(UE.GetAccountInfo()) do - if self.RoundWinner ~= i then Loser = i; end - end - local WeaponID = self.CurrWeaponItem[self.RoundWinner] or ItemTool.GetFirstWeaponID(self.RoundWinner); - table.insert(self.RoundWinners, { - Winner = self.RoundWinner, - Time = UE.GetServerTime() - self.RoundStartTime, - -- 拿到对方的枪械 - Weapon = WeaponID, - Score = { - Winner = self.RoundDeadTimes[Loser] or 0, -- 这个是阵亡数,需要反过来 - Loser = self.RoundDeadTimes[self.RoundWinner] or 0, - }, - }); - - if self:IsFormalMode() then - self:AddSelectWeaponsArchive(self.RoundWinner, WeaponID, 3, 1); - end - else - local Weapon = nil; - for i, v in pairs(UGCGameSystem.GetAllPlayerPawn()) do - local CurWeapon = UGCWeaponManagerSystem.GetCurrentWeapon(v); - if CurWeapon then - Weapon = CurWeapon:GetWeaponItemID(); - break ; - end - end - -- 判断此时是什么情况 - local DeadTimes = 0; - if table.getCount(self.RoundDeadTimes) == 2 then DeadTimes = 1; end - table.insert(self.RoundWinners, { - Winner = nil, - Time = UE.GetServerTime() - self.RoundStartTime, - -- 拿到对方的枪械 - Weapon = Weapon, - Score = { - Winner = DeadTimes, -- 这个是阵亡数,需要反过来 - Loser = DeadTimes, - }, - }); - end - local IsOver, WinnerID = self:CheckGameEnd(); - if IsOver then - for i, v in pairs(UE.GetAccountInfo()) do - if WinnerID ~= i then self.GameLoser = i; end - end - self:SetGameOver(WinnerID); - end - self:DOREPONCE("RoundWinners"); - UGCEventSystem.SendEvent(EventTypes.UpdateRoundWinners, self.RoundWinners); - end - end -end - -function Mini_Solo:CheckTimeExhausted() - -- 判断血量 - local Winner = self:CheckTimeExhausted_Health(); - UGCLogSystem.Log("[Mini_Solo:CheckTimeExhausted] Health 胜利方:%s", tostring(Winner)); - if Winner == nil then - Winner = self:CheckTimeExhausted_Damage(); - UGCLogSystem.Log("[Mini_Solo:CheckTimeExhausted] 伤害胜利方:%s", tostring(Winner)); - if Winner == nil then return nil; end - end - return Winner; -end - ---- 通过血量进行判断 -function Mini_Solo:CheckTimeExhausted_Health() - -- 通过其他方式进行计算,计算伤害,计算血量 - UGCLogSystem.Log("[Mini_Solo:CheckTimeExhausted_Health] 开始判断Health") - local Table = {}; - for i, Pawn in pairs(UGCGameSystem.GetAllPlayerPawn()) do - if UE.IsValidPawn(Pawn) then - local Health = UGCPawnAttrSystem.GetHealth(Pawn); - table.insert(Table, { - PlayerKey = Pawn.PlayerKey, - Health = Health, - }); - end - end - local Count = table.getCount(Table); - if Count == 0 then return nil; end - if Count == 1 then return Table[1].PlayerKey; end - table.sort(Table, function(a, b) - return a.Health > b.Health; - end); - UGCLogSystem.LogTree(string.format("[Mini_Solo:CheckTimeExhausted_Health] Table ="), Table) - if Table[1].Health ~= Table[2].Health then - return Table[1].PlayerKey; - end - return nil; -end - ---- 通过伤害进行判断 -function Mini_Solo:CheckTimeExhausted_Damage() - local Table = {}; - for PlayerKey, Damage in pairs(self.RoundDamages) do - table.insert(Table, { - PlayerKey = PlayerKey, - Damage = Damage, - }); - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:CheckTimeExhausted_Damage] Table ="), Table) - local Count = table.getCount(Table); - if Count == 0 then - return nil; - elseif Count == 1 then - return Table[1].PlayerKey; - end - table.sort(Table, function(a, b) return a.Damage > b.Damage; end); - if Table[1].Damage ~= Table[2].Damage then return Table[1].PlayerKey; end - return nil; -end - -function Mini_Solo:SelectMapName(MapIndex) - if DefaultSettings.EnableTest then return "Map_JCK" end - -- 过滤掉没有开放的 - if not table.isEmpty(self.PlayerSelectMaps) then - for PlayerKey, MapName in pairs(self.PlayerSelectMaps) do - if MiniGameConfig[MiniGameMapType.SoloKing].Map.MapName[MapName] == nil then - self.PlayerSelectMaps[PlayerKey] = nil; -- 设置为空 - end - end - end - - UGCLogSystem.LogTree(string.format("[Mini_Solo:SelectMapName] self.PlayerSelectMaps ="), self.PlayerSelectMaps) - -- 查看两位玩家之前选择的 - local SelectCount = table.getCount(self.PlayerSelectMaps); - if SelectCount == 1 then - for i, v in pairs(self.PlayerSelectMaps) do return v; end - elseif SelectCount == 0 then - -- 随机地图 - return self.Owner:RandomSelectMap(); - else - local PlayerNoSelectMap = {}; - for PlayerKey, Archive in pairs(ArchiveTable) do - if Archive.NoSelectMaps then - for MapName, Count in pairs(Archive.NoSelectMaps) do - PlayerNoSelectMap[PlayerKey] = (PlayerNoSelectMap[PlayerKey] or 0) + (Count > 0 and Count or 0) - end - end - end - - UGCLogSystem.LogTree(string.format("[Mini_Solo:SelectMapName] PlayerNoSelectMap ="), PlayerNoSelectMap) - if not table.isEmpty(PlayerNoSelectMap) then - local MapCounts = {}; - for PlayerKey, Count in pairs(PlayerNoSelectMap) do - table.insert(MapCounts, { - PlayerKey = PlayerKey, - Count = Count, - }) - end - table.sort(MapCounts, function(a, b) return a.Count > b.Count end) - return self.PlayerSelectMaps[MapCounts[1].PlayerKey]; - end - - local MapList = {}; - for PlayerKey, MapName in pairs(self.PlayerSelectMaps) do MapList[MapName] = (MapList[MapName] or 0) + 1; end - local Maps = {}; - for i, v in pairs(MapList) do - table.insert(Maps, { - Map = i; - val = math.pop(); - }); - end - table.sort(Maps, function(a, b) return a.val > b.val; end) - return Maps[1].Map; - end -end - ---- 在此时可以进行地图资源的加载,以及软资源的异步加载等 -function Mini_Solo:OnAlready() - UGCLogSystem.Log("[Mini_Solo:OnAlready] 可以加载地图上的东西了") - if IsServer then - PoisonManager:Init(); - end -end - -function Mini_Solo:OnPlayerGetWeapon(InPawn, InWeapon) -end - ----@param PlayerKey PlayerKey 玩家 ----@param WeaponID int32 武器ID ----@param PreCount int32 攻击前子弹数 ----@param CurrCount int32 当前子弹数(攻击后) -function Mini_Solo:OnBulletNumChange(PlayerKey, WeaponID, PreCount, CurrCount) - local Count = PreCount - CurrCount; - UGCLogSystem.Log("[Mini_Solo:OnBulletNumChange] 射击数量 = %d", Count) - self:AddSelectWeaponsArchive(PlayerKey, WeaponID, 4, Count); -end - ---- 正式开始游戏 -function Mini_Solo:Start() - UGCLogSystem.Log("[Mini_Solo:Start] 正式开始游戏,进入小游戏内部准备") -end - -Mini_Solo.HadAddWinTimes = false; -Mini_Solo.LiveInfo = { {}, {} }; - -function Mini_Solo:HandlePlayerRank(GameWinner) - if self.HadAddWinTimes then return ; end - self.HadAddWinTimes = true; - self.GameWinner = GameWinner; - UGCLogSystem.Log("[Mini_Solo:HandlePlayerRank] GameWinner = %s", tostring(GameWinner)); - - local Scores = {}; - for PlayerKey, ArchiveData in pairs(UE.GetArchiveData()) do - Scores[PlayerKey] = ArchiveData == nil and DefaultSettings.RankScore or ArchiveData.Score; - if self.GameWinner then - if self.GameWinner ~= PlayerKey and PlayerKey > 0 then self.GameLoser = PlayerKey; end - end - end - - UGCLogSystem.LogTree(string.format("[Mini_Solo:HandlePlayerRank] Scores ="), Scores) - local Diff = 0; - if self.GameLoser ~= nil and self.GameWinner ~= nil and Scores[self.GameLoser] ~= nil and Scores[self.GameWinner] ~= nil then - Diff = Scores[self.GameWinner] - Scores[self.GameLoser]; - end - - -- 计算两边比分 - local ScoreDiff = 0; - local RoundScores = {}; - for i, v in pairs(self.RoundWinners) do - if v.Winner then RoundScores[v.Winner] = (RoundScores[v.Winner] or 0) + 1; end - end - - UGCLogSystem.Log("[Mini_Solo:HandlePlayerRank] GameLoser = %s", tostring(self.GameLoser)); - - if self.GameWinner then - local Add, AddHide = 0, 0; - -- 计算技术分 - local LobbyTeamPlayerKeys = UGCTeamSystem.GetLobbyTeamKeysByPlayerKey(self.GameWinner); - for i, v in pairs(LobbyTeamPlayerKeys) do - if v ~= self.GameWinner then self.IsLobbyTeam = true; end - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:HandlePlayerRank] IsLobbyTeam = %s, LobbyTeamPlayerKeys", tostring(self.IsLobbyTeam)), LobbyTeamPlayerKeys) - - if self:IsFormalMode() then - if self.GameWinner and self.GameLoser then - ScoreDiff = (RoundScores[self.GameWinner] or 0) - (RoundScores[self.GameLoser] or 0); - ScoreDiff = math.abs(ScoreDiff); - end - - Add = self.AddFunc(Diff, Scores[self.GameWinner], true); - - --- 额外分 - if ScoreDiff > 0 and Add < 10 then - local OtherAddTable = { - [2] = math.random(2), - [3] = 3, - [4] = 5, - }; - local OtherAdd = OtherAddTable[ScoreDiff] or 0; - if not self.IsLobbyTeam then OtherAdd = 5; end - Add = Add + OtherAdd; - end - - --- 扣除隐藏分 - local HideScore = ArchiveTable[self.GameWinner].HideScore or 0; - if Add > 0 and (HideScore ~= 0) then - if HideScore > 0 then - if HideScore > Add then - AddHide = Add; - Add = Add + Add; - ArchiveTable[self.GameWinner].HideScore = HideScore - Add; - else - AddHide = ArchiveTable[self.GameWinner].HideScore; - Add = Add + HideScore; - ArchiveTable[self.GameWinner].HideScore = 0; - end - end - end - UGCLogSystem.Log("[Mini_Solo:HandlePlayerRank] PlayerKey %s 加分为 %d", tostring(self.GameWinner), Add); - - ArchiveTable[self.GameWinner].TotalGameTimes = (ArchiveTable[self.GameWinner].TotalGameTimes or 0) + 1; - ArchiveTable[self.GameWinner].GameWinTimes = (ArchiveTable[self.GameWinner].GameWinTimes or 0) + 1; - ArchiveTable[self.GameWinner].Score = (ArchiveTable[self.GameWinner].Score or DefaultSettings.RankScore) + Add; - - self:OnPostPlayerRank(self.GameWinner, true); - end - - -- 发送 RPC - self.RankScores[1] = { - PlayerKey = self.GameWinner, - Current = ArchiveTable[self.GameWinner].Score, -- 当前分数,之前分数 = Current - Add - Add = Add, -- 最终分数,要获取应该减去的分 = Add - AddHide - AddHide = AddHide, -- 添加的隐藏分 - HideScore = ArchiveTable[self.GameWinner].HideScore, - }; - - if self.GameLoser then - local Reduce, ReduceHide = 0, 0; - -- 判断当前是什么状态,如果是初始直接进入的那么就不加分 - if self:IsFormalMode() then - Reduce = self.ReduceFunc(Diff, Scores[self.GameLoser]); - - UGCLogSystem.Log("[Mini_Solo:HandlePlayerRank] ScoreDiff = %d, Reduce = %d", ScoreDiff, Reduce); - if ScoreDiff > 0 and Reduce ~= 0 and (RoundScores[self.GameWinner] ~= nil and RoundScores[self.GameWinner] >= 4) then - -- 那么扣分上少扣一部分 - local AddVal = math.floor(math.abs(Reduce) / 10 * (4 - ScoreDiff)); - UGCLogSystem.Log("[Mini_Solo:HandlePlayerRank] 额外多加分:%d", AddVal); - Reduce = AddVal + Reduce; - if Reduce > -5 then Reduce = -5; end - end - - UGCLogSystem.Log("[Mini_Solo:HandlePlayerRank] Reduce = %d", Reduce); - - -- 计算隐藏分 - local HideScore = ArchiveTable[self.GameLoser].HideScore; - if Reduce < 0 and (HideScore ~= nil and HideScore ~= 0) then - if HideScore > 0 then - local Base = math.abs(Reduce); - if HideScore > Base then - Reduce = 0; - ReduceHide = Base; - ArchiveTable[self.GameLoser].HideScore = HideScore - Base; - else - Reduce = Reduce + HideScore; - ReduceHide = HideScore; - ArchiveTable[self.GameLoser].HideScore = 0; - end - else - ArchiveTable[self.GameLoser].HideScore = 0; - end - end - - ArchiveTable[self.GameLoser].TotalGameTimes = (ArchiveTable[self.GameLoser].TotalGameTimes or 0) + 1; - if Reduce ~= 0 then - ArchiveTable[self.GameLoser].Score = (ArchiveTable[self.GameLoser].Score or DefaultSettings.RankScore) + Reduce; - end - self:OnPostPlayerRank(self.GameLoser, false); - end - - self.RankScores[2] = { - PlayerKey = self.GameLoser, - Current = ArchiveTable[self.GameLoser].Score, - Add = Reduce, - AddHide = ReduceHide, - HideScore = ArchiveTable[self.GameLoser].HideScore, - }; - end - - if self:IsFormalMode() then - if not self.IsLobbyTeam then - UGCLogSystem.LogTree(string.format("[Mini_Solo:HandlePlayerRank] LiveInfo ="), self.LiveInfo); - for i, Info in pairs(self.LiveInfo) do - UGCGameSystem.SendLiveStreamingTLog(i, 411, Info); - end - end - local PlayerKeys = {}; - for i, v in pairs(UE.GetAccountInfo()) do table.insert(PlayerKeys, i); end - UGCLogSystem.LogTree(string.format("[Mini_Solo:HandlePlayerRank] PlayerKeys ="), PlayerKeys) - self:InsertLastGame(PlayerKeys[1], PlayerKeys[2]); - self:InsertLastGame(PlayerKeys[2], PlayerKeys[1]); - UGCLogSystem.Log("[Mini_Solo:HandlePlayerRank] 开始插入新的战绩"); - else - for PlayerKey, v in pairs(UE.GetAccountInfo()) do - UGCPlayerStateSystem.SavePlayerArchiveData(UE.GetPlayerUID(PlayerKey), ArchiveTable[PlayerKey]); - end - end - else - for i, v in pairs(UE.GetAccountInfo()) do - table.insert(self.RankScores, { - PlayerKey = nil, -- 用于判断是否是平局 - PK = i, - Current = ArchiveTable[i].Score, - Add = 0, - AddHide = 0, - HideScore = ArchiveTable[i].HideScore, - }); - UGCPlayerStateSystem.SavePlayerArchiveData(UE.GetPlayerUID(i), ArchiveTable[i]); - end - end - --- 无论如何都要同步一下 - UGCLogSystem.Log("[Mini_Solo:HandlePlayerRank] 同步") - - -- 这个就很小了,可以正常走 - GameState:HandleArchiveData(nil, { - "GameTimes", - "Weapons", - "WinTimes", - "CurSeason", - "IsNewSeason", - "SelectMaps", - "LastSelectMap", - "Disables", - "LastSelectWeapons", - "sw_version", - "PlayerEnableShovel", - "SeasonInfo", - "TechScore", - "Friends", - "SelectWeapons", - "Last10Games", - "NoSelectMaps", - "EnterWeapons", - "EnterWeaponIndex", - }); - - UGCLogSystem.Log("[Mini_Solo:HandlePlayerRank] 发送"); - UGCLogSystem.LogTree(string.format("[Mini_Solo:HandlePlayerRank] PlayerSelectedWeapons ="), self.PlayerSelectedWeapons); - for i, PC in pairs(UGCGameSystem.GetAllPlayerController(false)) do - -- 再次发送数据 - if not table.isEmpty(self.PlayerSelectedWeapons[PC.PlayerKey]) then - local List = {}; - for WeaponID, v in pairs(self.PlayerSelectedWeapons[PC.PlayerKey]) do - List[WeaponID] = TableHelper.DeepCopyTable(ArchiveTable[PC.PlayerKey].SelectWeapons[WeaponID]); - end - PC:SendWeapons(-1, List); - end - end -end - -function Mini_Solo:OnPostPlayerRank(PlayerKey, IsWin) - local Rank = UGCRankSystem.GetUGCRank(PlayerKey); - UGCLogSystem.Log("[Mini_Solo:OnPostPlayerRank] UGCRank Begin = %s", tostring(Rank)); - UGCRankSystem.AddRanktProgress(PlayerKey, ArchiveTable[PlayerKey].Score - Rank); -- rank 是对的 - UGCLogSystem.Log("[Mini_Solo:OnPostPlayerRank] UGCRank End = %s", tostring(UGCRankSystem.GetUGCRank(PlayerKey))); - - local PS = UGCGameSystem.GetPlayerStateByPlayerKey(PlayerKey); - if PS and UE.IsValid(PS) then PS:OnBestRank(ArchiveTable[PlayerKey].Score); end - - -- 设置分数 - local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey) - - --- 1:积分;2:技术分 - --local UID = UE.GetPlayerUID(PlayerKey); - --PC.RankingListComponent:Server_UpdateRankListScore(PC, UID, 1, ArchiveTable[PlayerKey].Score); - - if not self.IsLobbyTeam then - for i = 1, 2 do - table.insert(self.LiveInfo[i], { - UID = AccountTable[PlayerKey].UID, - TeamRank = IsWin and 1 or 2, - rankScore = ArchiveTable[PlayerKey].Score, - }); - end - end - UGCLogSystem.Log("[Mini_Solo:OnPostPlayerRank] Player:%s 积分:%s 技术分:%s", UE.GetPlayerName(PlayerKey), tostring(ArchiveTable[PlayerKey].Score), tostring(ArchiveTable[PlayerKey].Score)); -end - -function Mini_Solo:IsFormalMode() - return self.ModeType == GameModeConfig.EGameModeType.DefaultMode and table.getCount(UE.GetAccountInfo()) > 1; -end - ---- 小游戏结束 -function Mini_Solo:OnGameEnd(InResultList) - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnGameEnd] 游戏结束 InResultList ="), InResultList) - UGCLogSystem.Log("[Mini_Solo:OnGameEnd] GameWinner = %s", tostring(self.GameWinner)); - if IsServer then - if self.GameWinner == nil then - local Winners = {}; - for i, v in pairs(InResultList) do - table.insert(Winners, { - PlayerKey = i, - Score = v, - }); - end - if table.getCount(Winners) == 1 then - self.GameWinner = Winners[1].PlayerKey; - else - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnGameEnd] Winners ="), Winners) - table.sort(Winners, function(a, b) return a.Score > b.Score; end) - if Winners[1].Score == Winners[2].Score then - self.GameWinner = nil; - else - self.GameWinner = Winners[1].PlayerKey - end - end - end - if table.isEmpty(self.RankScores) then - self:HandlePlayerRank(self.GameWinner); - end - self.Owner:SendRPC("UpdatePlayerRank", self.RankScores); - end -end - -function Mini_Solo:UpdatePlayerRank(RankScores) - UGCLogSystem.LogTree(string.format("[Mini_Solo:UpdatePlayerRank] InRanks ="), RankScores); - WidgetManager:GetPanel(WidgetConfig.EUIType.GameEnd, function(Widget, ...) - Widget:OnUpdatePlayerRank(RankScores); - end, RankScores); -end - ----@param Pawn UGCPlayerPawn_C -function Mini_Solo:OnPawnInit(Pawn, InitArmor, InitMedication) - if IsServer then - if self.State < MiniGameState.ROUND_PREPARE then return ; end - if self.State >= MiniGameState.MINI_END then return ; end - -- 仅在正式模式下 - local AddArmors = TableHelper.DeepCopyTable(InitArmor); - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPawnInit] InitArmor ="), InitArmor) - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPawnInit] AddArmors ="), AddArmors) - local Medications = TableHelper.DeepCopyTable(InitMedication); - if self:IsFormalMode() then - local CurrWeaponId = 0; - if self.State == MiniGameState.ROUND_PREPARE then - -- 说明此时拿取第一把枪即可 - CurrWeaponId = self.SelectWeapons[1]; - else - CurrWeaponId = self.CurrWeaponItem[Pawn.PlayerKey] or ItemTool.GetFirstWeaponID(Pawn.PlayerKey); - end - - UGCLogSystem.Log("[Mini_Solo:OnPawnInit] CurrWeaponId = %d", CurrWeaponId); - if WeaponTable[CurrWeaponId] and WeaponTable[CurrWeaponId].TypeNew then - local SpecialConfig = self.SpecialWeapon[WeaponTable[CurrWeaponId].TypeNew]; - if SpecialConfig and SpecialConfig.InitArmors then - for i, v in pairs(SpecialConfig.InitArmors) do - AddArmors[i] = SpecialConfig.InitArmors[i]; - end - end - end - end - - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPawnInit] AddArmors ="), AddArmors) - - local AddItems = {}; - for i, v in pairs(AddArmors) do - table.insert(AddItems, { v, 1 }); - end - - for i, v in pairs(Medications) do - table.insert(AddItems, v); - end - - Pawn:AddInitItems(AddItems); - UGCEventSystem.SetTimer(GameState, function() - -- 判断当前有哪些东西 - local DelayWeapons = MiniGameConfig[MiniGameMapType.SoloKing].DelayWeapons; - Pawn:AddInitItems(DelayWeapons); - end, 1); - end -end - -Mini_Solo.RoundDamages = {}; - ---- 玩家受到伤害回调 ----@param DamagedActor UGCPlayerPawn_C ----@param Damage float ----@param DamageType EDamageType ----@param EventInstigator UGCPlayerController_C -function Mini_Solo:OnPlayerTakeDamage(DamagedActor, Damage, DamageType, EventInstigator) - UGCLogSystem.Log("[Mini_Solo:OnPlayerTakeDamage] 收到的伤害为 %f, DamagedActor = %s", Damage, UE.GetName(DamagedActor)); - -- 选择武器期间不受伤害 - if EventInstigator ~= nil and UE.IsValid(EventInstigator) and EventInstigator.PlayerKey ~= DamagedActor.PlayerKey then - local PlayerKey = EventInstigator.PlayerKey; - self.Damages[PlayerKey] = (self.Damages[PlayerKey] or 0) + Damage; - self.RoundDamages[PlayerKey] = (self.RoundDamages[PlayerKey] or 0) + Damage; - end - return Damage; -end - ---- 因为在短短的时间内,只可能有一个玩家死亡,因此只需要一个变量即可 -Mini_Solo.IsPlayerDying = false; - ---- 玩家死亡回调 -function Mini_Solo:OnPlayerDead(InPlayerKey, InCauserKey) - UGCLogSystem.Log("[Mini_Solo:OnPlayerDead] PlayerKey = %s, CauserKey = %s", tostring(InPlayerKey), tostring(InCauserKey)); - -- 检查是否 - if IsServer then - if self.State == MiniGameState.ROUND_GAMING then - -- 检查一下是否已经击杀三局了 - local WinnerPlayerKey = 0; - for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do - if v.PlayerKey == InPlayerKey then - --- 计算死亡者的 KD - self.RoundDeadTimes[InPlayerKey] = (self.RoundDeadTimes[InPlayerKey] or 0) + 1; - self.TotalKDA[InPlayerKey].Dead = (self.TotalKDA[InPlayerKey].Dead or 0) + 1; - ArchiveTable[InPlayerKey].Dead = (ArchiveTable[InPlayerKey].Dead or 0) + 1; - else - self.RoundDeadTimes[v.PlayerKey] = self.RoundDeadTimes[v.PlayerKey] or 0; - local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(v.PlayerKey); - if UE.IsValidPawn(Pawn) then - UGCPawnAttrSystem.SetHealth(Pawn, UGCPawnAttrSystem.GetHealth(Pawn) + self.KillHealing); - if not self.EnableInsult then - UGCPawnSystem.DisabledPawnState(Pawn, EPawnState.GunFire, true); - UGCPawnSystem.DisabledPawnState(Pawn, EPawnState.MeleeAttack, true); - end - end - WinnerPlayerKey = v.PlayerKey; - end - end - - --- 计算击杀者的分数 - if InCauserKey ~= nil and InCauserKey ~= InPlayerKey and InCauserKey > 0 then - self.TotalKDA[InCauserKey].Kill = (self.TotalKDA[InCauserKey].Kill or 0) + 1; - if ArchiveTable[InCauserKey] then - ArchiveTable[InCauserKey].Kill = (ArchiveTable[InCauserKey].Kill or 0) + 1; - end - end - - self:DOREPONCE("RoundDeadTimes"); - self.IsPlayerDying = true; - if self.RoundDeadTimes[InPlayerKey] == nil or self.RoundDeadTimes[InPlayerKey] >= self.KillTimes then - -- 结束 - if self.RoundWinner == nil then - self.RoundWinner = WinnerPlayerKey; - UGCLogSystem.Log("[Mini_Solo:OnPlayerDead] InCauserKey = %d, State = %s", InCauserKey, TableHelper.printEnum(MiniGameState, self.State)); - self.bRoundEnd = true; - local WeaponId = self.CurrWeaponItem[WinnerPlayerKey] or ItemTool.GetFirstWeaponID(WinnerPlayerKey); - -- 检查一下是否超过一半 - table.insert(self.RoundWinners, { - Winner = self.RoundWinner, - Time = UE.GetServerTime() - self.RoundStartTime, - -- 拿到对方的枪械 - Weapon = WeaponId, - Score = { - Winner = self.RoundDeadTimes[InPlayerKey] or 0, -- 这个是阵亡数,需要反过来 - Loser = self.RoundDeadTimes[self.RoundWinner] or 0, - }, - }); - if self:IsFormalMode() then - self:AddSelectWeaponsArchive(self.RoundWinner, WeaponId, 3, 1); - end - - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPlayerDead] self.RoundWinners ="), self.RoundWinners) - -- 同步一下 - self:DOREPONCE("RoundWinners"); - local IsOver, WinnerID = self:CheckGameEnd(); - if IsOver then - self.GameLoser = InPlayerKey; - self:SetGameOver(WinnerID); - end - UGCEventSystem.SendEvent(EventTypes.UpdateRoundWinners, self.RoundWinners); - end - else - -- 玩家重生 - UGCEventSystem.SetTimer(GameState, function() - UE.ResetGame1(0.1); - end, self.ResetTime); - end - local PlayerDamageTable = {}; - for i, PC in pairs(UGCGameSystem.GetAllPlayerController(false)) do - local PlayerKey = PC.PlayerKey; - local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey); - PlayerDamageTable[PlayerKey] = { - Damage = self.Damages[PlayerKey] or 0, - Health = UE.IsValidPawn(Pawn) and UGCPawnAttrSystem.GetHealth(Pawn) or 0, - }; - end - self.Owner:SendRPC("AfterPlayerDead", PlayerDamageTable); - end - self.DeadCount = self.DeadCount + 1; - end -end - -function Mini_Solo:AfterPlayerDead(InTable) - UGCLogSystem.LogTree(string.format("[Mini_Solo:AfterPlayerDead] InTable ="), InTable) - -end - -Mini_Solo.CurrWeaponItem = {}; - -function Mini_Solo:OnPlayerRespawn(InPlayerKey) - -- 设置该玩家不能动 - if IsServer then - self.IsPlayerDying = false; - self.Damages[InPlayerKey] = 0; - else - if InPlayerKey == LocalPlayerKey then - if self.ModeType ~= GameModeConfig.EGameModeType.DefaultMode then - --WidgetManager:ShowPanel(WidgetConfig.EUIType.ShowCustomSelectWeaponBtn, false); - WidgetManager:GetPanel(WidgetConfig.EUIType.Main, function(Widget) - table.func(Widget, "ShowCustomSelectWeaponBtn", true); - end); - end - end - end -end - -function Mini_Solo:OnRep_RoundWinners() - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnRep_RoundWinners] RoundWinners"), self.RoundWinners) - UGCEventSystem.SendEvent(EventTypes.UpdateRoundWinners, self.RoundWinners); -end - -function Mini_Solo:OnPlayerLeave(InPlayerKey) - UGCLogSystem.Log("[Mini_Solo:OnPlayerLeave] 玩家 %d 退出", InPlayerKey) - -- 直接结束 - if self.State >= MiniGameState.MINI_END then return ; end - if IsServer then - local PlayerKeys = {}; - for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do - if UE.IsValid(v) and v.PlayerKey ~= InPlayerKey then - PlayerKeys[v.PlayerKey] = 1; - if v.PlayerKey ~= InPlayerKey then - self.GameWinner = v.PlayerKey; - self.RoundWinner = self.GameWinner; - end - end - end - UGCLogSystem.Log("[Mini_Solo:OnPlayerLeave] GameWinner = %s", tostring(self.GameWinner)) - table.printTable(PlayerKeys); - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPlayerLeave] PlayerKeys ="), PlayerKeys) - if table.getCount(PlayerKeys) == 1 then - for i, v in pairs(PlayerKeys) do self.GameWinner = i; end - -- 查看哪个玩家已经够局数了 - if self.State == MiniGameState.ROUND_GAMING then - local WeaponID = self.CurrWeaponItem[self.GameWinner] or ItemTool.GetFirstWeaponID(self.GameWinner) - table.insert(self.RoundWinners, { - Winner = self.GameWinner, - Time = UE.GetServerTime() - self.RoundStartTime, - -- 拿到对方的枪械 - Weapon = WeaponID, - Score = { - Winner = self.RoundDeadTimes[InPlayerKey] or 0, -- 这个是阵亡数,需要反过来 - Loser = self.RoundDeadTimes[self.GameWinner] or 0, - }, - }); - if self:IsFormalMode() then - self:AddSelectWeaponsArchive(self.RoundWinner, WeaponID, 3, 1) - end - self:DOREPONCE("RoundWinners"); - end - - self:HandlePlayerRank(self.GameWinner); - self:SetGameOver(self.GameWinner); - end - end - - UGCLogSystem.Log("[Mini_Solo:OnPlayerLeave] 结束执行"); -end - ----@param WinnerId int32 -function Mini_Solo:SetGameOver(WinnerId) - UGCLogSystem.Log("[Mini_Solo:SetGameOver] 设置游戏结束, Winner = %s", UE.GetPlayerName(WinnerId)); - self.GameWinner = WinnerId; - - local WinTable = {}; - for _, Info in pairs(self.RoundWinners) do - if Info.Winner then - WinTable[Info.Winner] = (WinTable[Info.Winner] or 0) + 1; - end - end - - if self.GameWinner == nil then - -- 获取胜利的 - if table.getCount(UE.GetAccountInfo()) == 1 then - for i, PC in pairs(UGCGameSystem.GetAllPlayerController(false)) do - self.GameWinner = PC.PlayerKey; - end - else - local Wins = {}; - for PlayerKey, WinTimes in pairs(WinTable) do - table.insert(Wins, { - PlayerKey = PlayerKey, - WinTimes = WinTimes, - }); - end - table.sort(Wins, function(a, b) - return a.WinTimes > b.WinTimes; - end); - UGCLogSystem.LogTree(string.format("[Mini_Solo:SetGameOver] Wins ="), Wins) - self.GameWinner = Wins[1].PlayerKey; - if Wins[2] then - self.GameLoser = Wins[2].PlayerKey; - end - end - end - - UGCLogSystem.Log("[Mini_Solo:SetGameOver] GameWinner = %s, WinnerId = %s", tostring(self.GameWinner), tostring(WinnerId)); - - if self.GameLoser == nil then - for PlayerKey, Info in pairs(UE.GetAccountInfo()) do - if PlayerKey ~= self.GameWinner then self.GameLoser = PlayerKey; end - end - end - - self:DOREPONCE("GameWinner"); - - self.bGameEnd = true; - self.bRoundEnd = true; -end - -function Mini_Solo:InsertLastGame(PlayerKey, OtherKey) - UGCLogSystem.Log("[Mini_Solo:InsertLastGame] 开始执行"); - local WinTable = {}; - for _, Info in pairs(self.RoundWinners) do - if Info.Winner then - WinTable[Info.Winner] = (WinTable[Info.Winner] or 0) + 1; - end - end - - UGCLogSystem.LogTree(string.format("[Mini_Solo:InsertLastGame] RoundWinners ="), self.RoundWinners); - - local WinRoundTable = {}; - for i, v in pairs(self.RoundWinners) do - local IsWin = PlayerKey == v.Winner; - table.insert(WinRoundTable, { - PlayerKey == v.Winner, -- IsWin 1 - v.Weapon, -- WeaponID 2 - IsWin and v.Score.Winner or v.Score.Loser, -- 3 - IsWin and v.Score.Loser or v.Score.Winner, -- 4 - }); - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:SetGameOver] WinRoundTable "), WinRoundTable); - -- 直接添加 - local Last10Games = ArchiveTable[PlayerKey].Last10Games - if Last10Games == nil then - ArchiveTable[PlayerKey].Last10Games = {}; - end - local CurrCount = #(ArchiveTable[PlayerKey].Last10Games); - if CurrCount >= 10 then - table.remove(ArchiveTable[PlayerKey].Last10Games, 1); -- 移除第一个即可,以为不可能超过 10 个,最多 10 个 - end - - local IsWin = PlayerKey == self.GameWinner; - UGCLogSystem.LogTree(string.format("[Mini_Solo:InsertLastGame] RankScores ="), self.RankScores) - - local LastGame = { - IsWin, -- IsWin 1 - UE.GetPlayerUID(OtherKey), -- UID 2 - WinTable[PlayerKey] or 0, -- MyScore 3 - WinTable[OtherKey] or 0, -- EnemyScore 4 - self.RankScores[IsWin and 1 or 2].Current or 0, -- Score 5 - self.RankScores[IsWin and 1 or 2].Add or 0, -- Add Score 6 - self.TotalKDA[PlayerKey].Kill or 0, -- Kill 7 - self.TotalKDA[PlayerKey].Dead or 0, -- Dead 8 - WinRoundTable, -- GameInfo 9 - } - table.insert(ArchiveTable[PlayerKey].Last10Games, LastGame); - - -- 检查是否存在 Player - if ArchiveTable[PlayerKey].Friends == nil then ArchiveTable[PlayerKey].Friends = {}; end - if ArchiveTable[PlayerKey].Friends[UE.GetPlayerUID(OtherKey)] == nil then - ArchiveTable[PlayerKey].Friends[UE.GetPlayerUID(OtherKey)] = { - UE.GetPlayerName(OtherKey), - UE.GetPlayerIconURL(OtherKey), - }; - end - - local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey); - if PC and UE.IsValid(PC) then - PC:SendNewArchive(CurrCount + 1, LastGame, ArchiveTable[PlayerKey].Friends[UE.GetPlayerUID(OtherKey)]); - end - - -- 清空其他的 - local ExistFriends = {}; - for i, v in pairs(ArchiveTable[PlayerKey].Last10Games) do - -- 获取玩家的 UID - local UID = nil; - if type(v[2]) == 'table' then - UID = v[2][1]; - elseif type(v[2]) == 'number' then - UID = v[2] - end - if UID then ExistFriends[UID] = 1; end - end - - local Removes = {}; - for UID, v in pairs(ArchiveTable[PlayerKey].Friends) do - if ExistFriends[UID] == nil then table.insert(Removes, UID); end - end - - for i, UID in pairs(Removes) do - ArchiveTable[PlayerKey].Friends[UID] = nil; - end - - UGCLogSystem.LogTree(string.format("[Mini_Solo:InsertLastGame] ArchiveTable[PlayerKey].Last10Games ="), ArchiveTable[PlayerKey].Last10Games) - UGCPlayerStateSystem.SavePlayerArchiveData(UE.GetPlayerUID(PlayerKey), ArchiveTable[PlayerKey]); -end - -function Mini_Solo:OnRep_GameWinner() - -- 因为无法保证顺序,所以需要这样传输 - UGCEventSystem.SetTimer(GameState, function() - UGCEventSystem.SendEvent(EventTypes.UpdateGameWinner, self.GameWinner, self.RoundWinners); - end, 0.3); -end - ---- 检查是否游戏结束了 -function Mini_Solo:CheckGameEnd() - local Winners = {}; - for i, v in pairs(self.RoundWinners) do - if v.Winner then Winners[v.Winner] = 1 + (Winners[v.Winner] or 0); end - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:CheckGameEnd] Winners ="), Winners) - for i, v in pairs(Winners) do - if v > self.TotalRoundTimes // 2 then - self.GameWinner = i; - UGCLogSystem.Log("[Mini_Solo:CheckGameEnd] GameWinner = %s", tostring(i)); - return true, i; - end - end - return false; -end - ---- 存在一个内部参数可以控制 Tick,bEnableTick 设置为 false 就会停止 Tick -function Mini_Solo:OnTick(InDeltaTime, InServerTime) -end - ---- 小局初始化(每一次小局开始前都会调用) -function Mini_Solo:OnRoundStart(InTimes) - UGCLogSystem.Log("[Mini_Solo:OnRoundStart] 执行, InTimes = %d", InTimes) - if IsServer then - -- 显示选择武器界面 - self.RoundWinner = nil; - self.RoundDeadTimes = {}; - self:DOREPONCE("RoundDeadTimes") - else - UGCLogSystem.Log("[Mini_Solo:OnRoundStart] 执行") - UGCEventSystem.SendEvent(EventTypes.ShowRoundWin, false); - end - - UE.ClearSceneObjects(); - return true; -end - -function Mini_Solo:OnRep_RoundDeadTimes() - WidgetManager:GetPanel(WidgetConfig.EUIType.Main, function(Widget) - Widget:SetRoundKill(self.RoundDeadTimes); - end) -end - ---- 小局结束当前回合,每小局都会执行 -function Mini_Solo:OnRoundEnd(InRoundTimes, Winner) - UGCLogSystem.Log("[Mini_Solo:OnRoundEnd] RoundTimes = %d, Winner = %s", InRoundTimes, tostring(Winner)); - if IsServer then - -- 计算当前数据 - if self.CheckPlayerExistHandler ~= nil then - UGCEventSystem.StopTimer(self.CheckPlayerExistHandler); - self.CheckPlayerExistHandler = nil; - end - else - UGCEventSystem.SendEvent(EventTypes.ShowRoundWin, true, Winner); - -- 显示回合胜利 - --WidgetManager:GetPanel(WidgetConfig.EUIType.Main, function(Widget) - -- Widget:ShowRoundWin(true, Winner); - --end); - end -end - -Mini_Solo.CheckPlayerExistHandler = nil; - ---- 小局正式开始游戏(每一次都会调用) -function Mini_Solo:OnRoundFormalStart() - UGCLogSystem.Log("[Mini_Solo:OnRoundFormalStart] 小局正式开始"); - if IsServer then - local HadChanged = false; - -- 玩家装备对应武器 - if self.ModeType == GameModeConfig.EGameModeType.DefaultMode then - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnRoundFormalStart] CurrWeapon Begin"), self.CurrWeapon) - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnRoundFormalStart] SelectWeapons Begin"), self.SelectWeapons) - -- 从列表中随机给一把枪 - local WeaponId = self.SelectWeapons[1]; - if WeaponId then - table.remove(self.SelectWeapons, 1); - for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do - local PlayerKey = v.PlayerKey; - self.CurrWeaponItem[PlayerKey] = WeaponId; - HadChanged = true; - if self.PlayerSelectedWeapons[PlayerKey] == nil then self.PlayerSelectedWeapons[PlayerKey] = {}; end - self.PlayerSelectedWeapons[PlayerKey][WeaponId] = 1; - self:AddSelectWeaponsArchive(PlayerKey, WeaponId, 2, 1); - -- 玩家直接添加武器 - self:PlayerAddWeapon(PlayerKey, self.CurrWeaponItem[PlayerKey]); - end - end - - -- 移除对应的东西 - self:DOREPONCE("SelectWeapons"); - GameState:SetSelectGameMode(self.ModeType); - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnRoundFormalStart] SelectWeapons End"), self.SelectWeapons) - else - UGCLogSystem.Log("[Mini_Solo:OnRoundFormalStart] 娱乐模式") - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnRoundFormalStart] self.EnterWeaponItem ="), self.EnterWeaponItem) - -- 去读取一下,否则就用默认的枪械 - for i, PC in pairs(UGCGameSystem.GetAllPlayerController(false)) do - local PlayerKey = PC.PlayerKey; - if table.isEmpty(self.EnterWeaponItem[PlayerKey]) then - local EnterWeapons = ArchiveTable[PlayerKey].EnterWeapons or WeaponSelectionCombinationConfig.WeaponCombinationList.Weapon; - local EnterWeaponIndex = ArchiveTable[PlayerKey].EnterWeaponIndex or 1; - self.EnterWeaponItem[PlayerKey] = EnterWeapons[EnterWeaponIndex]; - HadChanged = true; - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnRoundFormalStart] EnterWeaponItem ="), self.EnterWeaponItem[PlayerKey]) - local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey); - if Pawn and UE.IsValid(Pawn) then - Pawn:UpdateSlotWeapons(self.EnterWeaponItem[PlayerKey]); - end - end - end - - if HadChanged then - self:DOREPONCE("CurrWeaponItem") - end - - self.RoundDamages = {}; - PoisonManager:Toggle(true); - if self.CheckPlayerExistHandler ~= nil then - UGCEventSystem.StopTimer(self.CheckPlayerExistHandler); - self.CheckPlayerExistHandler = nil; - end - self.CheckPlayerExistHandler = UGCEventSystem.SetTimerLoop(GameState, function() - self:CheckPlayerExist(); - end, 5); - else - --self:AllPawnsAddOutline(); - if GlobalModeType == nil then - GlobalModeType = GameModeConfig.EGameModeType.DefaultMode; - UGCEventSystem.SendEvent(EventTypes.UpdateModeType, GlobalModeType); - end - end - UE.ClearSceneObjects(); -end - ---- 娱乐模式下玩家获取武器 ----@param PlayerKey PlayerKey ----@param Index int32|nil -function Mini_Solo:GetPlayerEnterWeapons(PlayerKey, Index) - local Weapons = ItemTool.GetPlayerEnterWeapons(PlayerKey, Index); - self.EnterWeaponItem[PlayerKey] = TableHelper.DeepCopyTable(Weapons); - return Weapons; -end - ---- 检测玩家是否存在 -function Mini_Solo:CheckPlayerExist(dt, st) - -- 说明此时走了正常逻辑 - if self.IsPlayerDying == true then return ; end - - local Pawns = UGCGameSystem.GetAllPlayerPawn(); - local AlivePawns = {}; - local WinnerPlayerKey = 0; - local Count = 0; - for i, v in pairs(Pawns) do - if UE.IsValidPawn(v) then - AlivePawns[v.PlayerKey] = v; - WinnerPlayerKey = v.PlayerKey; - Count = Count + 1; - end - end - if Count > 1 then return ; end - if Count == 1 then - local DeadPlayerKey = 0; - -- 说明当前结束了,此时判断玩家是否计算了 - for PlayerKey, Info in pairs(UE.GetAccountInfo()) do - if WinnerPlayerKey ~= PlayerKey then DeadPlayerKey = PlayerKey; end - end - self:OnPlayerDead(DeadPlayerKey, WinnerPlayerKey); - end -end - -function Mini_Solo:AllPawnsAddOutline() - UGCLogSystem.Log("[Mini_Solo:AllPawnsAddOutline] 执行") - for i, Pawn in pairs(UGCGameSystem.GetAllPlayerPawn()) do - if UE.IsValidPawn(Pawn) then - UGCLogSystem.Log("[Mini_Solo:AllPawnsAddOutline] 添加描边") - Pawn:AddOutline(); - end - end -end - ----@param Pawn UGCPlayerPawn_C ----@param Controller UGCPlayerController_C -function Mini_Solo:OnPlayerPossessed(Pawn, Controller) - -- 清空玩家身上的武器 - if self.ModeType == GameModeConfig.EGameModeType.DefaultMode then - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPlayerPossessed] CurrWeaponItem"), self.CurrWeaponItem) - if table.isEmpty(self.CurrWeaponItem) then return ; end - UGCLogSystem.Log("[Mini_Solo:OnPlayerPossessed] 开始准备添加武器") - if self.CurrWeaponItem[Pawn.PlayerKey] ~= nil then - UGCEventSystem.SetTimer(Pawn, function() - UGCLogSystem.Log("[Mini_Solo:OnPlayerPossessed] 开始添加武器") - local Weapon = ItemTool.GetPlayerFirstWeapon(Pawn); - if Weapon == nil or not UE.IsValid(Weapon) or Weapon:GetWeaponItemID() ~= self.CurrWeaponItem[Pawn.PlayerKey] then - self:PlayerAddWeapon(Pawn.PlayerKey, self.CurrWeaponItem[Pawn.PlayerKey]); - end - end, 1); - end - else - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnPlayerPossessed] EnterWeaponItem ="), self.EnterWeaponItem); - if table.isEmpty(self.EnterWeaponItem) then return ; end - UGCEventSystem.SetTimer(Pawn, function() - Pawn:UpdateSlotWeapons(self.EnterWeaponItem[Pawn.PlayerKey]); - end, 1); - end -end - -Mini_Solo.CheckWeaponTimer = nil; - -function Mini_Solo:CloseCheckWeaponTimer() - -- 关闭 - if self.CheckWeaponTimer ~= nil then - UGCEventSystem.StopTimer(self.CheckWeaponTimer); - self.CheckWeaponTimer = nil; - end -end - -function Mini_Solo:CheckWeapon() - if table.isEmpty(self.CurrWeaponItem) then - return self:CloseCheckWeaponTimer(); - end - local HasWeaponCount = 0; - for i, Pawn in pairs(UGCGameSystem.GetAllPlayerPawn()) do - if UE.IsValidPawn(Pawn) then - -- 判断当前是什么武器 - if self.CurrWeaponItem[Pawn.PlayerKey] then - local HasWeapon = false; - local RemoveTypes = {}; - -- 检查当前是什么玩意 - local WeaponInfo = WeaponTable[self.CurrWeaponItem[Pawn.PlayerKey]] - if WeaponInfo then - if WeaponInfo.TypeNew == EWeaponTypeNew.EWeaponTypeNew_Melee then - -- 获取所有武器 - local AllItemData = UGCBackPackSystem.GetAllItemData(Pawn); - for _, Info in pairs(AllItemData) do - if Info.ItemID == self.CurrWeaponItem[Pawn.PlayerKey] then - UGCLogSystem.Log("[Mini_Solo:CheckWeapon] 找到武器了,近战武器") - HasWeapon = true; - HasWeaponCount = HasWeaponCount + 1; - - if Info.Count >= 2 then - UGCBackPackSystem.DropItem(Pawn, Info.ItemID, Info.Count - 1, true); - end - end - end - - for _, Type in pairs(AllWeaponEnums) do - local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(Pawn, Type); - if Weapon ~= nil and UE.IsValid(Weapon) then - if Weapon:GetWeaponItemID() ~= self.CurrWeaponItem[Pawn.PlayerKey] then - -- 检查是否有其他武器 - table.insert(RemoveTypes, { - DefineID = Weapon:GetItemDefineID(), - Count = 1; - }); - end - end - end - else - for _, Type in pairs(AllWeaponEnums) do - local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(Pawn, Type); - if Weapon ~= nil and UE.IsValid(Weapon) then - if Weapon:GetWeaponItemID() == self.CurrWeaponItem[Pawn.PlayerKey] then - UGCLogSystem.Log("[Mini_Solo:CheckWeapon] 找到武器了") - HasWeapon = true; - HasWeaponCount = HasWeaponCount + 1; - else - -- 检查是否有其他武器 - table.insert(RemoveTypes, { - DefineID = Weapon:GetItemDefineID(), - Count = 1; - }); - end - end - end - end - end - -- 有的话就移除 - if not table.isEmpty(RemoveTypes) then - local BackpackComp = UGCBackPackSystem.GetBackpackComponent(Pawn); - for j = 1, #RemoveTypes do - local Item = RemoveTypes[j]; - UGCLogSystem.Log("[Mini_Solo:CheckWeapon] 移除别的武器:%d", Item.DefineID.TypeSpecificID); - BackpackComp:DropItem(Item.DefineID, Item.Count, EBattleItemDropReason.Force); - end - end - - if not HasWeapon then - UGCLogSystem.Log("[Mini_Solo:CheckWeapon] 没有武器,给他加上") - -- 给玩家添加上去 - self:PlayerAddWeapon(self.CurrWeaponItem[Pawn.PlayerKey]) - -- 然后过一段时间补满子弹 - ItemTool.FillAllWeaponBullets(Pawn); - end - end - end - end - if HasWeaponCount == 2 then - self:CloseCheckWeaponTimer(); - end -end - ---- 玩家添加武器到备选列表 -function Mini_Solo:PlayerAddWeapon(PlayerKey, Weapon) - local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey); - if Pawn and UE.IsValid(Pawn) and Pawn:IsAlive() then - ItemTool.ClearAllWeapon(Pawn); - if Weapon then - UGCLogSystem.Log("[Mini_Solo:PlayerAddWeapon] 开始添加") - Pawn:AddItem(Weapon, 1, true, EFillBulletType.ClipInfinite); - - -- 添加其他倍镜 - local NeedAddTelescope = ItemTool.GetOtherTelescopes(Pawn); - -- 检查当前武器上是否有倍镜 - - for i, v in pairs(NeedAddTelescope) do - Pawn:AddItem(i, 1, false); - end - - -- 判断武器上原本是否有该配件 - if ArchiveTable[PlayerKey] and ArchiveTable[PlayerKey].Weapons[Weapon] then - if WeaponSuits[Weapon] then - if WeaponSuits[Weapon][EWeaponPartType.Telescope] then - local HaveParts = {}; - for i, PartID in pairs(WeaponSuits[Weapon][EWeaponPartType.Telescope]) do - HaveParts[PartID] = 1; - end - local Parts = ArchiveTable[PlayerKey].Weapons[Weapon]; - -- 判断是否有倍镜 - local HavePart = false; - for i, PartID in pairs(Parts) do - if HaveParts[PartID] then HavePart = true; end - end - - -- 移除 - if not HavePart then - local Weapons = ItemTool.GetWeaponsById(Pawn, Weapon) - for i, v in pairs(Weapons) do - UGCGunSystem.RemoveGunAttachmentBySocketType(v, ItemTool.GetWeaponAttachmentSocketType(EWeaponPartType.Telescope)); - end - end - end - end - end - - -- 启动检测 - self:CloseCheckWeaponTimer(); - self.CheckWeaponTimer = UGCEventSystem.SetTimerLoop(GameState, function() - UGCLogSystem.Log("[Mini_Solo:OnPlayerPossessed] 检查是否有武器") - self:CheckWeapon(); - end, 1); - end - end -end - ----@param PlayerStartList table> ----@param Controller UGCPlayerController_C -function Mini_Solo:SelectPlayerStart(PlayerStartList, Controller) - local TeamId = UGCPlayerControllerSystem.GetTeamID(Controller); - if self.DeadCount % 2 == 0 then - return PlayerStartList[TeamId]; - else - local Reverse = ((TeamId + 1) % 2 == 0) and 2 or 1; - return PlayerStartList[Reverse]; - end - return nil; -- 否则使用默认的方式 -end - -function Mini_Solo:GetRoundWinner(InTimes) - -- 获取当前回合赢了的玩家 / TeamId - if self.RoundWinner == nil then - -- 检查一下是否是玩家退出 - local LastPCs = UGCGameSystem.GetAllPlayerController(false); - if table.getCount(LastPCs) == 1 then - for i, v in pairs(LastPCs) do - self:SetRoundWinner(v.PlayerKey) - return self.RoundWinner; - end - end - -- 设置一下 - local DeadTimesTable = {}; - for PlayerKey, DeadTimes in pairs(self.RoundDeadTimes) do - table.insert(DeadTimesTable, { - PlayerKey = PlayerKey, - DeadTimes = DeadTimes, - }); - end - if #DeadTimesTable > 0 then - table.sort(DeadTimesTable, function(a, b) - return a.DeadTimes < b.DeadTimes; - end); - if #DeadTimesTable == 1 then - UE.ForeachAllPCs(function(PC) - if PC.PlayerKey ~= DeadTimesTable[1].PlayerKey then - self:SetRoundWinner(PC.PlayerKey); - end - end) - return self.RoundWinner; - else - if DeadTimesTable[1].DeadTimes < DeadTimesTable[2].DeadTimes then - self:SetRoundWinner(DeadTimesTable[1].PlayerKey); - return self.RoundWinner; - end - end - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:GetRoundWinner] DeadTimesTable ="), DeadTimesTable) - -- 判断一下生命值,到这步肯定是两个玩家都存活 - local HealthTable = {}; - UE.ForeachAllPCs(function(PC) - local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PC.PlayerKey); - if UE.IsValidPawn(Pawn) then - table.insert(HealthTable, { - PlayerKey = PC.PlayerKey, - Health = UGCPawnAttrSystem.GetHealth(Pawn), - }); - else - table.insert(HealthTable, { - PlayerKey = PC.PlayerKey, - Health = 0, - }); - end - end) - UGCLogSystem.LogTree(string.format("[Mini_Solo:GetRoundWinner] HealthTable ="), HealthTable) - if table.getCount(HealthTable) > 1 then - table.sort(HealthTable, function(a, b) - return a.Health > b.Health; - end) - if HealthTable[1].Health ~= HealthTable[2].Health then - self:SetRoundWinner(HealthTable[1].PlayerKey); - return self.RoundWinner; - end - end - -- 判断伤害 - local Damages = {}; - for PlayerKey, Damage in pairs(self.RoundDamages) do - table.insert(Damages, { - PlayerKey = PlayerKey, - Damage = Damage, - }); - end - if #Damages == 2 then - table.sort(Damages, function(a, b) - return a.Damage > b.Damage; - end); - if Damages[1].Damage > Damages[2].Damage then - self:SetRoundWinner(Damages[1].PlayerKey); - return self.RoundWinner; - end - elseif #Damages == 1 then - self:SetRoundWinner(Damages[1].PlayerKey); - return self.RoundWinner; - end - UGCLogSystem.LogTree(string.format("[Mini_Solo:GetRoundWinner] Damages ="), Damages) - end - return self.RoundWinner; -end - -function Mini_Solo:SetRoundWinner(InWinner) - self.RoundWinner = InWinner; - self:DOREPONCE("RoundWinners"); -end - -function Mini_Solo:GetScore() - -- 获取几方的一个数组,然后进行排好序 - local Rounds = {}; - for i, v in pairs(self.RoundWinners) do - if v.Winner then - Rounds[v.Winner] = (Rounds[v.Winner] or 0) + 1; - end - end - return Rounds; -end - -------------------------------------------- 武器 ------------------------------------------- -function Mini_Solo:OnSelectWeapons(InPlayerKey, ItemId, IsSelect) - if self.State ~= MiniGameState.MINI_PREPARE then return ; end - UGCLogSystem.Log("[Mini_Solo:OnSelectWeapons] 开始选择 InPlayerKey = %d, ItemId = %d, IsSelect = %s", InPlayerKey, ItemId, tostring(IsSelect)); - if self.SelectWeapons[InPlayerKey] == nil then - self.SelectWeapons[InPlayerKey] = {}; - end - if IsSelect then - -- 检查是否超过约定个数 - if table.getCount(self.SelectWeapons[InPlayerKey]) < self.SelectWeaponCount then - local Find = false; - for i, v in pairs(self.SelectWeapons[InPlayerKey]) do - if v == ItemId then - Find = true; - end - end - if not Find then - table.insert(self.SelectWeapons[InPlayerKey], ItemId); - end - end - else - local Find, FindIndex = false, 0; - for i, v in pairs(self.SelectWeapons[InPlayerKey]) do - if v == ItemId then - Find = true; - FindIndex = i; - end - end - if FindIndex ~= 0 then - table.remove(self.SelectWeapons[InPlayerKey], FindIndex); - end - -- 检查是否为空 - if table.isEmpty(self.SelectWeapons[InPlayerKey]) then - self.SelectWeapons[InPlayerKey] = nil; - end - end - -- 同步 - self:DOREPONCE("SelectWeapons"); -- 这种方式同步数据 - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnSelectWeapons] SelectWeapons ="), self.SelectWeapons) -end - ---- 执行属性同步 -function Mini_Solo:DOREPONCE(Name) - self.Owner:SetGameInfo(Name, self[Name]); -end - -function Mini_Solo:OnRep_SelectWeapons(InOld) - UGCLogSystem.Log("[Mini_Solo:OnRep_SelectWeapons] 执行") - -- 显示自己已经选择了的 - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnRep_SelectWeapons] self.SelectWeapons ="), self.SelectWeapons) - UGCEventSystem.SendEvent(EventTypes.UpdateSelectWeapons, self.SelectWeapons); -end - -Mini_Solo.CurrWeapon = {}; - -function Mini_Solo:SelectCurrWeapon(InPlayerKey, InWeaponId) - -- 移除对应的 - --if self.State ~= MiniGameState.ROUND_GAMING then return; end - UGCLogSystem.LogTree(string.format("[Mini_Solo:SelectCurrWeapon] self.SelectWeapons ="), self.SelectWeapons) - local Index = nil; - if InWeaponId == nil then - Index = self:RandSelectCurrWeapon(InPlayerKey) - else - Index = table.find(self.SelectWeapons[InPlayerKey], InWeaponId) - if Index == nil then - Index = self:RandSelectCurrWeapon(InPlayerKey); - end - end - - if Index ~= nil then - self.CurrWeapon[InPlayerKey] = self.SelectWeapons[InPlayerKey][Index]; - self:DOREPONCE("CurrWeapon"); - else - UGCLogSystem.Log("[Mini_Solo:SelectCurrWeapon] Index 为空,很奇怪,查一下"); - end - UGCLogSystem.Log("[Mini_Solo:SelectCurrWeapon] Index = %d", Index); -end - ---- 随机当前武器 -function Mini_Solo:RandSelectCurrWeapon(InPlayerKey) - UGCLogSystem.Log("[Mini_Solo:RandSelectCurrWeapon] 随机选择索引") - return math.random(table.getCount(self.SelectWeapons[InPlayerKey])) -end - -function Mini_Solo:OnRep_CurrWeapon() - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnRep_CurrWeapon] CurrWeapon ="), self.CurrWeapon); - -- 通知选择了 - UGCEventSystem.SendEvent(EventTypes.UpdateCurrWeapon, self.CurrWeapon); -end - -Mini_Solo.PlayerSelectMaps = {}; - -function Mini_Solo:OnPlayerSelectMaps(PlayerKey, MapName) - if self.State > MiniGameState.MINI_PREPARE then return ; end - self.PlayerSelectMaps[PlayerKey] = MapName; - self:DOREPONCE("PlayerSelectMaps"); -end - ---- 这是被击中之后的表现 -function Mini_Solo:OnPlayerInjury(PlayerKey, CauserKey, DamageData) - if not self:IsFormalMode() then return ; end - local WeaponID = DamageData.WeaponID; -- 需要去除不是的环境 - -- 说明存在 - if CauserKey ~= nil and UE.GetAccountInfo(CauserKey) ~= nil then - self:AddSelectWeaponsArchive(CauserKey, WeaponID, 5, 1); - -- 计算暴击数 - if DamageData.IsHeadShotDamage then - self:AddSelectWeaponsArchive(CauserKey, WeaponID, 6, 1); - end - --- 总伤害 - self:AddSelectWeaponsArchive(CauserKey, WeaponID, 7, DamageData.Damage); - end -end - ---- 对应的是 UE.MakeSelectWeapon ----@param PlayerKey PlayerKey 玩家Key ----@param WeaponID int32 武器ID ----@param MajorIndex int32 主要索引 ----@param AddCount int32 添加数量 -function Mini_Solo:AddSelectWeaponsArchive(PlayerKey, WeaponID, MajorIndex, AddCount) - if ArchiveTable[PlayerKey].SelectWeapons == nil then ArchiveTable[PlayerKey].SelectWeapons = {}; end - if ArchiveTable[PlayerKey].SelectWeapons[WeaponID] == nil then - ArchiveTable[PlayerKey].SelectWeapons[WeaponID] = { - 0, -- 选择的次数 - 0, -- 使用次数 - 0, -- 获胜次数 - 0, -- 射击数 - 0, -- 击中数 - 0, -- 暴击数 - 0, -- 总伤害 - }; - end - -- 二次验证 - ArchiveTable[PlayerKey].SelectWeapons[WeaponID][MajorIndex] = (ArchiveTable[PlayerKey].SelectWeapons[WeaponID][MajorIndex] or 0) + AddCount; -end - -function Mini_Solo:OnRep_PlayerSelectMaps() - if not table.isEmpty(self.PlayerSelectMaps) then - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnRep_PlayerSelectMaps] PlayerSelectMaps ="), self.PlayerSelectMaps); - WidgetManager:GetPanel(WidgetConfig.EUIType.AllWeapon, function(Widget) - Widget:OnPlayerSelectMap(self.PlayerSelectMaps); - end); - end -end - -function Mini_Solo:OnRep_RoundTimes() - UGCLogSystem.Log("[Mini_Solo:OnRep_RoundTimes] 当前是 %s 关卡", tostring(self.RoundTimes)) - UGCEventSystem.SendEvent(EventTypes.UpdateRoundTimes, self.RoundTimes, self.TotalRoundTimes); -end - ---- 设置是否开启禁用功能 -function Mini_Solo:SetEnableDisableType(InPlayerKey, DisableType, IsEnable) - if self.State > MiniGameState.ROUND_PREPARE then return ; end - if self.Disables[InPlayerKey] == nil then self.Disables[InPlayerKey] = {}; end - self.Disables[InPlayerKey][DisableType] = IsEnable; - -- 先不管 - self:DOREPONCE("Disables"); -end - -function Mini_Solo:OnRep_Disables() - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnRep_Disables] self.Disables ="), self.Disables) - UGCEventSystem.SendEvent(EventTypes.PlayerDisable, self.Disables) -end - -Mini_Solo.PlayerSelectModes = {}; - -function Mini_Solo:OnRep_PlayerSelectModes() - UGCLogSystem.LogTree(string.format("[Mini_Solo:OnRep_PlayerSelectModes] self.PlayerSelectModes ="), self.PlayerSelectModes) - UGCEventSystem.SendEvent(EventTypes.UpdateSelectModes, self.PlayerSelectModes); - if table.getCount(self.PlayerSelectModes) == 2 then - if self.PlayerSelectModes[1] == self.PlayerSelectModes[2] then - GlobalModeType = self.PlayerSelectModes[1]; - else - GlobalModeType = GameModeConfig.EGameModeType.DefaultMode; - end - -- 更新一下 - UGCEventSystem.SendEvent(EventTypes.UpdateModeType, GlobalModeType); - end -end - ---- 娱乐模式武器数据 -Mini_Solo.EnterWeaponItem = {}; - ---- 选择模式,一个玩家只能选一次 -function Mini_Solo:SelectMode(InPlayerKey, InModeType) - UGCLogSystem.Log("[Mini_Solo:SelectMode] 执行,PlayerKey = %s,ModeType = %s", tostring(InPlayerKey), tostring(InModeType)); - table.insert(self.PlayerSelectModes, InModeType); - ArchiveTable[InPlayerKey].ModeType = InModeType; - self:DOREPONCE("PlayerSelectModes"); - - -- 检查是否跟玩家数量不一样 - if #self.PlayerSelectModes == table.getCount(UGCGameSystem.GetAllPlayerController(false)) then - if self.PlayerSelectModes[1] == self.PlayerSelectModes[2] and self.PlayerSelectModes[1] ~= GameModeConfig.EGameModeType.DefaultMode then - self.ModeType = self.PlayerSelectModes[1]; - self:DOREPONCE("ModeType"); - self:ResetMiniGameTimes(); - - UGCLogSystem.Log("[Mini_Solo:SelectMode] 执行") - -- 拿到之前的武器,并赋值 - for i, PC in pairs(UGCGameSystem.GetAllPlayerController(false)) do - local PlayerKey = PC.PlayerKey; - self:GetPlayerEnterWeapons(PlayerKey, ArchiveTable[PlayerKey].EnterWeaponIndex); - end - - UGCLogSystem.LogTree(string.format("[Mini_Solo:SelectMode] EnterWeaponItem ="), self.EnterWeaponItem) - - UGCLogSystem.Log("[Mini_Solo:SelectMode] self.SelectMapTime = %s", tostring(self.SelectMapTime)); - if self.CurrTimeCount ~= nil and self.CurrTimeCount > GameStateTimes.GangUp.SelectMapTime then - UGCLogSystem.Log("[Mini_Solo:SelectMode] self.CurrTimeCount = %s", tostring(self.CurrTimeCount), tostring(self.SelectMapTime)); - MiniManager:UpdateInternalCount(GameStateTimes.GangUp.SelectMapTime); - end - end - end -end - -function Mini_Solo:OnRep_ModeType() - self:ResetMiniGameTimes(); - -- 同步一下 - if GlobalModeType == nil then GlobalModeType = self.ModeType; end - UGCEventSystem.SendEvent(EventTypes.UpdateModeType, self.ModeType); -end - ---- 重置时间 -function Mini_Solo:ResetMiniGameTimes() - -- 把时间传递过去 - local Times = GameModeConfig.GameModeInfo[self.ModeType].MiniGameTimes; - if Times then - for Name, Time in pairs(Times) do MiniGameTimes[Name] = Time; end - end -end - -Mini_Solo.PlayerSelectedWeapons = {}; - ----@deprecated -function Mini_Solo:PlayerSelectWeapon(PlayerKey, WeaponID) - -- 给玩家添加上去 - self.CurrWeaponItem[PlayerKey] = WeaponID; - if self.PlayerSelectedWeapons[PlayerKey] == nil then self.PlayerSelectedWeapons[PlayerKey] = {}; end - self.PlayerSelectedWeapons[PlayerKey][WeaponID] = 1; - -- 开始添加这个武器 - self:PlayerAddWeapon(PlayerKey, WeaponID); - self:DOREPONCE("CurrWeaponItem"); - UGCLogSystem.Log("[Mini_Solo:PlayerSelectWeapon] WeaponID = %d", WeaponID); - ArchiveTable[PlayerKey].LastWeapon = WeaponID; -end - ---- 玩家选择多个武器,此处是配置,并不是设置 -function Mini_Solo:PlayerSelectWeapons(PlayerKey, SaveIndex, Weapons) - -- 保存EnterWeapons - if table.isEmpty(ArchiveTable[PlayerKey].EnterWeapons) then ArchiveTable[PlayerKey].EnterWeapons = {}; end - ArchiveTable[PlayerKey].EnterWeapons[SaveIndex] = Weapons; - UGCLogSystem.LogTree(string.format("[Mini_Solo:PlayerSelectWeapons] Weapons ="), Weapons) - self.EnterWeaponItem[PlayerKey] = TableHelper.DeepCopyTable(Weapons); - local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey); - if Pawn and UE.IsValid(Pawn) then - Pawn:UpdateSlotWeapons(Weapons); - local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey); - UnrealNetwork.CallUnrealRPC(PC, Pawn, "UpdateEnterWeapons", SaveIndex, Weapons); - end -end - ---- 选择武器索引 -function Mini_Solo:SelectWeaponIndex(PlayerKey, WeaponIndex) - if self.ModeType == GameModeConfig.EGameModeType.DefaultMode then return ; end - ArchiveTable[PlayerKey].EnterWeaponIndex = WeaponIndex; - local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey); - -- 玩家拾取该武器 - if Pawn then - Pawn:UpdateSlotWeapons(self:GetPlayerEnterWeapons(PlayerKey, WeaponIndex)); - end -end - -Mini_Solo.AlreadyPlayers = {}; - -function Mini_Solo:OnPlayerAlready(PlayerKey) - self.AlreadyPlayers[PlayerKey] = 1; - ArchiveTable[PlayerKey].ModeType = GameModeConfig.EGameModeType.GangUpMode; - self:DOREPONCE("AlreadyPlayers"); - if self.ModeType == GameModeConfig.EGameModeType.DefaultMode then return ; end - local SelectMapTime = GameModeConfig.GameModeInfo[self.ModeType].SelectMapTime; - if SelectMapTime == nil then return ; end - if self.CurrTimeCount <= SelectMapTime then return ; end - if table.getCount(self.AlreadyPlayers) < 2 then return ; end - - MiniManager:UpdateInternalCount(SelectMapTime); -end - -function Mini_Solo:OnRep_AlreadyPlayers() - UGCEventSystem.SendEvent(EventTypes.UpdatePlayerReady, self.AlreadyPlayers); -end - -function Mini_Solo:ShowRankInheritanceUI() - -- 看一下是否可以显示段位页面 - if table.isEmpty(ArchiveTable[LocalPlayerKey]) then return ; end - if ArchiveTable[LocalPlayerKey].IsNewSeason then - -- 读取之前数据 - local Seasons = ArchiveTable[LocalPlayerKey].Seasons - if table.isEmpty(Seasons) then return ; end - UGCLogSystem.LogTree(string.format("[Mini_Solo:ShowRankInheritanceUI] Seasons ="), Seasons) - -- 获取上一赛季 - local LastSeason, LastRankScore = -1, 0; - for i, v in pairs(Seasons) do - if i > LastSeason then - LastSeason = i; - LastRankScore = v[2][1]; - end - end - if LastSeason > -1 then - local HideScore = ArchiveTable[LocalPlayerKey].HideScore; - UGCLogSystem.Log("[Mini_Solo:ShowRankInheritanceUI] LastRankScore = %d, HideScore = %d", LastRankScore, HideScore) - WidgetManager:ShowPanel(WidgetConfig.EUIType.ShowRankInheritance, false, LastSeason, DefaultSettings.CurrentSeason, LastRankScore, DefaultSettings.RankScore, HideScore); - end - end -end - -function Mini_Solo:OpenOldParts(PlayerKey, bOldParts) - if ArchiveTable[PlayerKey] then - ArchiveTable[PlayerKey].bOldParts = bOldParts; - end -end - -return Mini_Solo; diff --git a/SoloKing/Script/Global/Tool/TestTool.lua b/SoloKing/Script/Global/Plugin/Plugins/TestTool.lua similarity index 100% rename from SoloKing/Script/Global/Tool/TestTool.lua rename to SoloKing/Script/Global/Plugin/Plugins/TestTool.lua diff --git a/SoloKing/Script/Global/Tool/ItemTool.lua b/SoloKing/Script/Global/Tool/ItemTool.lua index df86756f..2993e835 100644 --- a/SoloKing/Script/Global/Tool/ItemTool.lua +++ b/SoloKing/Script/Global/Tool/ItemTool.lua @@ -108,10 +108,10 @@ end function ItemTool.AddWeaponItem(InPawn, InWeaponId, InCount, bAppend, FillBulletType) if not UE.IsValid(InPawn) then return end local bHadAdd = false; - local Times = 10; + local Times = 10; repeat bHadAdd = UGCBackPackSystem.AddItem(InPawn, InWeaponId, InCount) - Times = Times - 1; + Times = Times - 1; until bHadAdd or Times <= 0; local Weapon = ItemTool.GetLastWeapon(InPawn, InWeaponId); @@ -125,8 +125,8 @@ function ItemTool.AddWeaponItem(InPawn, InWeaponId, InCount, bAppend, FillBullet end function ItemTool.GetWeaponIdParts(PlayerKey, InWeaponId) - if WeaponSuits[InWeaponId] == nil then return; end - if table.isEmpty(WeaponSuits[InWeaponId][EWeaponPartType.Best]) then return; end + if WeaponSuits[InWeaponId] == nil then return ; end + if table.isEmpty(WeaponSuits[InWeaponId][EWeaponPartType.Best]) then return ; end local Parts = nil; if ArchiveTable[PlayerKey] and not table.isEmpty(ArchiveTable[PlayerKey].Weapons) then Parts = ArchiveTable[PlayerKey].Weapons[InWeaponId]; @@ -149,7 +149,6 @@ end ---@param InPawn UGCPlayerPawn_C ---@return table function ItemTool.GetWeaponPartsDefineIDs(InPawn, Weapon) - local BackComp = UGCBackPackSystem.GetBackpackComponent(InPawn); local InstanceIds = {}; local CustomList = {}; for i = 0, 5 do @@ -166,6 +165,27 @@ function ItemTool.GetWeaponPartsDefineIDs(InPawn, Weapon) return InstanceIds, CustomList; end +---@param Weapon ASTExtraWeapon +function ItemTool.GetWeaponPartDefineIDMap(Weapon) + local List = UGCGunSystem.GetWeaponAllAttachmentIDList(Weapon) + local Map = {}; + for i, v in pairs(List) do Map[v.TypeSpecificID] = v; end + return Map; +end + +---@param Weapon ASTExtraWeapon +function ItemTool.GetWeaponPartSocketMap(Weapon) + local List = UGCGunSystem.GetAvailableWeaponAttachmentSocketTypeList(Weapon); + local Map = {}; + for i, Socket in pairs(List) do + local DefineID = UGCGunSystem.GetWeaponAttachmentIDBySocketType(Weapon, Socket); + if DefineID and DefineID.bValidInstance then + Map[DefineID.TypeSpecificID] = Socket; + end + end + return Map; +end + ---@param Weapon ASTExtraWeapon ---@param InPawn UGCPlayerPawn_C function ItemTool.ClearWeapon(InPawn, Weapon) @@ -605,6 +625,37 @@ function ItemTool.SetWeaponParts(InWeapon, Parts) end end +--- 从背包中寻找对应配件,如果有添加,没有的话就创建 +---@param InWeapon ASTExtraShootWeapon +function ItemTool.ReuseWeaponParts(InWeapon, Parts) + if not ItemTool.IsShootWeapon(InWeapon) then return ; end + if table.isEmpty(Parts) then ItemTool.DisuseAllParts(InWeapon); return; end + local Pawn = InWeapon:GetOwnerPawn(); + + local PartMap = {}; + for i, v in pairs(Parts) do PartMap[v] = 1; end + local AllItems = UGCBackPackSystem.GetAllAttachmentDefineIDInBackpack(Pawn) + + -- 查看当前枪上有哪些 + local HasMap = ItemTool.GetWeaponPartSocketMap(InWeapon); + + local Removes = {}; + for PartID, SocketType in pairs(HasMap) do + if PartMap[PartID] then + PartMap[PartID] = nil; + else + Removes[PartID] = SocketType; + end + end + for i, v in pairs(Removes) do + UGCGunSystem.RemoveGunAttachmentBySocketType(InWeapon, v); + end + + for i, v in pairs(PartMap) do + UGCGunSystem.CreateAndAddGunAttachment(InWeapon, i); + end +end + ---@param InWeapon ASTExtraShootWeapon function ItemTool.GetAllPartTypes(InWeapon) local WeaponID = InWeapon:GetWeaponItemID(); @@ -640,6 +691,13 @@ function ItemTool.RemoveAllParts(InWeapon) end end +--- 将枪上的配件全部放回背包 +---@param InWeapon ASTExtraShootWeapon +function ItemTool.DisuseAllParts(InWeapon) + if not InWeapon:IsShotGun() then return end + UGCGunSystem.DisuseAllWeaponAttachmentsOnServer(InWeapon); +end + ---@return ASTExtraShootWeapon function ItemTool.GetLocalPawnCurrWeapon() local Pawn = UE.GetLocalPawn(); @@ -688,7 +746,7 @@ end ---@param WeaponID int32 function ItemTool.RemoveBullet(Pawn, WeaponID) local AmmoID = WeaponAmmoIdMap[WeaponID] - if AmmoID == nil then return; end + if AmmoID == nil then return ; end local AllData = UGCBackPackSystem.GetAllItemData(Pawn); for i, v in pairs(AllData) do if v.ItemID == AmmoID then @@ -722,12 +780,12 @@ end function ItemTool.GetPlayerEnterWeapons(PlayerKey, Index) if Index == nil then Index = 1; end - local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey); + local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey); local SlotWeapons = nil; if not table.isEmpty(ArchiveTable[PlayerKey].EnterWeapons) then SlotWeapons = ArchiveTable[PlayerKey].EnterWeapons[Index]; end - SlotWeapons = SlotWeapons or WeaponSelectionCombinationConfig.WeaponCombinationList.Weapon[Index]; + SlotWeapons = SlotWeapons or WeaponSelectionCombinationConfig.WeaponCombinationList.Weapon[Index]; local Weapons = {}; for i, v in pairs(SlotWeapons) do Weapons[WeaponSelectionCombinationConfig.ECombinationType[i]] = v;