206 lines
5.8 KiB
Lua
Raw Normal View History

2025-01-04 23:00:19 +08:00
---@class BP_BuffController_C:AActor
---@field DefaultSceneRoot USceneComponent
---@field PlayerBuffs table<int32, table<int32, BuffItem>> <PlayerKey = { [BuffId = BuffItem]}> 所有玩家拥有的 Buff
---@field GlobalBuffIndex int32
--Edit Below--
---@type BP_BuffController_C
local BP_BuffController = {
-- 玩家拥有的Buff
PlayerBuffs = {};
-- Buff 添加的 Index
GlobalBuffIndex = 0;
};
BP_BuffController.ControllerInst = nil;
function BP_BuffController:ReceiveBeginPlay()
self.SuperClass.ReceiveBeginPlay(self);
end
function BP_BuffController.GetBuffController()
if BP_BuffController.ControllerInst == nil then
local AllActor = GameplayStatics.GetAllActorsOfClass(UGCGameSystem.GameState, BP_BuffController.GetSelfClass(), {})
if AllActor:Num() > 0 then
BP_BuffController.ControllerInst = AllActor[0];
else
BP_BuffController.ControllerInst = ScriptGameplayStatics.SpawnActor(UGCGameSystem.GameState, BP_BuffController.GetManagerClass(),
VectorHelper.VectorZero(),
VectorHelper.RotZero(),
VectorHelper.ScaleOne());
end
end
return BP_BuffController.ControllerInst;
end
function BP_BuffController:ReceiveTick(DeltaTime)
self.SuperClass.ReceiveTick(self, DeltaTime);
self:TickBuff(DeltaTime);
if self:HasAuthority() then
--- 移除时间到了的 Buff
local ServerTime = KismetSystemLibrary.GetGameTimeInSeconds(self);
local RemoveBuffs = {};
for PlayerKey, Buffs in pairs(self.PlayerBuffs) do
for BuffId, BuffItem in pairs(Buffs) do
if BuffItem.ContinueTime > 0 then
for BuffIndex, SingleItem in pairs(BuffItem.Items) do
if SingleItem.EndTime <= ServerTime then
RemoveBuffs[#RemoveBuffs + 1] = {
PlayerKey = PlayerKey,
BuffId = BuffId,
RemoveIndex = BuffIndex, -- 这个index是 GlobalBuffIndex
};
end
end
end
end
end
for i = 1, #RemoveBuffs do
self:RemoveBuff(RemoveBuffs[i].PlayerKey, RemoveBuffs[i].BuffId, RemoveBuffs[i].RemoveIndex);
end
end
end
--[[
function BP_BuffController:ReceiveEndPlay()
self.SuperClass.ReceiveEndPlay(self);
end
--]]
function BP_BuffController:GetReplicatedProperties()
return "PlayerBuffs"
end
--[[
function BP_BuffController:GetAvailableServerRPCs()
return
end
--]]
--- 给玩家添加 Buff
---@protected
---@param InPlayerKey int32 玩家 Key
---@param InBuffId int32 BuffType
---@return
function BP_BuffController:AddBuff(InPlayerKey, InBuffId, ...)
local ActionInfo = BuffConfig.BuffActionInfo[InBuffId];
if ActionInfo == nil then
UGCLogSystem.Log("[BP_BuffController:AddBuff_Private] 不存在当前 BuffId: %d", InBuffId)
return nil
end
local BuffInst = require(ActionInfo.Path);
if BuffInst == nil then
UGCLogSystem.LogError("[BP_BuffController:AddBuff_Private] 无法 require Buff[%d][%s]", InBuffId, ActionInfo.Path);
return nil;
end
-- 添加到表中
if self.PlayerBuffs[InPlayerKey] == nil then
self.PlayerBuffs[InPlayerKey] = {};
end
if self.PlayerBuffs[InPlayerKey][InBuffId] == nil then
self.PlayerBuffs[InPlayerKey][InBuffId] = {};
end
self.GlobalBuffIndex = self.GlobalBuffIndex + 1;
local ServerTime = KismetSystemLibrary.GetGameTimeInSeconds(self);
--- 检查一下是否需要冷却
-- 开启 Init
table.func(BuffInst, "Init", InBuffId, InPlayerKey, ...)
-- 添加的瞬间就会执行一次
table.func(BuffInst, "ApplyBuff", InBuffId, InPlayerKey, ...);
--- 将参数放到每一个 Inst里面
BuffInst["Vars"] = {
InBuffId,
InPlayerKey,
...
};
-- 判断是否需要一添加就移除
if BuffInst["bRunOnce"] ~= nil and BuffInst["bRunOnce"] == true then
UGCLogSystem.Log("[BP_BuffController:AddBuff_Private] BuffId: %d 只执行一次", InBuffId)
return BuffInst;
end
local CooldownTime = BuffInst["CooldownTime"];
if type(CooldownTime) ~= "number" then
CooldownTime = 0;
end
self.PlayerBuffs[InPlayerKey][InBuffId][self.GlobalBuffIndex] = {
StartTime = ServerTime,
Inst = BuffInst,
PlayerKey = InPlayerKey,
BuffId = InBuffId,
EndTime = ServerTime + CooldownTime,
};
return BuffInst;
end
function BP_BuffController:RemoveBuff(InPlayerKey, InBuffId, InBuffIndex)
local BuffItem = self.PlayerBuffs[InPlayerKey][InBuffId][InBuffIndex];
self:RemoveBuff(BuffItem.Inst);
end
function BP_BuffController:RemoveBuff(InBuffInst)
-- 遍历所有
for PlayerKey, Buffs in pairs(self.PlayerBuffs) do
local RemoveBuffId = nil;
for BuffId, BuffItem in pairs(Buffs) do
local Index = nil;
for BuffIndex, SingleItem in pairs(BuffItem.Items) do
if SingleItem.Inst == InBuffInst then
-- 移除当前的
Index = BuffIndex;
end
end
if Index ~= nil then
table.func(BuffItem[Index].Inst, "RemoveBuff", table.unpackTable(BuffItem[Index].Inst.Vars))
BuffItem[Index] = nil; -- 移除
end
if table.isEmpty(BuffItem) then
RemoveBuffId = BuffId;
end
end
if RemoveBuffId ~= nil then
Buffs[RemoveBuffId] = nil;
end
end
end
---@param InPlayerKey int32 要移除的玩家 Key
function BP_BuffController:RemovePlayerBuff(InPlayerKey)
for BuffId, BuffItem in pairs(self.PlayerBuffs[InPlayerKey]) do
for BuffIndex, SingleItem in pairs(BuffItem.Items) do
table.func(SingleItem.Inst, "RemoveBuff", table.unpackTable(SingleItem.Inst.Vars));
end
end
self.PlayerBuffs[InPlayerKey] = {};
end
function BP_BuffController:TickBuff(InDeltaTime)
if self:HasAuthority() then
for PlayerKey, Buffs in pairs(self.PlayerBuffs) do
for BuffId, BuffItem in pairs(Buffs) do
for BuffIndex, SingleItem in pairs(BuffItem.Items) do
table.func(SingleItem.Inst, "Tick", SingleItem.BuffId, SingleItem.PlayerKey, InDeltaTime);
end
end
end
end
end
function BP_BuffController.GetSelfClass()
return UE.LoadClass(UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/BUFF/BP_BuffController.BP_BuffController_C'));
end
return BP_BuffController;