---@class BP_BuffController_C:AActor ---@field DefaultSceneRoot USceneComponent ---@field PlayerBuffs table> 所有玩家拥有的 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;