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:
Lefteris Notas
2026-05-21 14:38:30 +03:00
parent a145ae9373
commit f986343325
50 changed files with 86 additions and 0 deletions

View File

@@ -0,0 +1,246 @@
// Copyright Epic Games, Inc. All Rights Reserved.
// UE5 Modular Game Framework — BPC_StateManager (130)
// Central State Authority. Single source of truth for "what can the player do right now?"
// Manages exclusive action states, upper-body overlay states, action gating,
// vital signs (heart rate), and the force-stack pattern for nested overrides.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "GameplayTagContainer.h"
#include "BPC_StateManager.generated.h"
// Forward declarations
class UDA_StateGatingTable;
class UBPC_HealthSystem;
class UBPC_StressSystem;
class UBPC_StaminaSystem;
class UBPC_MovementStateSystem;
// ============================================================================
// Delegates
// ============================================================================
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnActionStateChanged, FGameplayTag, NewState, FGameplayTag, OldState);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnOverlayStateChanged, FGameplayTag, NewOverlay, FGameplayTag, OldOverlay);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnVitalSignChanged, FGameplayTag, VitalTag, float, NewValue);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnForceStackPushed, FGameplayTag, ForceState);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnForceStackPopped, FGameplayTag, RestoredState);
/**
* Result codes for state change requests.
* Mirrors the Blueprint E_ActionRequestResult enum.
*/
UENUM(BlueprintType)
enum class EActionRequestResult : uint8
{
Granted UMETA(DisplayName = "Granted"),
Denied UMETA(DisplayName = "Denied — Gated"),
BlockedByForce UMETA(DisplayName = "Blocked — Force Stack Override"),
AlreadyActive UMETA(DisplayName = "Already Active"),
InvalidState UMETA(DisplayName = "Invalid State Tag"),
RequesterNotFound UMETA(DisplayName = "Requester Not Found"),
CooldownActive UMETA(DisplayName = "Cooldown Active"),
VitalThreshold UMETA(DisplayName = "Vital Threshold Not Met"),
};
/**
* Heart rate tier for vital sign tracking.
*/
UENUM(BlueprintType)
enum class EHeartRateTier : uint8
{
Resting UMETA(DisplayName = "Resting (60-80 BPM)"),
Elevated UMETA(DisplayName = "Elevated (80-100 BPM)"),
Stressed UMETA(DisplayName = "Stressed (100-130 BPM)"),
Panic UMETA(DisplayName = "Panic (130-160 BPM)"),
Critical UMETA(DisplayName = "Critical (160+ BPM)"),
};
/**
* BPC_StateManager — Central State Authority.
*
* Every system queries IsActionPermitted(Tag) instead of checking other systems
* directly. Gating rules are defined in DA_StateGatingTable (37 rules).
* In C++, the Chooser Table iteration is native-speed — no BP interpretive overhead.
*/
UCLASS(Blueprintable, ClassGroup = (Framework), meta = (BlueprintSpawnableComponent))
class FRAMEWORK_API UBPC_StateManager : public UActorComponent
{
GENERATED_BODY()
public:
UBPC_StateManager();
// ========================================================================
// Configuration
// ========================================================================
/** The gating rules Data Asset. Contains all 37 action rules. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Framework|Config")
TObjectPtr<UDA_StateGatingTable> GatingTable;
/** Default action state on BeginPlay. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Framework|Config")
FGameplayTag DefaultActionState;
/** Default overlay state on BeginPlay. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Framework|Config")
FGameplayTag DefaultOverlayState;
// ========================================================================
// Core Query — Hot Path
// ========================================================================
/**
* Central query: "Can the player perform this action right now?"
* Called by EVERY gameplay system per-frame. C++ makes this fast.
*/
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Framework|State")
bool IsActionPermitted(FGameplayTag ActionTag) const;
/**
* Request a state change. Returns the result code.
* Server-authoritative.
*/
UFUNCTION(BlueprintCallable, Category = "Framework|State")
EActionRequestResult RequestStateChange(FGameplayTag NewState, AActor* Requester);
// ========================================================================
// Current State (Read-Only)
// ========================================================================
/** Currently active exclusive action state (only one at a time). */
UPROPERTY(BlueprintReadOnly, Category = "Framework|State")
FGameplayTag CurrentActionState;
/** Currently active upper-body overlay state. */
UPROPERTY(BlueprintReadOnly, Category = "Framework|State")
FGameplayTag CurrentOverlayState;
// ========================================================================
// Force Stack Pattern (Death, Cutscenes, Void Space)
// ========================================================================
/**
* Pushes a forced state onto the stack. Overrides all gating.
* Example: death overrides everything.
*/
UFUNCTION(BlueprintCallable, Category = "Framework|State")
void ForceStateChange(FGameplayTag ForceState, FString Reason);
/**
* Pops the top forced state and restores the previous state.
* Example: respawn restores the pre-death state.
*/
UFUNCTION(BlueprintCallable, Category = "Framework|State")
void RestorePreviousState();
/** Returns the number of states currently on the force stack. */
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Framework|State")
int32 GetForceStackDepth() const { return ForceStack.Num(); }
// ========================================================================
// Vital Signs — Heart Rate
// ========================================================================
/** Current heart rate in BPM (smoothed). */
UPROPERTY(BlueprintReadOnly, Category = "Framework|Vitals")
float HeartRateBPM = 70.0f;
/** Current heart rate tier. */
UPROPERTY(BlueprintReadOnly, Category = "Framework|Vitals")
EHeartRateTier HeartRateTier = EHeartRateTier::Resting;
/** Target heart rate (set by stress, stamina, combat). Interpolated toward each tick. */
UPROPERTY(BlueprintReadOnly, Category = "Framework|Vitals")
float TargetHeartRate = 70.0f;
/** Smoothing speed for heart rate interpolation. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Vitals")
float HeartRateSmoothSpeed = 2.0f;
// ========================================================================
// Event Dispatchers
// ========================================================================
UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
FOnActionStateChanged OnActionStateChanged;
UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
FOnOverlayStateChanged OnOverlayStateChanged;
UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
FOnVitalSignChanged OnVitalSignChanged;
UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
FOnForceStackPushed OnForceStackPushed;
UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
FOnForceStackPopped OnForceStackPopped;
// ========================================================================
// Overrides
// ========================================================================
virtual void BeginPlay() override;
virtual void TickComponent(float DeltaTime, ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction) override;
protected:
// ========================================================================
// Internal State
// ========================================================================
/** Force stack — array of (State, Reason) pairs. Most recent is active. */
struct FForceStackEntry
{
FGameplayTag State;
FString Reason;
};
TArray<FForceStackEntry> ForceStack;
/** Previous action state before force override (for restore). */
FGameplayTag PreForceActionState;
/** Previous overlay state before force override (for restore). */
FGameplayTag PreForceOverlayState;
// ========================================================================
// Gating Logic
// ========================================================================
/** Check gating rules for a tag against current state. */
bool EvaluateGatingRules(FGameplayTag ActionTag) const;
/** Check if any force stack entry blocks this action. */
bool IsBlockedByForceStack(FGameplayTag ActionTag) const;
// ========================================================================
// Vital Sign Calculation
// ========================================================================
/** Recalculates target heart rate based on stress tier + stamina exhaustion + combat. */
void RecalculateTargetHeartRate();
/** Determines heart rate tier from current BPM. */
static EHeartRateTier GetHeartRateTier(float BPM);
// ========================================================================
// Binding References (cached in BeginPlay)
// ========================================================================
UPROPERTY()
TObjectPtr<UBPC_HealthSystem> CachedHealthSystem;
UPROPERTY()
TObjectPtr<UBPC_StressSystem> CachedStressSystem;
UPROPERTY()
TObjectPtr<UBPC_StaminaSystem> CachedStaminaSystem;
UPROPERTY()
TObjectPtr<UBPC_MovementStateSystem> CachedMovementSystem;
};