UGCProjects/SoloKing/Script/Blueprint/UGCPlayerController.lua

471 lines
16 KiB
Lua
Raw Normal View History

2025-01-04 23:00:19 +08:00
---@class UGCPlayerController_C:BP_UGCPlayerController_C
--Edit Below--
require('Script.Global.Global')
---@type UGCPlayerController_C
local UGCPlayerController = {};
--- 默认滑铲
UGCPlayerController.PlayerEnableShovel = false;
--- 默认显示飘字
UGCPlayerController.EnableDamageText = true;
--- 记录一个 WeaponInfo
UGCPlayerController.WeaponInfo = {};
function UGCPlayerController:ReceiveBeginPlay()
self.SuperClass.ReceiveBeginPlay(self);
GlobalInit.InitGlobalVar()
--- 设置一个默认值
self.EnableDamageText = DefaultSettings.EnableDamageText;
if IsClient then
WidgetManager:Init(self);
if not DefaultSettings.EnableAutoPickUp then UITool.HidePickUpPanel(); end
UGCEventSystem.SetTimer(self, function()
WidgetManager:ShowPanel(WidgetConfig.EUIType.Main, false);
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
local MiniState = GameState.MiniInfo.State
UGCLogSystem.Log("[UGCPlayerController:ReceiveBeginPlay] 执行 MiniState = %s", tostring(MiniState));
if MiniState ~= nil and MiniState <= 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);
end
end
else
if MiniState == nil then
UGCLogSystem.Log("[UGCPlayerController:ReceiveBeginPlay] GlobalMiniState 不存在")
else
UGCLogSystem.Log("[UGCPlayerController:ReceiveBeginPlay] State = %s", TableHelper.printEnum(MiniGameState, MiniState));
end
end
end, 1);
end
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
UGCEventSystem.AddListener(EventTypes.ClientAlready, self.OnClientAlready, self);
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
-- 添加玩家死亡复活回调
self.OnCharacterDeadDelegate:Add(self.OnCharacterDeath, self)
self.PlayerControllerRespawnedDelegate:AddInstance(self.OnRespawnPawn, self)
self.OnSpectatorChange:Add(self.OnChangeSpectorActor, self);
UGCLogSystem.Log("[UGCPlayerController:ReceiveBeginPlay] 执行")
end
function UGCPlayerController:GetReplicatedProperties()
return { "PlayerEnableShovel", "Lazy" }
end
function UGCPlayerController:GetAvailableServerRPCs()
return "Test_Func"
, "SetEnableShovel"
, "SetEnableDamageText"
, "ResendArchive"
end
--- 重置游戏
function UGCPlayerController:ResetGame()
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
PlayerState:ResetGame();
end
function UGCPlayerController:OnRespawnPawn()
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey);
table.func(MiniManager, "OnPawnInit", Pawn);
UGCLogSystem.Log("[UGCPlayerController:OnRespawnPawn] 执行")
if IsServer then
Pawn:AddInitItems();
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
-- 检测当前有多少人
local Pawns = UGCGameSystem.GetAllPlayerPawn()
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
--- 所有玩家重置成功
local PlayerCount = table.getCount(Pawns)
if PlayerCount > 1 then
-- 说明现在可以改动玩家了
if self:IsFriendObserver() then
-- 改变观战人数
local OBKeys = {};
for _, PC in pairs(UGCGameSystem.GetAllPlayerController(false)) do
if FriendSystem.IsMyFriend(UE.GetPlayerUID(PC.PlayerKey)) then
table.insert(OBKeys, PC.PlayerKey);
end
end
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
UGCLogSystem.LogTree(string.format("[UGCPlayerController:OnRespawnPawn] OBKeys ="), OBKeys)
if not table.isEmpty(OBKeys) then
UGCGameSystem.ChangeAllowOBPlayerKeys(self, OBKeys);
UGCGameSystem.EnterSpectating(self);
end
end
end
else
2025-01-15 03:21:37 +08:00
-- 在这里修改 这里改了,改成全部都显示这个按键
--if GlobalMiniMode.ModeType ~= GameModeConfig.EGameModeType.DefaultMode then
2025-01-04 23:00:19 +08:00
UGCLogSystem.Log("[UGCPlayerController:OnRespawnPawn] 显示按钮")
WidgetManager:GetPanel(WidgetConfig.EUIType.Main, function(Widget)
table.func(Widget, "ShowCustomSelectWeaponBtn", true);
end)
2025-01-15 03:21:37 +08:00
--end
2025-01-04 23:00:19 +08:00
end
end
-- 该方法是客户端就绪
function UGCPlayerController:OnClientAlready()
local Archive = ArchiveTable[self.PlayerKey];
if not table.isEmpty(Archive) and not table.isEmpty(Archive.Disables) then
self.EnableDamageText = Archive.Disables.DamageText
UGCLogSystem.Log("[UGCPlayerController:OnClientAlready] DamageText = %s", tostring(self.EnableDamageText));
UGCEventSystem.SendEvent(EventTypes.UpdateEnableDamageText, self.EnableDamageText)
end
end
---@param Character UGCPlayerPawn_C
function UGCPlayerController:OnCharacterDeath(Character)
UGCLogSystem.Log("[UGCPlayerController:OnCharacterDeath] 执行")
end
-------------------------------- 观战 --------------------------------
---@param IsEnterSpectate bool
function UGCPlayerController:EnterSpectate(IsEnterSpectate)
if IsServer then
local OBKeys = {};
for _, PC in pairs(UGCGameSystem.GetAllPlayerController(false)) do
if FriendSystem.IsMyFriend(UE.GetPlayerUID(PC.PlayerKey)) then
table.insert(OBKeys, PC.PlayerKey);
end
end
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
if table.isEmpty(OBKeys) then return ; end
UGCGameSystem.ChangeAllowOBPlayerKeys(self, OBKeys);
UGCGameSystem.EnterSpectating(self);
end
end
--- 设置能否移动
function UGCPlayerController:SetCanMove(IsCan)
self:SetCinematicMode(not IsCan, false, false, true, false);
end
--- 设置玩家是否可以滑铲
function UGCPlayerController:SetEnableShovel(IsEnable)
UGCLogSystem.Log("[UGCPlayerController:SetEnableShovel] 执行 IsEnable = %s", tostring(IsEnable));
if self.PlayerEnableShovel == IsEnable then return ; end
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
self.PlayerEnableShovel = IsEnable;
local PS = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
PS:SetEnableShovel(self.PlayerEnableShovel);
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey);
if Pawn and UE.IsValid(Pawn) and Pawn:IsAlive() then
UGCLogSystem.Log("[UGCPlayerController:SetEnableShovel] 是否可以滑铲 %s", tostring(GameState.EnableShovel));
UGCPawnSystem.DisabledPawnState(Pawn, EPawnState.Shoveling, not GameState.EnableShovel);
end
-- 记录一下
DOREPONCE(self, "PlayerEnableShovel");
end
function UGCPlayerController:OnRep_PlayerEnableShovel()
-- 检查一下
if LocalPlayerKey and self.PlayerKey == LocalPlayerKey then
-- 不需要设置,因为就是通过它改变的
UGCEventSystem.SendEvent(EventTypes.ChangeShovel, self.PlayerEnableShovel);
end
end
--- 设置是否开启飘字
function UGCPlayerController:SetEnableDamageText(IsEnable)
if not self:IsPureSpectator() then
if IsServer then
-- 保存一下
if ArchiveTable[self.PlayerKey].Disables == nil then ArchiveTable[self.PlayerKey].Disables = {}; end
ArchiveTable[self.PlayerKey].Disables.DamageText = IsEnable;
else
UnrealNetwork.CallUnrealRPC(self, self, "SetEnableDamageText", IsEnable);
end
self.EnableDamageText = IsEnable;
end
end
function UGCPlayerController:GetEnableDamageText()
local Archive = ArchiveTable[self.PlayerKey];
if not table.isEmpty(Archive) and not table.isEmpty(Archive.Disables) and Archive.Disables.DamageText ~= nil then
self.EnableDamageText = Archive.Disables.DamageText
end
end
--- 处理切换观战对象
function UGCPlayerController:OnChangeSpectorActor()
UGCEventSystem.SendEvent(EventTypes.ChangeSpector, self.IsCurrentSpectatorFreeView, self:GetCurPawn());
end
-------------------------------- 测试 --------------------------------
function UGCPlayerController:Test_Func(InFuncName, ...)
UGCLogSystem.Log("[UGCPlayerController:Test_Func] 执行 %s", InFuncName)
self[InFuncName](self, ...)
end
function UGCPlayerController:Test_PlayerLeave(PlayerKey)
table.func(MiniManager, "Test_PlayerLeave", PlayerKey);
end
--function UGCPlayerController:ReceiveTick(DeltaTime)
-- self.SuperClass.ReceiveTick(self, DeltaTime);
--end
function UGCPlayerController:ReceiveEndPlay()
self:CloseLastGameTimer();
self.SuperClass.ReceiveEndPlay(self);
end
function UGCPlayerController:CloseLastGameTimer()
if self.SendLastGamesTimer then
UGCEventSystem.StopTimer(self.SendLastGamesTimer);
self.SendLastGamesTime = nil;
end
end
---------------------------------- 处理存档 ----------------------------------
---通知重新发送存档
---@param Array int[]
function UGCPlayerController:ResendArchive(Array)
if IsServer then
self.SendListIndex = Array;
self:SendLast10Games(Array);
else
UnrealNetwork.CallUnrealRPC(self, self, "ResendArchive", Array);
end
end
---@type int[]
UGCPlayerController.SendListIndex = nil;
UGCPlayerController.SendLastGamesTimer = nil;
--- 直接调用该函数即可
function UGCPlayerController:SendLast10Games(InList)
local Total = table.getCount(ArchiveTable[self.PlayerKey].Last10Games)
if table.isEmpty(InList) then
InList = {};
for i = 1, Total do table.insert(InList, i); end
end
self.SendListIndex = InList;
UGCLogSystem.LogTree(string.format("[UGCPlayerController:SendLast10Games] SendListIndex ="), self.SendListIndex);
if not table.isEmpty(InList) then
self.SendLastGamesTimer = UGCEventSystem.SetTimerLoop(self, function()
local Index = self.SendListIndex[1];
if Index == nil then return self:CloseLastGameTimer(); end
table.remove(self.SendListIndex, 1)
self:SendArchive(Index);
end, 1);
end
end
--- 发送本局历史战绩
function UGCPlayerController:SendNewArchive(Index, Archive, Friend)
if IsServer then
UnrealNetwork.CallUnrealRPC(self, self, "SendNewArchive", Index, Archive, Friend);
else
UGCLogSystem.Log("[UGCPlayerController:SendNewArchive] 执行 Index = %d", Index);
WidgetManager:GetPanel(WidgetConfig.EUIType.GameRecord, function(Widget)
Widget:AddLastGameItem(Index, Archive, Friend);
Widget:OnAllLastGamesAlready(Index);
end);
end
end
--- 发送存档
---@param Index int 索引,只发送当前的
function UGCPlayerController:SendArchive(Index, Total, Archive, Friend)
if IsServer then
UGCLogSystem.Log("[UGCPlayerController:SendArchive] 执行 Index = %d", Index);
if table.isEmpty(ArchiveTable[self.PlayerKey]) then return end
if table.isEmpty(ArchiveTable[self.PlayerKey].Last10Games) then return ; end
local LastGame = ArchiveTable[self.PlayerKey].Last10Games[Index]
if table.isEmpty(LastGame) then return ; end
Total = table.getCount(ArchiveTable[self.PlayerKey].Last10Games);
local UID = nil
if LastGame[9] then
UID = LastGame[2]
else
UID = LastGame[2][1];
end
UnrealNetwork.CallUnrealRPC(self, self, "SendArchive", Index, Total,
ArchiveTable[self.PlayerKey].Last10Games[Index],
(UID == nil and nil or ArchiveTable[self.PlayerKey].Friends[UID])
);
else
if ArchiveTable[self.PlayerKey] == nil then ArchiveTable[self.PlayerKey] = {}; end
if ArchiveTable[self.PlayerKey].Last10Games == nil then ArchiveTable[self.PlayerKey].Last10Games = {}; end
ArchiveTable[self.PlayerKey].Last10Games[Index] = Archive;
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
WidgetManager:GetPanel(WidgetConfig.EUIType.GameRecord, function(Widget)
Widget:AddLastGameItem(Index, Archive, Friend);
end)
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
self:CloseLastGameTimer();
UGCEventSystem.SetTimer(self, function()
-- 验证是否完全,不完全发送数据
local Success, List = self:CheckArchiveDataComplete(Total);
if not Success then self:ResendArchive(List); end
end, 3);
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
-- 判断是否完整
if self:CheckArchiveDataComplete(Total) then
-- 数据完整
self:CloseLastGameTimer();
UGCEventSystem.SendEvent(EventTypes.AllLastGamesAlready, Total)
end
end
end
--- 检查Last10Games存档数据是否完整
function UGCPlayerController:CheckArchiveDataComplete(Total)
if table.isEmpty(ArchiveTable[self.PlayerKey]) then return false; end
if table.isEmpty(ArchiveTable[self.PlayerKey].Last10Games) then return false; end
local Count = table.getCount(ArchiveTable[self.PlayerKey].Last10Games);
if Total <= Count then return true; end
local ResendList = {};
for i = 1, Total do
if ArchiveTable[self.PlayerKey].Last10Games[i] == nil then table.insert(ResendList, i); end
end
return false, ResendList;
end
UGCPlayerController.SelectWeapons = {};
-- 一次发送 RPC 的武器数量
UGCPlayerController.OneSendWeaponCount = 10;
function UGCPlayerController:SendSelectWeapons()
if table.isEmpty(ArchiveTable[self.PlayerKey]) then return end
if table.isEmpty(ArchiveTable[self.PlayerKey].SelectWeapons) then return end
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
UGCEventSystem.SetTimer(self, function()
self.SendSelectWeaponsTimer = UGCEventSystem.SetTimerLoop(self, function()
self:SendWeapons();
end, 1);
end, 0.3);
end
--- 发送 SelectWeapons
function UGCPlayerController:SendWeapons(Total, InList)
if IsServer then
if table.isEmpty(self.SelectWeapons) then
self.SelectWeapons = TableHelper.DeepCopyTable(ArchiveTable[self.PlayerKey].SelectWeapons);
end
if table.isEmpty(InList) then
InList = {};
local ZheList = {};
if table.getCount(self.SelectWeapons) <= self.OneSendWeaponCount then
InList = self.SelectWeapons;
else
local Num = 1;
local List = {};
for i, v in pairs(self.SelectWeapons) do
InList[i] = v;
Num = Num + 1;
if Num > self.OneSendWeaponCount then break ; end
end
2025-01-14 15:37:16 +08:00
2025-01-04 23:00:19 +08:00
for WeaponId, v in pairs(InList) do
self.SelectWeapons[WeaponId] = nil;
end
end
if table.isEmpty(self.SelectWeapons) then
if self.SendSelectWeaponsTimer then
UGCEventSystem.StopTimer(self.SendSelectWeaponsTimer)
self.SendSelectWeaponsTimer = nil;
end
end
end
if table.isEmpty(InList) then return ; end
if Total == nil then
UnrealNetwork.CallUnrealRPC(self, self, "SendWeapons", table.getCount(ArchiveTable[self.PlayerKey].SelectWeapons), InList);
else
UnrealNetwork.CallUnrealRPC(self, self, "SendWeapons", Total, InList);
end
else
-- 组装即可
if table.isEmpty(InList) then return ; end
if ArchiveTable[self.PlayerKey] == nil then ArchiveTable[self.PlayerKey] = {}; end
if table.isEmpty(ArchiveTable[self.PlayerKey].SelectWeapons) then ArchiveTable[self.PlayerKey].SelectWeapons = {}; end
for Weapon, List in pairs(InList) do
ArchiveTable[self.PlayerKey].SelectWeapons[Weapon] = List;
end
if Total == table.getCount(ArchiveTable[self.PlayerKey].SelectWeapons) or Total == -1 then
UGCLogSystem.Log("[UGCPlayerController:SendWeapons] 执行")
UGCEventSystem.SendEvent(EventTypes.AllSelectWeaponsAlready, ArchiveTable[self.PlayerKey].SelectWeapons);
end
end
end
2025-01-14 15:37:16 +08:00
--- 一次发送武器配件数量的rpc有多少个
UGCPlayerController.OneSendWeaponPartsCount = 20;
UGCPlayerController.SendPartsTimer = nil;
--- 正在发送的 IDs
UGCPlayerController.InSendWeaponIds = {};
-- 发送武器配件信息
function UGCPlayerController:SendWeaponParts(InList)
if table.isEmpty(ArchiveTable[self.PlayerKey]) then return; end
local Weapons = ArchiveTable[self.PlayerKey].Weapons;
if table.isEmpty(Weapons) then return; end
if table.isEmpty(self.InSendWeaponIds) then self.InSendWeaponIds = {}; end
if table.isEmpty(InList) then
for WeaponID, Parts in pairs(Weapons) do
table.insert(self.InSendWeaponIds, WeaponID);
end
else
for i, v in pairs(InList) do
if i > 10000 then
table.insert(self.InSendWeaponIds, i);
else
table.insert(self.InSendWeaponIds, v);
end
end
end
self.SendPartsTimer = UGCEventSystem.SetTimerLoop(self, function()
self:SendPartsRPC();
end, 0.5)
end
UGCPlayerController.SendPartsTimer = nil;
function UGCPlayerController:SendPartsRPC(InTotal, InList)
if IsServer then
-- 开始发送
local Weapons = ArchiveTable[self.PlayerKey].Weapons;
local Count = table.getCount(self.InSendWeaponIds);
local SendTable = {};
if Count <= self.OneSendWeaponPartsCount then
for i, WeaponID in pairs(self.InSendWeaponIds) do
SendTable[WeaponID] = Weapons[WeaponID] or {};
end
self.InSendWeaponIds = {};
UGCEventSystem.StopTimer(self.SendPartsTimer);
else
for i = 1, self.OneSendWeaponPartsCount do
local WeaponID = self.InSendWeaponIds[1];
SendTable[WeaponID] = Weapons[WeaponID] or {};
table.remove(self.InSendWeaponIds, 1);
end
end
UnrealNetwork.CallUnrealRPC(self, self, "SendPartsRPC", InTotal or table.getCount(SendTable), SendTable);
else
if table.isEmpty(ArchiveTable[self.PlayerKey]) then ArchiveTable[self.PlayerKey] = {}; end
if table.isEmpty(ArchiveTable[self.PlayerKey].Weapons) then ArchiveTable[self.PlayerKey].Weapons = {}; end
for WeaponID, Parts in pairs(InList) do
ArchiveTable[self.PlayerKey].Weapons[WeaponID] = Parts;
end
-- 查看是否完全了
2025-01-16 13:35:17 +08:00
if table.getCount(ArchiveTable[self.PlayerKey].Weapons) == InTotal or InTotal == -1 then
-- 更新存档武器
2025-01-14 15:37:16 +08:00
end
end
end
2025-01-04 23:00:19 +08:00
return UGCPlayerController;