---@class BP_CustomItemBase_C:AActor ---@field Capsule UCapsuleComponent ---@field DefaultSceneRoot USceneComponent ---@field ItemId int32 ---@field RotationLength int32 ---@field ConstItemId int32 --Edit Below-- require('Script.Global.DefaultSettings') ---@type BP_CustomItemBase_C local BP_CustomItemBase = {}; BP_CustomItemBase.OverlapPlayers = {}; BP_CustomItemBase.bCanPickUp = false; BP_CustomItemBase.bUseLimit = false; BP_CustomItemBase.RefreshTime = 0; BP_CustomItemBase.EventType = nil; BP_CustomItemBase.bEnableOverlap = true; BP_CustomItemBase.CachedItemId = 0; --function BP_CustomItemBase:ReceiveBeginPlay() -- self.SuperClass.ReceiveBeginPlay(self); --end function BP_CustomItemBase:LuaInit() self:PreInit(); self:InitItem(); self:PostInit(); end function BP_CustomItemBase:new(Config) if Config ~= nil then return setmetatable({ bUseLimit = Config.IsLimit, RefreshTime = Config.RefreshTime, EventType = Config.EventType, OverlapPlayers = {}; bCanPickUp = false; bEnableOverlap = true; }, { __index = self, __metatable = self, }) else return setmetatable({ bUseLimit = false, RefreshTime = 5, EventType = nil, OverlapPlayers = {}; bCanPickUp = false; bEnableOverlap = true; }, { __index = self, __metatable = self, }); end end function BP_CustomItemBase:PreInit() end function BP_CustomItemBase:InitItem() if IsServer then UGCEventSystem.AddListener(EventTypes.PlayerDead, self.OnPlayerDead, self); if not self.bUseLimit then self:RandomNewItem(); end else self:HandleEffect(self.ParticleSystem); end if self.bEnableOverlap then self.Capsule.OnComponentBeginOverlap:Add(self.OnCapsuleBegin, self); self.Capsule.OnComponentEndOverlap:Add(self.OnCapsuleEnd, self); end end function BP_CustomItemBase:PostInit() end function BP_CustomItemBase:OnCapsuleBegin(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult) if IsServer then if UE.IsPlayerPawn(OtherActor) then self.OverlapPlayers[#self.OverlapPlayers + 1] = OtherActor.PlayerKey; self:OnPlayerIn(OtherActor); end end end function BP_CustomItemBase:OnCapsuleEnd(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex) if IsServer then if UE.IsPlayerPawn(OtherActor) then self:OnPlayerOut(OtherActor); table.removeValue(self.OverlapPlayers, OtherActor.PlayerKey, true); end end end function BP_CustomItemBase:OnPlayerDead(InDeadPlayerKey, InKillerPlayerKey) table.removeValue(self.OverlapPlayers, InDeadPlayerKey) end ---@param InPawn UGCPlayerPawn_C function BP_CustomItemBase:OnItemUsed(InPawn) if self.ItemId == 0 then return; end if self.EventType ~= nil then UGCEventSystem.SendEvent(self.EventType, self, InPawn); end self.ItemId = 0; self.CachedItemId = 0; DOREPONCE(self, "ItemId"); end ---@param OtherActor UGCPlayerPawn_C function BP_CustomItemBase:OnPlayerIn(OtherActor) if IsServer then UGCLogSystem.Log("[BP_CustomItemBase:OnPlayerIn] Pawn = %s", UE.GetPlayerName(OtherActor.PlayerKey)) if not self:IsItemIdValid() then return end UGCLogSystem.Log("[BP_CustomItemBase:OnPlayerIn] 执行 111") self:OnPlayerAddItem(OtherActor); if not self.bUseLimit then UGCLogSystem.Log("[BP_CustomItemBase:OnPlayerIn] 执行 222") UGCEventSystem.SetTimer(self, function() self:PreRandomNewItem(); self:RandomNewItem(); self:OnPostRandomNewItem(); end, self.RefreshTime) end DOREPONCE(self, "ItemId"); end end ---@param OtherActor UGCPlayerPawn_C function BP_CustomItemBase:OnPlayerOut(OtherActor) end ---@param InPawn UGCPlayerPawn_C function BP_CustomItemBase:OnPlayerAddItem(InPawn) end function BP_CustomItemBase:PreRandomNewItem() end function BP_CustomItemBase:UseConstItemID() if self.ConstItemId ~= 0 then -- 使用这个 self:SetItemId(self.ConstItemId); end end function BP_CustomItemBase:RandomNewItem() end ---@param Component UParticleSystemComponent function BP_CustomItemBase:HandleEffect(Component, Name) if Component == nil then UGCLogSystem.Log("[BP_CustomItemBase:HandleEffect] Component = nil") return end UGCLogSystem.Log("[BP_CustomItemBase:HandleEffect] ItemId = %d, Component = %s", self.ItemId, UE.GetName(Component)); if self:IsItemIdValid() then if Component.Template == nil then local Resource = GameState:LoadResource(); if Resource and Resource.ParticleList[Name] then local Item = Resource.ParticleList[Name]; UGCLogSystem.Log("[BP_CustomItemBase:HandleEffect] 直接就找到了,Item = %s", UE.GetName(Item)); if Item ~= nil then Component:SetTemplate(Item); end else self.ParticleTimer = UGCEventSystem.SetTimerLoop(self, function() Resource = GameState:LoadResource(); if Resource and Resource.ParticleList[Name] then local Item = Resource.ParticleList[Name]; if Item ~= nil then UGCLogSystem.Log("[BP_CustomItemBase:HandleEffect] Item = %s", UE.GetName(Item)); Component:SetTemplate(Item); end if self.ParticleTimer ~= nil then UGCEventSystem.StopTimer(self.ParticleTimer); self.ParticleTimer = nil; end else if Resource then UGCLogSystem.Log("[BP_CustomItemBase:HandleEffect] Resource = %s", UE.GetName(Resource)); else UGCLogSystem.Log("[BP_CustomItemBase:HandleEffect] Resource = nil"); end UGCLogSystem.Log("[BP_CustomItemBase:HandleEffect] 还是需要继续循环"); end end, 0.3); end end Component:SetHiddenInGame(false); else Component:SetHiddenInGame(true); end UGCLogSystem.Log("[BP_CustomItemBase:HandleEffect] ItemId = %d, IsVisible = %s", self.ItemId, tostring(Component:IsVisible())) end function BP_CustomItemBase:OnPostRandomNewItem() UGCLogSystem.LogTree(string.format("[BP_CustomItemBase:OnPostRandomNewItem] self.OverlapPlayers ="), self.OverlapPlayers) if not table.isEmpty(self.OverlapPlayers) then local PlayerKey = self.OverlapPlayers[math.random(#self.OverlapPlayers)]; if PlayerKey ~= nil then local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey); if UE.IsValid(Pawn) and Pawn:IsAlive() then self:OnPlayerIn(Pawn); end end end end ---@return bool function BP_CustomItemBase:IsItemIdValid() return self.ItemId ~= 0; end ---@param InItemId int32 function BP_CustomItemBase:SetItemId(InItemId) UGCLogSystem.Log("[BP_CustomItemBase:SetItemId] InItemId = %d", InItemId) self.ItemId = self.ConstItemId == 0 and InItemId or self.ConstItemId; UGCLogSystem.Log("[BP_CustomItemBase:SetItemId] 执行 InItemId = %d", self.ItemId) self.CachedItemId = self.ItemId; -- 发送 RPC DOREPONCE(self, "ItemId"); end function BP_CustomItemBase:SetCanPickUp(IsCan) self.bCanPickUp = IsCan; DOREPONCE(self, "bCanPickUp") end ---@return int32 function BP_CustomItemBase:GetItemId() return self.CachedItemId; end function BP_CustomItemBase:ResetItem() self.ItemId = 0; self.CachedItemId = 0; DOREPONCE(self, "ItemId"); end --[[ function BP_CustomItemBase:ReceiveTick(DeltaTime) self.SuperClass.ReceiveTick(self, DeltaTime); end --]] --[[ function BP_CustomItemBase:ReceiveEndPlay() self.SuperClass.ReceiveEndPlay(self); end --]] function BP_CustomItemBase:GetReplicatedProperties() return { "ItemId", "Lazy" } , { "bCanPickUp", "Lazy" } end --[[ function BP_CustomItemBase:GetAvailableServerRPCs() return end --]] return BP_CustomItemBase;