Files

151 lines
5.5 KiB
C++

// 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 PG_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 PG_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<UDA_EquipmentConfig> 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<FDamageModifier> 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<UBPC_HealthSystem> CachedHealthSystem;
UPROPERTY()
TObjectPtr<UBPC_ShieldDefenseSystem> CachedShieldSystem;
UPROPERTY()
TObjectPtr<UBPC_HitReactionSystem> CachedHitReactionSystem;
};