2025-01-04 23:00:19 +08:00

584 lines
24 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.

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