// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Components/ActorComponent.h" #include "Net/Serialization/FastArraySerializer.h" #include "LyraInventoryManagerComponent.generated.h" #define UE_API LYRAGAME_API class ULyraInventoryItemDefinition; class ULyraInventoryItemInstance; class ULyraInventoryManagerComponent; class UObject; struct FFrame; struct FLyraInventoryList; struct FNetDeltaSerializeInfo; struct FReplicationFlags; /** A message when an item is added to the inventory */ USTRUCT(BlueprintType) struct FLyraInventoryChangeMessage { GENERATED_BODY() //@TODO: Tag based names+owning actors for inventories instead of directly exposing the component? UPROPERTY(BlueprintReadOnly, Category=Inventory) TObjectPtr InventoryOwner = nullptr; UPROPERTY(BlueprintReadOnly, Category = Inventory) TObjectPtr Instance = nullptr; UPROPERTY(BlueprintReadOnly, Category=Inventory) int32 NewCount = 0; UPROPERTY(BlueprintReadOnly, Category=Inventory) int32 Delta = 0; }; /** A single entry in an inventory */ USTRUCT(BlueprintType) struct FLyraInventoryEntry : public FFastArraySerializerItem { GENERATED_BODY() FLyraInventoryEntry() {} FString GetDebugString() const; private: friend FLyraInventoryList; friend ULyraInventoryManagerComponent; UPROPERTY() TObjectPtr Instance = nullptr; UPROPERTY() int32 StackCount = 0; UPROPERTY(NotReplicated) int32 LastObservedCount = INDEX_NONE; }; /** List of inventory items */ USTRUCT(BlueprintType) struct FLyraInventoryList : public FFastArraySerializer { GENERATED_BODY() FLyraInventoryList() : OwnerComponent(nullptr) { } FLyraInventoryList(UActorComponent* InOwnerComponent) : OwnerComponent(InOwnerComponent) { } TArray GetAllItems() const; public: //~FFastArraySerializer contract void PreReplicatedRemove(const TArrayView RemovedIndices, int32 FinalSize); void PostReplicatedAdd(const TArrayView AddedIndices, int32 FinalSize); void PostReplicatedChange(const TArrayView ChangedIndices, int32 FinalSize); //~End of FFastArraySerializer contract bool NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms) { return FFastArraySerializer::FastArrayDeltaSerialize(Entries, DeltaParms, *this); } ULyraInventoryItemInstance* AddEntry(TSubclassOf ItemClass, int32 StackCount); void AddEntry(ULyraInventoryItemInstance* Instance); void RemoveEntry(ULyraInventoryItemInstance* Instance); private: void BroadcastChangeMessage(FLyraInventoryEntry& Entry, int32 OldCount, int32 NewCount); private: friend ULyraInventoryManagerComponent; private: // Replicated list of items UPROPERTY() TArray Entries; UPROPERTY(NotReplicated) TObjectPtr OwnerComponent; }; template<> struct TStructOpsTypeTraits : public TStructOpsTypeTraitsBase2 { enum { WithNetDeltaSerializer = true }; }; /** * Manages an inventory */ UCLASS(MinimalAPI, BlueprintType) class ULyraInventoryManagerComponent : public UActorComponent { GENERATED_BODY() public: UE_API ULyraInventoryManagerComponent(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Inventory) UE_API bool CanAddItemDefinition(TSubclassOf ItemDef, int32 StackCount = 1); UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Inventory) UE_API ULyraInventoryItemInstance* AddItemDefinition(TSubclassOf ItemDef, int32 StackCount = 1); UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Inventory) UE_API void AddItemInstance(ULyraInventoryItemInstance* ItemInstance); UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Inventory) UE_API void RemoveItemInstance(ULyraInventoryItemInstance* ItemInstance); UFUNCTION(BlueprintCallable, Category=Inventory, BlueprintPure=false) UE_API TArray GetAllItems() const; UFUNCTION(BlueprintCallable, Category=Inventory, BlueprintPure) UE_API ULyraInventoryItemInstance* FindFirstItemStackByDefinition(TSubclassOf ItemDef) const; UE_API int32 GetTotalItemCountByDefinition(TSubclassOf ItemDef) const; UE_API bool ConsumeItemsByDefinition(TSubclassOf ItemDef, int32 NumToConsume); //~UObject interface UE_API virtual bool ReplicateSubobjects(class UActorChannel* Channel, class FOutBunch* Bunch, FReplicationFlags* RepFlags) override; UE_API virtual void ReadyForReplication() override; //~End of UObject interface private: UPROPERTY(Replicated) FLyraInventoryList InventoryList; }; #undef UE_API