584 lines
24 KiB
Lua
584 lines
24 KiB
Lua
|
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结束的GameTime,Client不对该时间进行判断,仅靠服务器的同步进行关闭等操作
|
|||
|
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
|