// Copyright Epic Games, Inc. All Rights Reserved. // UE5 Modular Game Framework — DA_ItemData (07) // Base item Data Asset. Single source of truth for every item. // C++ gives us UPROPERTY metadata (EditCondition, EditConditionHides, ClampMin/Max) // that make the Data Asset editor usable for designers — impossible in Blueprint. #pragma once #include "CoreMinimal.h" #include "Engine/DataAsset.h" #include "GameplayTagContainer.h" #include "Engine/Texture2D.h" #include "Engine/StaticMesh.h" #include "DA_ItemData.generated.h" /** * Item type classification. */ UENUM(BlueprintType) enum class EItemType : uint8 { Weapon UMETA(DisplayName = "Weapon"), Ammo UMETA(DisplayName = "Ammo"), Consumable UMETA(DisplayName = "Consumable"), KeyItem UMETA(DisplayName = "Key Item"), Document UMETA(DisplayName = "Document"), Collectible UMETA(DisplayName = "Collectible"), Tool UMETA(DisplayName = "Tool"), Resource UMETA(DisplayName = "Resource"), Misc UMETA(DisplayName = "Misc"), }; /** * Equipment slot type. */ UENUM(BlueprintType) enum class EEquipmentSlot : uint8 { None UMETA(DisplayName = "None"), PrimaryWeapon UMETA(DisplayName = "Primary Weapon"), SecondaryWeapon UMETA(DisplayName = "Secondary Weapon"), Melee UMETA(DisplayName = "Melee"), Tool UMETA(DisplayName = "Tool"), Armor UMETA(DisplayName = "Armor"), Accessory UMETA(DisplayName = "Accessory"), }; /** * Equipment-specific data (shown when ItemType is Weapon or Tool). */ USTRUCT(BlueprintType) struct FRAMEWORK_API FItemEquipmentData { GENERATED_BODY() UPROPERTY(EditAnywhere, BlueprintReadWrite) EEquipmentSlot Slot = EEquipmentSlot::None; UPROPERTY(EditAnywhere, BlueprintReadWrite) float Damage = 0.0f; UPROPERTY(EditAnywhere, BlueprintReadWrite) float FireRate = 0.0f; UPROPERTY(EditAnywhere, BlueprintReadWrite) float Range = 0.0f; UPROPERTY(EditAnywhere, BlueprintReadWrite) int32 MagazineSize = 0; UPROPERTY(EditAnywhere, BlueprintReadWrite) float ReloadTime = 0.0f; }; /** * Consumable-specific data (shown when ItemType is Consumable). */ USTRUCT(BlueprintType) struct FRAMEWORK_API FItemConsumableData { GENERATED_BODY() UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ClampMin = "0", ClampMax = "100")) float HealthRestore = 0.0f; UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ClampMin = "0", ClampMax = "100")) float StressReduce = 0.0f; UPROPERTY(EditAnywhere, BlueprintReadWrite) float UseDuration = 1.0f; UPROPERTY(EditAnywhere, BlueprintReadWrite) bool bConsumedOnUse = true; }; /** * Inspect-specific data (shown when bHasInspectMode is true). */ USTRUCT(BlueprintType) struct FRAMEWORK_API FItemInspectData { GENERATED_BODY() UPROPERTY(EditAnywhere, BlueprintReadWrite) FVector AnchorPoint = FVector::ZeroVector; UPROPERTY(EditAnywhere, BlueprintReadWrite) FRotator DefaultRotation = FRotator::ZeroRotator; UPROPERTY(EditAnywhere, BlueprintReadWrite) float ZoomDistance = 50.0f; UPROPERTY(EditAnywhere, BlueprintReadWrite) bool bCanRotate = true; }; /** * DA_ItemData — Base Item Data Asset. * * Every item in the game is one DA_ItemData asset. No item data lives in * Blueprint logic. C++ gives us EditCondition metadata so the editor only * shows relevant sub-structs based on ItemType — a massive UX win for designers. */ UCLASS(BlueprintType, Blueprintable, meta = (DisplayName = "Item Data")) class FRAMEWORK_API UDA_ItemData : public UPrimaryDataAsset { GENERATED_BODY() public: UDA_ItemData(); // ======================================================================== // Core Properties (Every Item Has These) // ======================================================================== /** Unique GameplayTag identifier. Must be registered in DA_GameTagRegistry. */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Core") FGameplayTag ItemTag; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Core") FText DisplayName; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Core", meta = (MultiLine = true)) FText Description; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Core") TSoftObjectPtr Icon; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Core") TSoftObjectPtr WorldMesh; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Core", meta = (ClampMin = "0", ClampMax = "1000")) float Weight = 0.0f; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Core", meta = (ClampMin = "1", ClampMax = "999")) int32 StackLimit = 1; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Core") EItemType ItemType = EItemType::Misc; // ======================================================================== // Conditional Sub-Data (Shown Based on ItemType via EditCondition) // ======================================================================== UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Equipment", meta = (EditCondition = "ItemType == EItemType::Weapon || ItemType == EItemType::Tool", EditConditionHides)) FItemEquipmentData EquipmentData; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Consumable", meta = (EditCondition = "ItemType == EItemType::Consumable", EditConditionHides)) FItemConsumableData ConsumableData; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Inspect", meta = (EditCondition = "bHasInspectMode", EditConditionHides)) FItemInspectData InspectData; // ======================================================================== // Flags // ======================================================================== UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Flags") bool bIsKeyItem = false; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Flags") bool bCanBeDropped = true; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Flags") bool bHasInspectMode = false; // ======================================================================== // Combination / Crafting // ======================================================================== /** Tags of items this can combine with. */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Combination") TArray CombinesWith; /** The resulting item tag when combined with CombinesWith item. */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Combination") FGameplayTag CombineResult; // ======================================================================== // Extensibility // ======================================================================== /** Custom per-project properties — no need to modify the base class. */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Custom") TMap CustomProperties; // ======================================================================== // Validation (Editor-Only) // ======================================================================== #if WITH_EDITOR /** * Validates the item data asset for common errors. * Called by editor utilities or pre-save validation. */ UFUNCTION(BlueprintCallable, Category = "Item|Validation") bool ValidateItemData(FString& OutErrors) const; #endif // ======================================================================== // Overrides // ======================================================================== virtual void PostLoad() override; #if WITH_EDITOR virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; #endif };