feat: Implement core gameplay systems and data assets for health, stamina, stress, movement, hit reactions, and shield defense

This commit is contained in:
Lefteris Notas
2026-05-21 13:16:43 +03:00
parent 0b1128d209
commit 9ee0a65630
22 changed files with 480 additions and 14 deletions

View File

@@ -0,0 +1,3 @@
#include "Modules/ModuleManager.h"
IMPLEMENT_MODULE(FDefaultModuleImpl, Framework);

View File

@@ -0,0 +1,13 @@
#include "Inventory/DA_EquipmentConfig.h"
float UDA_EquipmentConfig::GetResistance(FGameplayTag DamageType) const
{
for (const FDamageTypeResistance& Entry : DamageTypeResistances)
{
if (Entry.DamageType == DamageType)
{
return Entry.Resistance;
}
}
return 0.0f;
}

View File

@@ -0,0 +1,6 @@
#include "Player/BPC_HealthSystem.h"
UBPC_HealthSystem::UBPC_HealthSystem()
{
PrimaryComponentTick.bCanEverTick = false;
}

View File

@@ -0,0 +1,6 @@
#include "Player/BPC_MovementStateSystem.h"
UBPC_MovementStateSystem::UBPC_MovementStateSystem()
{
PrimaryComponentTick.bCanEverTick = true;
}

View File

@@ -0,0 +1,6 @@
#include "Player/BPC_StaminaSystem.h"
UBPC_StaminaSystem::UBPC_StaminaSystem()
{
PrimaryComponentTick.bCanEverTick = true;
}

View File

@@ -0,0 +1,6 @@
#include "Player/BPC_StressSystem.h"
UBPC_StressSystem::UBPC_StressSystem()
{
PrimaryComponentTick.bCanEverTick = true;
}

View File

@@ -0,0 +1,5 @@
#include "Player/PC_CoreController.h"
APC_CoreController::APC_CoreController()
{
}

View File

@@ -0,0 +1,5 @@
#include "Player/PS_CorePlayerState.h"
APS_CorePlayerState::APS_CorePlayerState()
{
}

View File

@@ -0,0 +1,13 @@
#include "State/DA_StateGatingTable.h"
bool UDA_StateGatingTable::IsActionGated(FGameplayTag ActionTag, FGameplayTag CurrentState) const
{
for (const FStateGatingRule& Rule : GatingRules)
{
if (Rule.ActionTag == ActionTag && Rule.BlockedByState == CurrentState)
{
return Rule.bIsBlocked;
}
}
return false;
}

View File

@@ -0,0 +1,11 @@
#include "Weapons/BPC_HitReactionSystem.h"
UBPC_HitReactionSystem::UBPC_HitReactionSystem()
{
PrimaryComponentTick.bCanEverTick = false;
}
void UBPC_HitReactionSystem::PlayHitReaction(float DamageAmount, FVector HitDirection, AActor* DamageCauser)
{
// Stub — Blueprint child provides animation selection logic.
}

View File

@@ -0,0 +1,6 @@
#include "Weapons/BPC_ShieldDefenseSystem.h"
UBPC_ShieldDefenseSystem::UBPC_ShieldDefenseSystem()
{
PrimaryComponentTick.bCanEverTick = false;
}

View 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;
};

View File

@@ -0,0 +1,29 @@
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "BPC_HealthSystem.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnHealthChanged, float, CurrentHealth, float, MaxHealth);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDeath);
UCLASS(Blueprintable, ClassGroup=(Framework), meta=(BlueprintSpawnableComponent))
class FRAMEWORK_API UBPC_HealthSystem : public UActorComponent
{
GENERATED_BODY()
public:
UBPC_HealthSystem();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Health")
float MaxHealth = 100.0f;
UPROPERTY(BlueprintReadOnly, Category = "Framework|Health")
float CurrentHealth = 100.0f;
UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
FOnHealthChanged OnHealthChanged;
UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
FOnDeath OnDeath;
};

View File

@@ -0,0 +1,23 @@
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "GameplayTagContainer.h"
#include "BPC_MovementStateSystem.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnMovementModeChanged, FGameplayTag, NewMode, FGameplayTag, OldMode);
UCLASS(Blueprintable, ClassGroup=(Framework), meta=(BlueprintSpawnableComponent))
class FRAMEWORK_API UBPC_MovementStateSystem : public UActorComponent
{
GENERATED_BODY()
public:
UBPC_MovementStateSystem();
UPROPERTY(BlueprintReadOnly, Category = "Framework|Movement")
FGameplayTag CurrentMovementMode;
UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
FOnMovementModeChanged OnMovementModeChanged;
};

View File

@@ -0,0 +1,25 @@
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "BPC_StaminaSystem.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnExhaustionStateChanged, bool, bExhausted);
UCLASS(Blueprintable, ClassGroup=(Framework), meta=(BlueprintSpawnableComponent))
class FRAMEWORK_API UBPC_StaminaSystem : public UActorComponent
{
GENERATED_BODY()
public:
UBPC_StaminaSystem();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Stamina")
float MaxStamina = 100.0f;
UPROPERTY(BlueprintReadOnly, Category = "Framework|Stamina")
float CurrentStamina = 100.0f;
UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
FOnExhaustionStateChanged OnExhaustionStateChanged;
};

View File

@@ -0,0 +1,32 @@
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "BPC_StressSystem.generated.h"
UENUM(BlueprintType)
enum class EStressTier : uint8
{
Calm UMETA(DisplayName = "Calm"),
Tense UMETA(DisplayName = "Tense"),
Distressed UMETA(DisplayName = "Distressed"),
Panic UMETA(DisplayName = "Panic"),
Catatonic UMETA(DisplayName = "Catatonic"),
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnStressTierChanged, EStressTier, NewTier);
UCLASS(Blueprintable, ClassGroup=(Framework), meta=(BlueprintSpawnableComponent))
class FRAMEWORK_API UBPC_StressSystem : public UActorComponent
{
GENERATED_BODY()
public:
UBPC_StressSystem();
UPROPERTY(BlueprintReadOnly, Category = "Framework|Stress")
EStressTier StressTier = EStressTier::Calm;
UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
FOnStressTierChanged OnStressTierChanged;
};

View File

@@ -0,0 +1,14 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "PC_CoreController.generated.h"
UCLASS()
class FRAMEWORK_API APC_CoreController : public APlayerController
{
GENERATED_BODY()
public:
APC_CoreController();
};

View File

@@ -0,0 +1,14 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerState.h"
#include "PS_CorePlayerState.generated.h"
UCLASS()
class FRAMEWORK_API APS_CorePlayerState : public APlayerState
{
GENERATED_BODY()
public:
APS_CorePlayerState();
};

View File

@@ -0,0 +1,34 @@
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "GameplayTagContainer.h"
#include "DA_StateGatingTable.generated.h"
USTRUCT(BlueprintType)
struct FRAMEWORK_API FStateGatingRule
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FGameplayTag ActionTag;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FGameplayTag BlockedByState;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool bIsBlocked = true;
};
UCLASS(BlueprintType)
class FRAMEWORK_API UDA_StateGatingTable : public UPrimaryDataAsset
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gating")
TArray<FStateGatingRule> GatingRules;
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Gating")
bool IsActionGated(FGameplayTag ActionTag, FGameplayTag CurrentState) const;
};

View File

@@ -0,0 +1,24 @@
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "GameplayTagContainer.h"
#include "BPC_HitReactionSystem.generated.h"
UCLASS(Blueprintable, ClassGroup=(Framework), meta=(BlueprintSpawnableComponent))
class FRAMEWORK_API UBPC_HitReactionSystem : public UActorComponent
{
GENERATED_BODY()
public:
UBPC_HitReactionSystem();
UFUNCTION(BlueprintCallable, Category = "Framework|Combat")
void PlayHitReaction(float DamageAmount, FVector HitDirection, AActor* DamageCauser);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|HitReaction")
float FlinchThreshold = 5.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|HitReaction")
float RagdollThreshold = 50.0f;
};

View File

@@ -0,0 +1,26 @@
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "BPC_ShieldDefenseSystem.generated.h"
UCLASS(Blueprintable, ClassGroup=(Framework), meta=(BlueprintSpawnableComponent))
class FRAMEWORK_API UBPC_ShieldDefenseSystem : public UActorComponent
{
GENERATED_BODY()
public:
UBPC_ShieldDefenseSystem();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Shield")
float ShieldHealth = 100.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Shield")
float MaxShieldHealth = 100.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Shield")
float BlockAngle = 90.0f;
UPROPERTY(BlueprintReadOnly, Category = "Framework|Shield")
bool bShieldBroken = false;
};

View File

@@ -538,7 +538,112 @@ State->OnVitalSignChanged.AddDynamic(this, &UMyClass::OnVitalSignChanged);
`IsActionPermitted()` is on the **hot path** — called potentially per-frame by 10+ systems. In C++, it's a native `TArray`/`TMap` lookup. In BP, it would be interpretive graph traversal each call. Heart rate smoothing is `FMath::FInterpTo` in tick — one native call vs BP interpolation nodes.
### Remaining BP to Create
- `DA_StateGatingTable` (131) — 37 gating rules Data Asset
- **Data Asset instance:** `DA_StateGatingTable` — populate with 37 gating rules (C++ stub class is ready, create the asset instance)
---
## Stub Classes (UHT Resolution — 10 Systems)
These 10 classes are **forward-declared** in existing C++ headers as `TObjectPtr<>` or `TSubclassOf<>` UPROPERTY members. They must exist as C++ `UCLASS()` definitions for UHT to process the Framework module. The Blueprint child provides the actual runtime implementation.
### System 08 — BPC_HealthSystem
| | |
|---|---|
| **Header** | `Source/Framework/Public/Player/BPC_HealthSystem.h` |
| **Source** | `Source/Framework/Private/Player/BPC_HealthSystem.cpp` |
| **Parent** | `UActorComponent` |
| **Blueprint Child to Create** | `BPC_HealthSystem` — attach to player pawn, implement health logic |
Provides `CurrentHealth`, `MaxHealth`, `OnHealthChanged` dispatcher, `OnDeath` dispatcher. Referenced by `BPC_StateManager` (130) and `BPC_DamageReceptionSystem` (72).
### System 09 — BPC_StaminaSystem
| | |
|---|---|
| **Header** | `Source/Framework/Public/Player/BPC_StaminaSystem.h` |
| **Source** | `Source/Framework/Private/Player/BPC_StaminaSystem.cpp` |
| **Parent** | `UActorComponent` |
| **Blueprint Child to Create** | `BPC_StaminaSystem` — attach to player pawn |
Provides `CurrentStamina`, `MaxStamina`, `OnExhaustionStateChanged` dispatcher. Referenced by `BPC_StateManager` (130).
### System 10 — BPC_StressSystem
| | |
|---|---|
| **Header** | `Source/Framework/Public/Player/BPC_StressSystem.h` |
| **Source** | `Source/Framework/Private/Player/BPC_StressSystem.cpp` |
| **Parent** | `UActorComponent` |
| **Blueprint Child to Create** | `BPC_StressSystem` — attach to player pawn |
Provides `EStressTier` enum (Calm → Catatonic), `StressTier` property, `OnStressTierChanged` dispatcher. Referenced by `BPC_StateManager` (130).
### System 11 — BPC_MovementStateSystem
| | |
|---|---|
| **Header** | `Source/Framework/Public/Player/BPC_MovementStateSystem.h` |
| **Source** | `Source/Framework/Private/Player/BPC_MovementStateSystem.cpp` |
| **Parent** | `UActorComponent` |
| **Blueprint Child to Create** | `BPC_MovementStateSystem` — attach to player pawn |
Provides `CurrentMovementMode` (FGameplayTag), `OnMovementModeChanged` dispatcher. Referenced by `BPC_StateManager` (130).
### PC_CoreController / PS_CorePlayerState
| | APC_CoreController | APS_CorePlayerState |
|---|---|---|
| **Header** | `Public/Player/PC_CoreController.h` | `Public/Player/PS_CorePlayerState.h` |
| **Source** | `Private/Player/PC_CoreController.cpp` | `Private/Player/PS_CorePlayerState.cpp` |
| **Parent** | `APlayerController` | `APlayerState` |
| **Blueprint Child to Create** | `PC_CoreController` | `PS_CorePlayerState` |
Minimal stubs. Referenced as `TSubclassOf<>` in `GM_CoreGameMode` (05). Set your BP children as the default classes in `BP_CoreGameMode` Class Defaults.
### System 75 — BPC_HitReactionSystem
| | |
|---|---|
| **Header** | `Source/Framework/Public/Weapons/BPC_HitReactionSystem.h` |
| **Source** | `Source/Framework/Private/Weapons/BPC_HitReactionSystem.cpp` |
| **Parent** | `UActorComponent` |
| **Blueprint Child to Create** | `BPC_HitReactionSystem` — attach to player and enemy pawns |
Provides `PlayHitReaction()` stub, `FlinchThreshold`, `RagdollThreshold`. Referenced by `BPC_DamageReceptionSystem` (72).
### System 79 — BPC_ShieldDefenseSystem
| | |
|---|---|
| **Header** | `Source/Framework/Public/Weapons/BPC_ShieldDefenseSystem.h` |
| **Source** | `Source/Framework/Private/Weapons/BPC_ShieldDefenseSystem.cpp` |
| **Parent** | `UActorComponent` |
| **Blueprint Child to Create** | `BPC_ShieldDefenseSystem` — attach to player pawn |
Provides `ShieldHealth`, `MaxShieldHealth`, `BlockAngle`, `bShieldBroken`. Referenced by `BPC_DamageReceptionSystem` (72).
### System 120 — DA_EquipmentConfig
| | |
|---|---|
| **Header** | `Source/Framework/Public/Inventory/DA_EquipmentConfig.h` |
| **Source** | `Source/Framework/Private/Inventory/DA_EquipmentConfig.cpp` |
| **Parent** | `UPrimaryDataAsset` |
| **Blueprint Child** | **Not needed** — create Data Asset instances per equipment item |
Provides `FDamageTypeResistance` struct array, `Durability`, `Weight`, `GetResistance()` query. Referenced by `BPC_DamageReceptionSystem` (72).
### System 131 — DA_StateGatingTable
| | |
|---|---|
| **Header** | `Source/Framework/Public/State/DA_StateGatingTable.h` |
| **Source** | `Source/Framework/Private/State/DA_StateGatingTable.cpp` |
| **Parent** | `UPrimaryDataAsset` |
| **Blueprint Child** | **Not needed** — create one Data Asset instance with 37 gating rules |
Provides `FStateGatingRule` struct (ActionTag, BlockedByState, bIsBlocked), `IsActionGated()` query. Referenced by `BPC_StateManager` (130).
---
@@ -553,11 +658,21 @@ State->OnVitalSignChanged.AddDynamic(this, &UMyClass::OnVitalSignChanged);
| 05 | `AGM_CoreGameMode` | `AGameModeBase` | **Yes**`BP_CoreGameMode` | Set as Default GameMode |
| 06 | `AGS_CoreGameState` | `AGameStateBase` | **Yes**`BP_CoreGameState` | Set in GameMode defaults |
| 07 | `UDA_ItemData` | `UPrimaryDataAsset` | No — create per-item instances | None |
| 08 | `UBPC_HealthSystem` | `UActorComponent` | **Yes** — BP child implements logic | None |
| 09 | `UBPC_StaminaSystem` | `UActorComponent` | **Yes** — BP child implements logic | None |
| 10 | `UBPC_StressSystem` | `UActorComponent` | **Yes** — BP child implements logic | None |
| 11 | `UBPC_MovementStateSystem` | `UActorComponent` | **Yes** — BP child implements logic | None |
| 31 | `UBPC_InventorySystem` | `UActorComponent` | No — add to pawn directly | None |
| 35 | `USS_SaveManager` | `UGameInstanceSubsystem` | No — auto-created | None |
| 72 | `UBPC_DamageReceptionSystem` | `UActorComponent` | No — add to pawn/enemy | None |
| 75 | `UBPC_HitReactionSystem` | `UActorComponent` | **Yes** — BP child implements logic | None |
| 79 | `UBPC_ShieldDefenseSystem` | `UActorComponent` | **Yes** — BP child implements logic | None |
| 120 | `UDA_EquipmentConfig` | `UPrimaryDataAsset` | No — create per-item instances | None |
| 128 | `USS_EnhancedInputManager` | `UGameInstanceSubsystem` | No — auto-created | None |
| 130 | `UBPC_StateManager` | `UActorComponent` | No — add to pawn directly | None |
| 131 | `UDA_StateGatingTable` | `UPrimaryDataAsset` | No — create one Data Asset instance | None |
| — | `APC_CoreController` | `APlayerController` | **Yes**`PC_CoreController` BP child | Set in GameMode defaults |
| — | `APS_CorePlayerState` | `APlayerState` | **Yes**`PS_CorePlayerState` BP child | Set in GameMode defaults |
### What "No BP Child" Means
@@ -565,25 +680,38 @@ Systems marked **"No — add to pawn directly"** mean you place the raw C++ comp
Systems marked **"No — auto-created"** are `UGameInstanceSubsystem`s. UE creates them automatically when the GameInstance initializes. No spawning, no placement, no BeginPlay required.
Systems marked **"Yes — BP child implements logic"** are C++ stubs that exist solely for UHT resolution. The stubs provide the necessary UCLASS definition and basic properties/dispatchers. The full gameplay logic lives in the Blueprint child.
---
## Build Order (Dependency Chain)
```
1. DA_GameTagRegistry ← No dependencies (can build first)
2. I_InterfaceLibrary ← No dependencies
3. FL_GameUtilities ← Needs GI_GameFramework (forward declare ok)
4. GI_GameFramework ← Needs DA_GameTagRegistry
5. GM_CoreGameMode ← Needs GI_GameFramework
6. GS_CoreGameState ← Needs GI_GameFramework
7. DA_ItemData ← No C++ dependencies
8. BPC_InventorySystem ← Needs DA_ItemData
9. SS_SaveManager ← Needs GI_GameFramework
10. BPC_DamageReceptionSystem ← Needs DA_ItemData (EquipmentConfig)
11. SS_EnhancedInputManager ← No C++ framework deps (EnhancedInput plugin only)
12. BPC_StateManager ← Needs DA_StateGatingTable (stub)
1. DA_GameTagRegistry ← No dependencies (can build first)
2. I_InterfaceLibrary ← No dependencies
3. FL_GameUtilities ← Needs GI_GameFramework (forward declare ok)
4. GI_GameFramework ← Needs DA_GameTagRegistry
5. GM_CoreGameMode ← Needs GI_GameFramework
6. GS_CoreGameState ← Needs GI_GameFramework
7. DA_ItemData ← No C++ dependencies
8. BPC_HealthSystem (stub) ← No C++ dependencies
9. BPC_StaminaSystem (stub) ← No C++ dependencies
10. BPC_StressSystem (stub) ← No C++ dependencies
11. BPC_MovementStateSystem (stub) ← No C++ dependencies
12. PC_CoreController / PS_CorePlayerState (stubs) ← No C++ dependencies
13. DA_EquipmentConfig (stub) ← No C++ dependencies
14. BPC_InventorySystem ← Needs DA_ItemData
15. SS_SaveManager ← Needs GI_GameFramework
16. BPC_DamageReceptionSystem ← Needs DA_EquipmentConfig, DA_ItemData
17. BPC_HitReactionSystem (stub) ← No C++ dependencies
18. BPC_ShieldDefenseSystem (stub) ← No C++ dependencies
19. SS_EnhancedInputManager ← No C++ framework deps (EnhancedInput plugin only)
20. BPC_StateManager ← Needs DA_StateGatingTable, BPC_HealthSystem, BPC_StaminaSystem, BPC_StressSystem, BPC_MovementStateSystem
21. DA_StateGatingTable (stub) ← No C++ dependencies
```
**Note:** Stub classes have zero C++ dependencies and can be built in any order before the systems that reference them. Build them first to satisfy UHT forward-declaration resolution.
---
## Blueprint Assets Still Required (Not Converted to C++)
@@ -599,7 +727,7 @@ These Blueprint specs remain Blueprint-only. They have full spec files in `docs/
| 132 | `SS_AudioManager` | `BP_AudioManager` | C++ available (not in this batch) |
### Actor Components (attach to pawn)
All 80 `BPC_*` specs except the 4 converted above remain Blueprint-only. Create BP children, attach to pawn.
All `BPC_*` specs except the 4 fully converted C++ classes (InventorySystem, DamageReceptionSystem, StateManager, EnhancedInputManager) and the 8 stub classes listed above remain Blueprint-only. Create BP children, attach to pawn.
### Widgets (all 14 remain Blueprint — UMG is designed for BP)
| # | System |