// Copyright ExByte Studios. Item Interaction Ecosystem. #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "ItemInstanceData.h" #include "ItemInteractionInterfaces.h" #include "PickupItemActor.generated.h" class UStaticMeshComponent; class UInteractableComponent; /** * The world representation of an item lying on the ground / a surface (section 12). * * One actor per world item only (never one per inventory item - section 32/34). * Implements IWorldItemProvider so the interaction layer can pick it up, carry it * or take part of its stack without ItemWorld <-> ItemInteraction coupling. */ UCLASS() class ITEMWORLD_API APickupItemActor : public AActor, public IWorldItemProvider { GENERATED_BODY() public: APickupItemActor(); virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; virtual void BeginPlay() override; /** Server: stamp this pickup with an item and refresh its visuals. */ UFUNCTION(BlueprintCallable, Category = "Item|World") void InitializeFromItem(const FItemInstanceData& InItem); /** Server convenience: spawn a fresh pickup for ItemId at a transform. */ UFUNCTION(BlueprintCallable, Category = "Item|World", meta = (WorldContext = "WorldContext")) static APickupItemActor* SpawnPickup(UObject* WorldContext, FName ItemId, int32 Quantity, const FTransform& Transform); /** Server convenience: spawn a pickup carrying an existing instance (e.g. on drop). */ static APickupItemActor* SpawnPickupFromInstance(UObject* WorldContext, const FItemInstanceData& Item, const FTransform& Transform); //~ IWorldItemProvider virtual bool GetProvidedItem(FItemInstanceData& OutItem) const override; virtual bool IsItemAvailable() const override; virtual void NotifyItemTaken(AActor* Taker) override; virtual void UpdateProvidedItem(const FItemInstanceData& RemainingItem) override; virtual void SetCarried(AActor* Holder, bool bCarried) override; /** Server: drop this carried actor back into the world at a transform. */ void ReleaseToWorld(const FTransform& WorldTransform); UStaticMeshComponent* GetMeshComponent() const { return Mesh; } UFUNCTION(BlueprintPure, Category = "Item|World") const FItemInstanceData& GetItemData() const { return ItemData; } protected: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Item|World") TObjectPtr Root; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Item|World") TObjectPtr Mesh; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Item|World") TObjectPtr Interactable; UPROPERTY(ReplicatedUsing = OnRep_ItemData, BlueprintReadOnly, Category = "Item|World") FItemInstanceData ItemData; UPROPERTY(Replicated, BlueprintReadOnly, Category = "Item|World") bool bIsLocked = false; UPROPERTY(Replicated, BlueprintReadOnly, Category = "Item|World") TObjectPtr CurrentHolder = nullptr; UFUNCTION() void OnRep_ItemData(); /** Resolves the definition and applies WorldMesh + interactable display name. */ void RefreshVisuals(); };