// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Components/ActorComponent.h" #include "Containers/Array.h" #include "Containers/ArrayView.h" #include "Containers/Map.h" #include "Containers/Set.h" #include "Containers/SparseArray.h" #include "Containers/UnrealString.h" #include "CoreTypes.h" #include "Net/Serialization/FastArraySerializer.h" #include "Templates/SubclassOf.h" #include "Templates/UnrealTemplate.h" #include "UObject/Class.h" #include "UObject/UObjectGlobals.h" #include "LyraInventoryManagerComponent.generated.h" 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(BlueprintType) class LYRAGAME_API ULyraInventoryManagerComponent : public UActorComponent { GENERATED_BODY() public: ULyraInventoryManagerComponent(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Inventory) bool CanAddItemDefinition(TSubclassOf ItemDef, int32 StackCount = 1); UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Inventory) ULyraInventoryItemInstance* AddItemDefinition(TSubclassOf ItemDef, int32 StackCount = 1); UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Inventory) void AddItemInstance(ULyraInventoryItemInstance* ItemInstance); UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Inventory) void RemoveItemInstance(ULyraInventoryItemInstance* ItemInstance); UFUNCTION(BlueprintCallable, Category=Inventory, BlueprintPure=false) TArray GetAllItems() const; UFUNCTION(BlueprintCallable, Category=Inventory, BlueprintPure) ULyraInventoryItemInstance* FindFirstItemStackByDefinition(TSubclassOf ItemDef) const; int32 GetTotalItemCountByDefinition(TSubclassOf ItemDef) const; bool ConsumeItemsByDefinition(TSubclassOf ItemDef, int32 NumToConsume); //~UObject interface virtual bool ReplicateSubobjects(class UActorChannel* Channel, class FOutBunch* Bunch, FReplicationFlags* RepFlags) override; virtual void ReadyForReplication() override; //~End of UObject interface private: UPROPERTY(Replicated) FLyraInventoryList InventoryList; };