584 lines
24 KiB
Lua
Raw Permalink Normal View History

2025-01-18 21:26:02 +08:00
require("Script.Global.BuffSystem.Config.BuffActionConfig")
require("Script.Global.BuffSystem.Config.BuffAssetConfig")
-- 其中BuffCauser, CauserActor, EndTime不进行同步仅服务器拥有
-- BuffInst = {BuffAssetType, OwnerPawn, BuffCauser, CauserActor, EndTime, BuffActions}
BuffManager = BuffManager or {
-- 可配置参数 ----------------------------------------------------
-- Tick的帧数
TickFPS = 24;
-- 可配置参数 End ------------------------------------------------
-- 已注册的GameState
RegisteredGameState = nil;
-- 已Require的 BuffAsset
BuffAssetList = {};
-- 正在使用中的Buff实例 [BuffID] = BuffInst (类型为table参考上述对BuffInst的描述)
BuffInstList = {};
-- 玩家拥有的Buff 这里由于用于同步因此Val里面的信息为列表而非字典 [Pawn] = {[BuffID] = BuffAssetType}, ...}
AllPlayerOwnedBuffs = {};
-- 客户端上一次同步AllPlayerOwnedBuffs的table [Pawn] = {[BuffID] = BuffAssetType}, ...}
ClientAllPlayerOwnedBuffs = {};
-- 这个函数用于衔接服务器和客户端的AllPlayerOwnedBuffs同步因为Pawn作为Key值不能进行OnRep同步 {{Pawn, {[BuffID] = BuffAssetType, ...}}, ...}
OwnedBuffInfo = {};
-- Buff起始时间和结束时间 [BuffID] = {StartTime, EndTime} 这里是列表而不是字典
BuffTimeInfo = {};
-- 那些自动移除的Buff用于有时间限制的Buff
AutoRemoveBuffList = {};
-- 已绑定死亡清除函数的玩家 {[Pawn] = 1}
BoundOnEndPlayDelegatePlayers = {};
}
--- 这里统一一下获取时间的函数
function BuffManager.GetGameTime()
if BuffManager.RegisteredGameState then
return KismetSystemLibrary.GetGameTimeInSeconds(BuffManager.RegisteredGameState)
else
return 0.
end
end
-- ReplicatedProperties ----------------------------------------------------------------------------------------
-- 需要GameState同步的变量
BuffManager.ReplicatedProperties = {
"OwnedBuffInfo"
}
-- 需要GameState同步的函数
BuffManager.RPCFunc = {
"DoBuffActionFunction"
}
-- 需要在GameState中辅助同步的变量,用逗号作为间隔将其加入UGCGameState:GetReplicatedProperties()的末尾
function BuffManager.GetReplicatedProperties()
return table.unpack(BuffManager.ReplicatedProperties)
end
-- AllPlayerOwnedBuffs
function BuffManager.DOREPONCE_OwnedBuffInfo()
BuffManager.OwnedBuffInfo = {}
-- 分解AllPlayerOwnedBuffs
for Pawn, BuffInfo in pairs(BuffManager.AllPlayerOwnedBuffs) do
BuffManager.OwnedBuffInfo[#BuffManager.OwnedBuffInfo + 1] = {Pawn, BuffInfo}
end
BuffManager.RegisteredGameState.OwnedBuffInfo = BuffManager.OwnedBuffInfo
UGCLogSystem.LogTree("[BuffManager_DOREPONCE_OwnedBuffInfo] Finish", BuffManager.OwnedBuffInfo)
end
function BuffManager.OnRep_OwnedBuffInfo()
BuffManager.OwnedBuffInfo = BuffManager.RegisteredGameState.OwnedBuffInfo
UGCLogSystem.LogTree("[BuffManager_OnRep_OwnedBuffInfo] OwnedBuffInfo:", BuffManager.OwnedBuffInfo)
BuffManager.AllPlayerOwnedBuffs = {}
-- 重构AllPlayerOwnedBuffs
for i, v in pairs(BuffManager.OwnedBuffInfo) do
if v[1] and v[2] then
BuffManager.AllPlayerOwnedBuffs[v[1]] = v[2]
end
end
-- 客户端校验玩家拥有的Buff并进行创建和删除操作
BuffManager.ClientUpdateAllPlayerOwnedBuffs()
end
-- ReplicatedProperties End ------------------------------------------------------------------------------------
-- Register ----------------------------------------------------------------------------------------------------
--- 初始化注册 该函数需要在GameState的服务器和客户端中同时调用
---@param InGameState UGCGameState_C GameState作为辅助同步的Actor
function BuffManager.InitRegister(InGameState)
BuffManager.RegisteredGameState = InGameState
-- 初始化一下Tick的时间
BuffManager.LastTickTime = BuffManager.GetGameTime()
-- 启用Tick
BuffManager.TickHandle = UGCEventSystem.SetTimerLoop(BuffManager.RegisteredGameState, BuffManager.Tick, 1./BuffManager.TickFPS)
-- 注册一下RPC函数
BuffManager.RegisterRPCFunc(InGameState)
if UGCGameSystem.IsServer() then
-- 注册参数
BuffManager.RegisterParam(InGameState)
-- 校验Pawn的有效性不为当前游玩的PlayerPawn则移除其所有Buff
-- BuffManager.CheckPawnIsValidHandle = UGCEventSystem.SetTimerLoop(BuffManager.RegisteredGameState, BuffManager.CheckPawnIsValid, 1)
else
-- 注册OnRep函数
BuffManager.RegisterClientOnRepFunc(InGameState)
-- 每秒校验一下同步的Buff
BuffManager.UpdateAllPlayerOwnedBuffsHandle = UGCEventSystem.SetTimerLoop(BuffManager.RegisteredGameState, BuffManager.ClientUpdateAllPlayerOwnedBuffs, 1)
end
end
-- 注册RPC函数
function BuffManager.RegisterRPCFunc(InGameState)
for i, FuncName in pairs(BuffManager.RPCFunc) do
InGameState[FuncName] = function(GameState, ...)
BuffManager[FuncName](...)
end
end
end
-- 注册参数
function BuffManager.RegisterParam(InGameState)
UGCLogSystem.Log("[BuffManager_RegisterParam]")
for i, PropertyName in pairs(BuffManager.ReplicatedProperties) do
-- 这里要保证两个同名
if BuffManager[PropertyName] then
InGameState[PropertyName] = BuffManager[PropertyName]
UGCLogSystem.Log("[BuffManager_RegisterParam] PropertyName:%s", tostring(PropertyName))
end
end
end
-- 注册客户端OnRep函数
function BuffManager.RegisterClientOnRepFunc(InGameState)
UGCLogSystem.Log("[BuffManager_RegisterClientOnRepFunc]")
for i, PropertyName in pairs(BuffManager.ReplicatedProperties) do
local OnRepFuncName = "OnRep_" .. PropertyName
if BuffManager[OnRepFuncName] then
InGameState[OnRepFuncName] = function(InGameState)
UGCLogSystem.Log("[BuffManager_RegisterClientOnRepFunc] Exe")
BuffManager[OnRepFuncName]()
end
BuffManager[OnRepFuncName]()
UGCLogSystem.Log("[BuffManager_RegisterClientOnRepFunc] OnRepFuncName:%s", tostring(OnRepFuncName))
end
end
end
-- Register End ------------------------------------------------------------------------------------------------
--- 获取单个Action实例该实例主要用于拷贝和实例的RPC
function BuffManager.GetSimpleAction(InActionType)
local SimpleAction = BuffManager.SimpleAction[InActionType]
if SimpleAction == nil then
local BuffFileName = BuffActionConfig.ActionFileName[InActionType]
-- UGCLogSystem.Log("[BuffManager_GetCopyAction] BuffFileName:%s", tostring(BuffFileName))
if BuffFileName then
SimpleAction = require(BuffActionConfig.ActionRootPath .. "." .. BuffFileName)
BuffManager.SimpleAction[InActionType] = SimpleAction
else
return nil
end
end
return SimpleAction
end
--- 作为BuffAction拷贝临时模板列表
BuffManager.SimpleAction = {}
--- 获取拷贝的BuffAction
---@param InActionType BuffActionConfig.EActionType
---@param CopyAction table 拷贝出的Action
function BuffManager.GetCopyAction(InActionType)
-- UGCLogSystem.Log("[BuffManager_GetCopyAction] InActionType:%s", tostring(InActionType))
local SimpleAction = BuffManager.GetSimpleAction(InActionType)
-- UGCLogSystem.Log("[BuffManager_GetCopyAction] Finish")
return table.NewLuaObj(SimpleAction)
end
function BuffManager.GetBuffAssetInfo(InBuffAssetType)
if BuffManager.BuffAssetList[InBuffAssetType] == nil then
BuffManager.BuffAssetList[InBuffAssetType] = require(BuffAssetConfig.AssetRootPath .. "." .. BuffAssetConfig.BuffFileName[InBuffAssetType])
end
return BuffManager.BuffAssetList[InBuffAssetType]
end
--- 获取一个新的BuffID
function BuffManager.GetNewBuffID()
if BuffManager.NowBuffID == nil then
BuffManager.NowBuffID = 1;
else
BuffManager.NowBuffID = 1 + BuffManager.NowBuffID;
end
return BuffManager.NowBuffID
end
--- 由于需要做同步处理,因此该变量在服务器和客户端需要采用不同的变量
function BuffManager.GetAllPlayerOwnedBuffs()
if UGCGameSystem.IsServer() then
return BuffManager.AllPlayerOwnedBuffs
else
return BuffManager.ClientAllPlayerOwnedBuffs
end
end
--- 获取Buff的拥有者
---@param InBuffID uint
function BuffManager.GetBuffOwner(InBuffID)
-- 服务器和客户端需要两套进行
local TargetAllPlayerOwnedBuffs = BuffManager.GetAllPlayerOwnedBuffs()
for Pawn, PlayerOwnedBuff in pairs(TargetAllPlayerOwnedBuffs) do
for BuffID, BuffActionType in pairs(PlayerOwnedBuff) do
if BuffID == InBuffID then
return Pawn
end
end
end
return -1
end
--- 获取Buff的结束时间
---@param InBuffID uint
function BuffManager.GetBuffEndTime(InBuffID)
local BuffInst = BuffManager.BuffInstList[InBuffID]
if BuffInst then
return BuffInst.EndTime
end
return -1
end
--- 判断BuffAsset是否一直存在
function BuffManager.BuffIsAlwaysExists(InBuffAssetType)
local BuffAssetInfo = BuffManager.GetBuffAssetInfo(InBuffAssetType)
if BuffAssetInfo then
return BuffAssetInfo.IsAlwaysExists
end
return false
end
--- 判断玩家是否拥有这个Buff
function BuffManager.PlayerHasBuff(InPawn, InBuffAssetType)
local PlayerOwnedBuff = BuffManager.GetAllPlayerOwnedBuffs()[InPawn]
if PlayerOwnedBuff then
for BuffID, BuffAssetType in pairs(PlayerOwnedBuff) do
if BuffAssetType == InBuffAssetType then
return true
end
end
end
return false
end
--- 获取玩家拥有的BuffAsset所有的BuffID
function BuffManager.GetPlayerOwnedBuffIDFromBuffAssetType(InPawn, InBuffAssetType)
local Res = {}
local PlayerOwnedBuff = BuffManager.GetAllPlayerOwnedBuffs()[InPawn]
if PlayerOwnedBuff then
for BuffID, BuffAssetType in pairs(PlayerOwnedBuff) do
if BuffAssetType == InBuffAssetType then
Res[#Res + 1] = BuffID
end
end
end
return Res
end
--- 通过BuffID获取BuffInst信息
function BuffManager.GetBuffInstInfoFromBuffID(InBuffID)
return BuffManager.BuffInstList[InBuffID]
end
--- 调用BuffInst里所有BuffAction的函数
function BuffManager.ExeBuffActionsFuncFromBuffInst(InBuffInst, FuncName, ...)
if InBuffInst then
for i, ActionInst in pairs(InBuffInst.BuffActions) do
ActionInst[FuncName](ActionInst, ...)
end
end
end
--- Server
--- 给玩家加入一个Buff添加有很多种情况不一定是创建新的Buff
---@param BuffCauser AController* @施加Buff的玩家或AI。
---@param CauserActor AActor* @施加Buff的Actor比如说PlayerPawn、燃烧瓶Actor等等
---@return BuffID 如果失败则返回-1 这里的BuffID可能是之前已创建的因为有些Buff为刷新时间的Buff
function BuffManager.PlayerAddBuff(InPawn, InBuffAssetType, BuffCauser, CauserActor)
UGCLogSystem.Log("[BuffManager_PlayerAddBuff] InBuffAssetType:%s", tostring(InBuffAssetType))
if UE.IsValid(InPawn) then
-- 获取Buff资产的信息该参数不可修改
local ConstBuffAsset = BuffManager.GetBuffAssetInfo(InBuffAssetType)
if ConstBuffAsset then
-- 获取Buff叠加类型 多次获得该Buff时所需要做的处理(延长时间或者叠加)
local BuffRepeatedType = ConstBuffAsset.BuffRepeatedType
-- 玩家拥有这个Buff的所有的BuffID
local OwnedThisBuffIDs = BuffManager.GetPlayerOwnedBuffIDFromBuffAssetType(InPawn, InBuffAssetType)
-- 玩家是否拥有这个Buff
local PlayerHaveThisBuff = (#OwnedThisBuffIDs > 0)
-- 获取Buff层数
local BuffLayer = #OwnedThisBuffIDs
-- 通过叠加模式进行Switch分别处理
if BuffRepeatedType == BuffAssetConfig.EBuffRepeatedType.TimeExpand then
--- Buff是时间刷新类型的Buff进行的处理
-- 判断玩家是否已有这个Buff
if PlayerHaveThisBuff then
--- 有这个Buff则调用Action刷新函数
-- 获取唯一的BuffID
local OnceBuffID = OwnedThisBuffIDs[1]
-- 获取已创建的Buff的实例
local BuffInst = BuffManager.GetBuffInstInfoFromBuffID(OnceBuffID)
-- 判断Buff是否为永久存在的
if not BuffManager.BuffIsAlwaysExists(InBuffAssetType)then
--- 该Buff不是永久存在的则需要刷新Buff的持续时间
BuffManager.AddBuffValidityTime(OnceBuffID, ConstBuffAsset.ValidityTime)
end
-- 调用一下刷新函数
BuffManager.ExeBuffActionsFuncFromBuffInst(BuffInst, "LuaResetAction")
-- 若玩家已拥有这个永久存在的Buff且不为叠加模式的Buff则直接返回对应的ID
return OnceBuffID
else
--- 没有这个Buff则创建一个并加入进去
-- New一个BuffID
local BuffID = BuffManager.GetNewBuffID()
-- 创建一个Buff给玩家
BuffManager.CreateBuffToPawn(BuffID, InPawn, InBuffAssetType, BuffCauser, CauserActor)
return BuffID
end
elseif BuffRepeatedType == BuffAssetConfig.EBuffRepeatedType.Superposition then
--- Buff是可重叠类型的Buff进行的处理
-- 判断是否超出层数
if ConstBuffAsset.LayerMax > BuffLayer then
-- New一个BuffID
local BuffID = BuffManager.GetNewBuffID()
UGCLogSystem.Log("[BuffManager_PlayerAddBuff] BuffID:%s", tostring(BuffID))
-- 创建一个Buff给玩家
BuffManager.CreateBuffToPawn(BuffID, InPawn, InBuffAssetType, BuffCauser, CauserActor)
return BuffID
end
end
end
end
return -1
end
--- 隔帧同步OwnedBuffInfo
function BuffManager.IntervalFrameSyncOwnedBuffInfo()
-- 这里是为了防止一帧中刷新多次参数导致复杂度变为n^2所做出的隔帧同步的处理
if BuffManager.SyncOwnedBuffInfoHandle == nil then
BuffManager.SyncOwnedBuffInfoHandle = UGCEventSystem.SetTimer(
UGCGameSystem.GameState,
function()
BuffManager.DOREPONCE_OwnedBuffInfo()
BuffManager.SyncOwnedBuffInfoHandle = nil
end,
0.01
)
end
end
--- 给玩家创建一个Buff无需校验Pawn之类传入参数在调用前需要验证好这些参数
---@return BuffID
function BuffManager.CreateBuffToPawn(InBuffID, InPawn, InBuffAssetType, InBuffCauser, InCauserActor)
UGCLogSystem.Log("[BuffManager_CreateBuffToPawn]")
local BuffActions = {}
local ConstInBuffAsset = BuffManager.GetBuffAssetInfo(InBuffAssetType)
for i, ActionInfo in pairs(ConstInBuffAsset.Actions) do
local ActionType = ActionInfo.ActionType
local Params = ActionInfo.Params
-- New一个BuffAction
local NewAction = BuffManager.GetCopyAction(ActionType)
-- 调用BuffAction的初始化函数
NewAction:InitBuffAction(InBuffID, InPawn, Params)
-- getmetatable(NewAction):InitBuffAction(InBuffID, InPawn, Params)
-- 调用LuaDoAction函数
NewAction:LuaDoAction()
-- 加入列表
BuffActions[ActionType] = NewAction
end
-- 获取Buff结束的GameTimeClient不对该时间进行判断仅靠服务器的同步进行关闭等操作
local EndTime = ConstInBuffAsset.IsAlwaysExists and -1 or BuffManager.GetGameTime() + ConstInBuffAsset.ValidityTime
-- 加入InstList
BuffManager.BuffInstList[InBuffID] = {BuffAssetType = InBuffAssetType, OwnerPawn = InPawn, BuffCauser = InBuffCauser, CauserActor = InCauserActor, EndTime = EndTime, BuffActions = BuffActions}
-- 设置玩家拥有的Buff
if BuffManager.GetAllPlayerOwnedBuffs()[InPawn] == nil then
BuffManager.GetAllPlayerOwnedBuffs()[InPawn] = {}
end
BuffManager.GetAllPlayerOwnedBuffs()[InPawn][InBuffID] = InBuffAssetType
if UGCGameSystem.IsServer() then
-- 隔帧同步玩家拥有的Buff
BuffManager.IntervalFrameSyncOwnedBuffInfo()
-- 玩家绑定Actor结束函数
BuffManager.PlayerBindOnEndPlayDelegate(InPawn)
end
-- Test
UGCLogSystem.LogTree("[BuffManager_CreateBuffToPawn] AllPlayerOwnedBuffs:", BuffManager.GetAllPlayerOwnedBuffs())
end
--- 增加Buff持续时间 此处无需验证BuffID
function BuffManager.AddBuffValidityTime(InBuffID, InAddTime)
UGCLogSystem.Log("[BuffManager_AddBuffValidityTime]")
---@param BuffInst table {BuffAssetType, OwnerPawn, BuffCauser, CauserActor, EndTime, BuffActions}
local BuffInst = BuffManager.BuffInstList[InBuffID]
local BuffAssetType = BuffInst.BuffAssetType
local ConstBuffAssetInfo = BuffManager.GetBuffAssetInfo(BuffAssetType)
local BuffEndTime = BuffManager.BuffInstList[InBuffID].EndTime
-- 限制Buff增加的时间到最大时间
local AddTime = math.clamp(BuffManager.GetGameTime() - BuffEndTime + InAddTime, 0, ConstBuffAssetInfo.MaxValidityTime)
UGCLogSystem.Log("[BuffManager_AddBuffValidityTime] InBuffID:%s, BuffEndTime:%s", tostring(InBuffID), tostring(BuffEndTime))
BuffManager.BuffInstList[InBuffID].EndTime = BuffManager.BuffInstList[InBuffID].EndTime + AddTime
UGCLogSystem.Log("[BuffManager_AddBuffValidityTime] Finish BuffEndTime:%s", tostring(BuffManager.BuffInstList[InBuffID].EndTime))
-- 刷新所需同步的起始时间和结束时间
end
--- 移除一个Buff
function BuffManager.RemoveBuffFromBuffID(InBuffID)
UGCLogSystem.Log("[BuffManager_RemoveBuffFromBuffID] InBuffID:%s", tostring(InBuffID))
-- BuffInst = {BuffAssetType, OwnerPawn, BuffCauser, CauserActor, EndTime, BuffActions}
local BuffInst = BuffManager.BuffInstList[InBuffID]
if BuffInst then
-- 调用所有Action的移除函数
BuffManager.ExeBuffActionsFuncFromBuffInst(BuffInst, "LuaUndoAction")
-- 清除BuffInst
BuffManager.BuffInstList[InBuffID] = nil
-- 获取该Buff的拥有者
local OwnerPlayer = BuffManager.GetBuffOwner(InBuffID)
-- 清除该玩家对应的BuffID
BuffManager.GetAllPlayerOwnedBuffs()[OwnerPlayer][InBuffID] = nil
if UGCGameSystem.IsServer() then
-- 隔帧同步OwnedBuffInfo
BuffManager.IntervalFrameSyncOwnedBuffInfo()
end
end
end
--- 移除玩家的某个Buff
---@param Layer 移除的层数
function BuffManager.PlayerRemoveBuffFromBuffAssetType(InPawn, InBuffAssetType, Layer)
UGCLogSystem.Log("[BuffManager_PlayerRemoveBuffFromBuffAssetType]")
if BuffManager.GetAllPlayerOwnedBuffs()[InPawn] and Layer > 0 then
for BuffID, BuffAssetType in pairs(BuffManager.GetAllPlayerOwnedBuffs()[InPawn]) do
if InBuffAssetType == BuffAssetType then
BuffManager.RemoveBuffFromBuffID(BuffID)
Layer = Layer - 1
if Layer <= 0 then
break
end
end
end
end
end
-- 清除玩家所有的Buff一般用于玩家死亡
function BuffManager.ClearPlayerBuff(InPawn)
UGCLogSystem.Log("[BuffManager_ClearPlayerBuff]")
if BuffManager.GetAllPlayerOwnedBuffs()[InPawn] then
for BuffID, BuffAssetType in pairs(BuffManager.GetAllPlayerOwnedBuffs()[InPawn]) do
BuffManager.RemoveBuffFromBuffID(BuffID)
end
end
BuffManager.GetAllPlayerOwnedBuffs()[InPawn] = nil
end
--- 玩家绑定死亡函数
function BuffManager.PlayerBindOnEndPlayDelegate(InPawn)
if BuffManager.BoundOnEndPlayDelegatePlayers[InPawn] == nil then
InPawn.OnEndPlay:Add(BuffManager.PlayerEndPlay, InPawn)
InPawn.OnDeath:Add(BuffManager.PlayerDeath, InPawn)
BuffManager.BoundOnEndPlayDelegatePlayers[InPawn] = 1
end
end
--- 玩家死亡函数 进行清除操作
---@param DeadCharacter:ASTExtraCharacter
function BuffManager.PlayerEndPlay(InPawn)
UGCLogSystem.Log("[BuffManager_PlayerEndPlay]")
-- 移除玩家已绑定死亡函数
BuffManager.BoundOnEndPlayDelegatePlayers[InPawn] = nil
-- 清除玩家的Buff
BuffManager.ClearPlayerBuff(InPawn)
end
function BuffManager.Tick()
-- 获取DeltaSeconds
local NowTime = BuffManager.GetGameTime()
local DeltaSeconds = NowTime - BuffManager.LastTickTime
-- 判断Buff时间是否到了该移除Buff的时候
local AllBuffID = table.getKeys(BuffManager.BuffInstList)
-- UGCLogSystem.LogTree("[BuffManager_Tick] AllBuffID:", AllBuffID)
for _, BuffID in pairs(AllBuffID) do
local EndTime = BuffManager.GetBuffEndTime(BuffID)
-- EndTime小于0则代表无限时长的Buff
if EndTime > 0 and EndTime < NowTime then
-- 由于时间间隔不同所以需要做最后一次Tick的判断传入的时间差是
local TempDeltaSeconds = EndTime - BuffManager.LastTickTime
if TempDeltaSeconds > 0 then
BuffManager.ExeBuffActionsFuncFromBuffInst(BuffManager.BuffInstList[BuffID], "LuaUpdateAction", TempDeltaSeconds)
end
BuffManager.RemoveBuffFromBuffID(BuffID)
end
end
-- 调用BuffAction的Tick函数
for BuffID, BuffInst in pairs(BuffManager.BuffInstList) do
BuffManager.ExeBuffActionsFuncFromBuffInst(BuffInst, "LuaUpdateAction", DeltaSeconds)
end
BuffManager.LastTickTime = NowTime
end
--- 客户端校验玩家拥有的Buff并进行创建和删除操作
function BuffManager.ClientUpdateAllPlayerOwnedBuffs()
--UGCLogSystem.LogTree("[BuffManager_ClientUpdateAllPlayerOwnedBuffs]", BuffManager.AllPlayerOwnedBuffs)
-- 先进行移除操作
for Pawn, PlayerOwnedBuff in pairs(BuffManager.ClientAllPlayerOwnedBuffs) do
for BuffID, BuffAssetType in pairs(PlayerOwnedBuff) do
if BuffManager.AllPlayerOwnedBuffs[Pawn] == nil or BuffManager.AllPlayerOwnedBuffs[Pawn][BuffID] == nil then
BuffManager.RemoveBuffFromBuffID(BuffID)
end
end
end
-- 再进行添加操作
for Pawn, PlayerOwnedBuff in pairs(BuffManager.AllPlayerOwnedBuffs) do
for BuffID, BuffAssetType in pairs(PlayerOwnedBuff) do
if BuffManager.ClientAllPlayerOwnedBuffs[Pawn] == nil or BuffManager.ClientAllPlayerOwnedBuffs[Pawn][BuffID] == nil then
if UE.IsValid(Pawn) then
BuffManager.CreateBuffToPawn(BuffID, Pawn, BuffAssetType)
end
end
end
end
end
--- 校验Pawn是否有效无效则清除对应Buff
function BuffManager.CheckPawnIsValid()
local AllPawn = UGCGameSystem.GetAllPlayerPawn()
local HaveBuffPawn = table.getKeys(BuffManager.GetAllPlayerOwnedBuffs())
for _, Pawn in pairs(HaveBuffPawn) do
if not table.hasValue(AllPawn, Pawn) then
UGCLogSystem.Log("[BuffManager_CheckPawnIsValid] Pawn:%s", tostring(Pawn))
BuffManager.ClearPlayerBuff(Pawn)
end
end
end
--- 用于Action的RPC函数 这里不能保证客户端已同步Buff因此采用传入BuffID是否为nil的方式判断是否使用单个实例的方法去调RPC如果是客户端调服务器就肯定可以
function BuffManager.RPCActionFunc(InPlayerKey, BuffID, BuffActionType, FuncName, ...)
UGCSendRPCSystem.ActorRPCNotify(InPlayerKey, UGCGameSystem.GameState, "DoBuffActionFunction", BuffID, BuffActionType, FuncName, ...)
end
function BuffManager.DoBuffActionFunction(BuffID, BuffActionType, FuncName, ...)
local BuffInst = BuffManager.BuffInstList[BuffID]
if BuffID == nil then
--- 调单例的函数
local SimpleAction = BuffManager.GetSimpleAction(BuffActionType)
if SimpleAction then
SimpleAction[FuncName](SimpleAction, ...)
else
return false
end
elseif BuffInst and BuffInst.BuffActions[BuffActionType] and BuffInst.BuffActions[BuffActionType][FuncName] then
--- 调BuffInst里的Action对应的函数
local BuffAction = BuffInst.BuffActions[BuffActionType]
BuffAction[FuncName](BuffAction, ...)
else
return false
end
return true
end