2025-01-08 22:46:12 +08:00

849 lines
30 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()
if self.CurrMiniMode.bGameEnd == false and self.CurrMiniMode.bRoundEnd == false then
table.func(self.CurrMiniMode, "OnTimeExhausted", self.State)
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
--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 DamagedActor UGCPlayerPawn_C
---@param Damage float
---@param DamageType EDamageType
---@param EventInstigator UGCPlayerController_C
--function MiniManager:OnPlayerDamage(DamagedActor, Damage, DamageType, EventInstigator)
-- UGCLogSystem.Log("[MiniManager:OnPlayerDamage] DamagedActor = %s, Damage = %f", UE.GetName(DamagedActor), Damage);
-- local CalDamage = table.func(self.CurrMiniMode, 'OnPlayerTakeDamage', DamagedActor, Damage, DamageType, EventInstigator)
-- if CalDamage == nil then return Damage; end
-- return CalDamage;
--end
--- S & C 接受到伤害函数
--function MiniManager:BPReceiveDamage(DamagedActor, Damage, DamageType, InstigatedBy, DamageCauser)
-- if IsServer then
-- table.func(self.CurrMiniMode, 'BPReceiveDamage', DamagedActor, Damage, DamageType, InstigatedBy, DamageCauser)
-- end
--end
--- 服务器/客户端收到伤害数据
---@param DamagedPawn UGCPlayerPawn_C
---@param Damage float
---@param DamageType UDamageType
---@param InstigatedBy UGCPlayerController_C
---@param DamageCauser AActor
--function MiniManager:ReceiveDamage(DamagedPawn, Damage, DamageType, InstigatedBy, DamageCauser)
-- UGCLogSystem.Log("[MiniManager:ReceiveDamage] 收到伤害")
-- table.func(self.CurrMiniMode, "ReceiveDamage", DamagedPawn, Damage, DamageType, InstigatedBy, DamageCauser);
--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