// Copyright Epic Games, Inc. All Rights Reserved. // UE5 Modular Game Framework — BPC_DamageReceptionSystem (72) // Damage reception, resistance calculation, and damage application. // Called potentially dozens of times per combat frame — C++ performance critical. #pragma once #include "CoreMinimal.h" #include "Components/ActorComponent.h" #include "GameplayTagContainer.h" #include "BPC_DamageReceptionSystem.generated.h" // Forward declarations class UDA_EquipmentConfig; class UBPC_HealthSystem; class UBPC_ShieldDefenseSystem; class UBPC_HitReactionSystem; // Delegates DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FOnDamageReceived, float, RawDamage, float, FinalDamage, AActor*, DamageCauser, FGameplayTag, DamageType, FVector, HitLocation); DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnDamageResisted, float, DamageResisted, FGameplayTag, ResistanceType, FString, Reason); DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnStaggered, AActor*, StaggerCauser, float, StaggerForce); DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnKnockedDown, AActor*, KnockdownCauser, float, KnockdownForce); /** * Damage modifier for a specific damage type. */ USTRUCT(BlueprintType) struct FRAMEWORK_API FDamageModifier { GENERATED_BODY() /** The damage type this modifier applies to. */ UPROPERTY(EditAnywhere, BlueprintReadWrite) FGameplayTag DamageType; /** Multiplier applied to incoming damage of this type. 0.5 = half damage, 2.0 = double. */ UPROPERTY(EditAnywhere, BlueprintReadWrite) float Multiplier = 1.0f; /** If true, this is a flat reduction (subtract after multiplier). */ UPROPERTY(EditAnywhere, BlueprintReadWrite) bool bFlatReduction = false; /** Flat damage reduction amount (only used if bFlatReduction is true). */ UPROPERTY(EditAnywhere, BlueprintReadWrite) float FlatReduction = 0.0f; }; /** * BPC_DamageReceptionSystem — Damage Reception & Resistance. * * Processes incoming damage: calculates resistance, applies armor/shield modifiers, * triggers hit reactions (stagger, knockdown), and routes final damage to the * health system. In C++, the damage pipeline is native-speed vectorized math. */ UCLASS(Blueprintable, ClassGroup = (Framework), meta = (BlueprintSpawnableComponent)) class FRAMEWORK_API UBPC_DamageReceptionSystem : public UActorComponent { GENERATED_BODY() public: UBPC_DamageReceptionSystem(); // ======================================================================== // Configuration // ======================================================================== /** Equipment config for armor/damage modifiers. */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Framework|Config") TObjectPtr EquipmentConfig; /** Base damage resistance (0.0 = no resistance, 1.0 = immune). */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Combat") float BaseResistance = 0.0f; /** Damage multipliers per damage type. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Combat") TArray DamageModifiers; // ======================================================================== // Damage Calculation — Hot Path // ======================================================================== /** * Calculate and apply damage. * Full pipeline: raw damage → calculate resistance → apply armor → apply shield → apply health. * Returns actual damage dealt. */ UFUNCTION(BlueprintCallable, Category = "Framework|Combat") float ApplyDamage(float RawDamage, AActor* DamageCauser, FGameplayTag DamageType, FVector HitLocation, FVector HitDirection); /** * Calculate effective resistance for a damage type. * Used by UI/preview systems to show expected damage. */ UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Framework|Combat") float CalculateResistance(FGameplayTag DamageType) const; /** * Get the damage modifier for a specific damage type. */ UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Framework|Combat") float GetDamageMultiplier(FGameplayTag DamageType) const; // ======================================================================== // Hit Reaction // ======================================================================== /** Damage threshold to trigger a stagger reaction. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Combat|Reactions") float StaggerThreshold = 20.0f; /** Damage threshold to trigger a knockdown. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Framework|Combat|Reactions") float KnockdownThreshold = 50.0f; // ======================================================================== // Event Dispatchers // ======================================================================== UPROPERTY(BlueprintAssignable, Category = "Framework|Events") FOnDamageReceived OnDamageReceived; UPROPERTY(BlueprintAssignable, Category = "Framework|Events") FOnDamageResisted OnDamageResisted; UPROPERTY(BlueprintAssignable, Category = "Framework|Events") FOnStaggered OnStaggered; UPROPERTY(BlueprintAssignable, Category = "Framework|Events") FOnKnockedDown OnKnockedDown; protected: /** Triggers hit reaction based on final damage amount. */ void EvaluateHitReaction(float FinalDamage, AActor* DamageCauser, FVector HitDirection); /** Cached references to sibling components. */ UPROPERTY() TObjectPtr CachedHealthSystem; UPROPERTY() TObjectPtr CachedShieldSystem; UPROPERTY() TObjectPtr CachedHitReactionSystem; };