Add core gameplay systems and data assets for player mechanics
- Implemented DA_EquipmentConfig for managing equipment resistances, durability, and weight. - Created DA_ItemData to serve as a base item data asset with various item types and properties. - Introduced BPC_HealthSystem for managing player health and death events. - Added BPC_MovementStateSystem to handle player movement modes with event delegation. - Developed BPC_StaminaSystem to track player stamina and exhaustion states. - Established BPC_StateManager as a central authority for managing player action states and gating. - Created BPC_StressSystem to monitor and respond to player stress levels. - Implemented PC_CoreController and PS_CorePlayerState for player controller and state management. - Developed SS_SaveManager for save/load functionality with slot management and serialization. - Introduced DA_StateGatingTable for defining action gating rules based on gameplay tags. - Added BPC_DamageReceptionSystem to process incoming damage and apply resistance calculations. - Implemented BPC_HitReactionSystem for managing hit reactions based on damage received. - Created BPC_ShieldDefenseSystem to manage shield health and blocking mechanics. - Added PG_FrameworkEditor.Target.cs for editor build configuration.
This commit is contained in:
210
Source/PG_Framework/Public/Inventory/BPC_InventorySystem.h
Normal file
210
Source/PG_Framework/Public/Inventory/BPC_InventorySystem.h
Normal file
@@ -0,0 +1,210 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
// UE5 Modular Game Framework — BPC_InventorySystem (31)
|
||||
// Core inventory grid. Add/remove/sort/stack/weight management.
|
||||
// In C++, TArray operations with lambdas are natively fast — no BP array node overhead.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "BPC_InventorySystem.generated.h"
|
||||
|
||||
class UDA_ItemData;
|
||||
|
||||
/**
|
||||
* Single inventory slot entry.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FRAMEWORK_API FInventorySlot
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** The item in this slot. nullptr = empty slot. */
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
TObjectPtr<UDA_ItemData> Item = nullptr;
|
||||
|
||||
/** How many of this item are stacked here. */
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
int32 Quantity = 0;
|
||||
|
||||
/** Grid position for UI layout. */
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
int32 GridX = 0;
|
||||
|
||||
/** Grid position for UI layout. */
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
int32 GridY = 0;
|
||||
|
||||
bool IsEmpty() const { return Item == nullptr || Quantity <= 0; }
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Item = nullptr;
|
||||
Quantity = 0;
|
||||
}
|
||||
|
||||
bool operator==(const FInventorySlot& Other) const
|
||||
{
|
||||
return Item == Other.Item && Quantity == Other.Quantity && GridX == Other.GridX && GridY == Other.GridY;
|
||||
}
|
||||
};
|
||||
|
||||
// Delegates
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnInventoryChanged);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnItemAdded, UDA_ItemData*, Item, int32, Quantity);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnItemRemoved, UDA_ItemData*, Item, int32, Quantity);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnWeightChanged, float, CurrentWeight, float, MaxWeight);
|
||||
|
||||
/**
|
||||
* BPC_InventorySystem — Core Inventory Grid.
|
||||
*
|
||||
* Manages the player's carried items: add, remove, sort, stack, weight tracking.
|
||||
* C++ TArray operations (FindByPredicate, Sort, Filter) are natively compiled —
|
||||
* no BP interpretive array node overhead.
|
||||
*/
|
||||
UCLASS(Blueprintable, ClassGroup = (Framework), meta = (BlueprintSpawnableComponent))
|
||||
class FRAMEWORK_API UBPC_InventorySystem : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UBPC_InventorySystem();
|
||||
|
||||
// ========================================================================
|
||||
// Configuration
|
||||
// ========================================================================
|
||||
|
||||
/** Grid width (columns). */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Inventory|Config")
|
||||
int32 GridWidth = 8;
|
||||
|
||||
/** Grid height (rows). */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Inventory|Config")
|
||||
int32 GridHeight = 5;
|
||||
|
||||
/** Maximum carry weight. Items exceeding this cannot be picked up. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Inventory|Config")
|
||||
float MaxWeight = 50.0f;
|
||||
|
||||
// ========================================================================
|
||||
// Inventory State
|
||||
// ========================================================================
|
||||
|
||||
/** All inventory slots (GridWidth × GridHeight). */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Framework|Inventory")
|
||||
TArray<FInventorySlot> Slots;
|
||||
|
||||
/** Current total weight carried. */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Framework|Inventory")
|
||||
float CurrentWeight = 0.0f;
|
||||
|
||||
/** Whether the inventory has been modified since last save. */
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Framework|Inventory")
|
||||
bool bDirty = false;
|
||||
|
||||
// ========================================================================
|
||||
// Core Operations
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* Add an item to the inventory. Stacks if possible, finds empty slot otherwise.
|
||||
* Returns the quantity actually added (may be less than requested if full).
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Framework|Inventory")
|
||||
int32 AddItem(UDA_ItemData* Item, int32 Quantity = 1);
|
||||
|
||||
/**
|
||||
* Remove an item from the inventory.
|
||||
* Returns the quantity actually removed.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Framework|Inventory")
|
||||
int32 RemoveItem(UDA_ItemData* Item, int32 Quantity = 1);
|
||||
|
||||
/**
|
||||
* Remove an item from a specific slot.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "Framework|Inventory")
|
||||
int32 RemoveItemFromSlot(int32 SlotIndex, int32 Quantity = 1);
|
||||
|
||||
/**
|
||||
* Check if an item can be added (enough space and weight capacity).
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Framework|Inventory")
|
||||
bool CanAddItem(UDA_ItemData* Item, int32 Quantity = 1) const;
|
||||
|
||||
// ========================================================================
|
||||
// Query
|
||||
// ========================================================================
|
||||
|
||||
/** Returns the total quantity of an item across all stacks. */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Framework|Inventory")
|
||||
int32 GetItemCount(UDA_ItemData* Item) const;
|
||||
|
||||
/** Returns whether the inventory contains at least this many of an item. */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Framework|Inventory")
|
||||
bool HasItem(UDA_ItemData* Item, int32 Quantity = 1) const;
|
||||
|
||||
/** Finds the first slot containing the given item. Returns -1 if not found. */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Framework|Inventory")
|
||||
int32 FindItemSlot(UDA_ItemData* Item) const;
|
||||
|
||||
/** Returns all unique items currently in the inventory. */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Framework|Inventory")
|
||||
TArray<UDA_ItemData*> GetAllItems() const;
|
||||
|
||||
/** Returns the number of empty slots available. */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Framework|Inventory")
|
||||
int32 GetEmptySlotCount() const;
|
||||
|
||||
/** Returns the number of free weight units remaining. */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Framework|Inventory")
|
||||
float GetRemainingWeight() const;
|
||||
|
||||
// ========================================================================
|
||||
// Organization
|
||||
// ========================================================================
|
||||
|
||||
/** Sort inventory by ItemType, then by DisplayName. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Framework|Inventory")
|
||||
void SortInventory();
|
||||
|
||||
/** Auto-merge all partial stacks of the same item. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Framework|Inventory")
|
||||
void ConsolidateStacks();
|
||||
|
||||
// ========================================================================
|
||||
// Event Dispatchers
|
||||
// ========================================================================
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Framework|Inventory|Events")
|
||||
FOnInventoryChanged OnInventoryChanged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Framework|Inventory|Events")
|
||||
FOnItemAdded OnItemAdded;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Framework|Inventory|Events")
|
||||
FOnItemRemoved OnItemRemoved;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Framework|Inventory|Events")
|
||||
FOnWeightChanged OnWeightChanged;
|
||||
|
||||
// ========================================================================
|
||||
// Overrides
|
||||
// ========================================================================
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
protected:
|
||||
/** Recalculates total weight from all slots. */
|
||||
void RecalculateWeight();
|
||||
|
||||
/** Finds an existing stack for an item (not at max stack limit). Returns -1 if none found. */
|
||||
int32 FindExistingStack(UDA_ItemData* Item) const;
|
||||
|
||||
/** Finds the first empty slot. Returns -1 if inventory is full. */
|
||||
int32 FindEmptySlot() const;
|
||||
|
||||
/** Marks inventory as modified and broadcasts change dispatchers. */
|
||||
void MarkDirty();
|
||||
};
|
||||
37
Source/PG_Framework/Public/Inventory/DA_EquipmentConfig.h
Normal file
37
Source/PG_Framework/Public/Inventory/DA_EquipmentConfig.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "DA_EquipmentConfig.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FRAMEWORK_API FDamageTypeResistance
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FGameplayTag DamageType;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
float Resistance = 0.0f;
|
||||
};
|
||||
|
||||
UCLASS(BlueprintType)
|
||||
class FRAMEWORK_API UDA_EquipmentConfig : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Config")
|
||||
TArray<FDamageTypeResistance> DamageTypeResistances;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Config")
|
||||
float Durability = 100.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Config")
|
||||
float Weight = 1.0f;
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Config")
|
||||
float GetResistance(FGameplayTag DamageType) const;
|
||||
};
|
||||
232
Source/PG_Framework/Public/Inventory/DA_ItemData.h
Normal file
232
Source/PG_Framework/Public/Inventory/DA_ItemData.h
Normal file
@@ -0,0 +1,232 @@
|
||||
// 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<UTexture2D> Icon;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item|Core")
|
||||
TSoftObjectPtr<UStaticMesh> 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<FGameplayTag> 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<FName, FString> 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
|
||||
};
|
||||
Reference in New Issue
Block a user