821 lines
28 KiB
Lua
Raw Normal View History

2025-01-04 23:00:19 +08:00
MiniManager = {};
---@private string 这是玩家选择的地图,按从前往后开始游玩
MiniManager.ScriptPath = "Script.Global.Mini.Script.Mini_";
---@type table<int32, FMiniGameMapIndex> 当前所有玩家选择的地图
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<PlayerKey, MiniGamePlayerDataItem> 玩家数据
MiniManager.PlayerData = {};
---@type table<int32, any> 小游戏需要同步的数据,会自动执行 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()
2025-02-04 17:59:01 +08:00
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
2025-01-04 23:00:19 +08:00
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<TeamId, table<int32, APlayerStart>>
---@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
2025-01-08 22:46:12 +08:00
--UGCLogSystem.LogTree(string.format("[MiniManager:OnPawnInit] GameConfig ="), MiniGameConfig);
2025-01-04 23:00:19 +08:00
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