diff --git a/Source/vampires/HealthComponent.cpp b/Source/vampires/HealthComponent.cpp new file mode 100644 index 0000000..93a8d8e --- /dev/null +++ b/Source/vampires/HealthComponent.cpp @@ -0,0 +1,108 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "HealthComponent.h" + +// Sets default values for this component's properties +UHealthComponent::UHealthComponent() +{ + // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features + // off to improve performance if you don't need them. + PrimaryComponentTick.bCanEverTick = false; + + // ... +} + +void UHealthComponent::TakeDamage(AActor* damagedActor, float damage, const UDamageType* damageType, + AController* instigatedBy, AActor* damageCauser) +{ + if (damagedActor == nullptr || IsDead || !CanDamage) + { + return; + } + + CurrentHealth -= damage; + + OnDamaged.ExecuteIfBound({damagedActor, damage, damageType, instigatedBy, damageCauser}); + + if (CurrentHealth <= 0.0f) + { + IsDead = true; + OnDeath.ExecuteIfBound({damagedActor, damage, damageType, instigatedBy, damageCauser}); + } +} + +void UHealthComponent::IncrementHealth(float value) +{ + CurrentHealth += value; + + if (CurrentHealth > MaxHealth) + { + CurrentHealth = MaxHealth; + } +} + +float UHealthComponent::GetMaxHealth() +{ + return MaxHealth; +} + +void UHealthComponent::SetMaxHealth(float value) +{ + MaxHealth = value; +} + +float UHealthComponent::GetCurrentHealth() +{ + return CurrentHealth; +} + +void UHealthComponent::SetCurrentHealth(float value) +{ + CurrentHealth = value; + + if (CurrentHealth > MaxHealth) + { + CurrentHealth = MaxHealth; + } +} + +void UHealthComponent::ResetHealth() +{ + CurrentHealth = MaxHealth; +} + +void UHealthComponent::RecoverHealth(float value) +{ + // TODO: We might want to add some extra checking here + IncrementHealth(value); +} + +bool UHealthComponent::GetIsDead() +{ + return IsDead; +} + +void UHealthComponent::SetIsDead(bool isDead) +{ + IsDead = isDead; +} + +bool UHealthComponent::GetCanDamage() +{ + return CanDamage; +} + +void UHealthComponent::SetCanDamage(bool canDamage) +{ + CanDamage = canDamage; +} + + +// Called when the game starts +void UHealthComponent::BeginPlay() +{ + Super::BeginPlay(); + + ResetHealth(); +} \ No newline at end of file diff --git a/Source/vampires/HealthComponent.h b/Source/vampires/HealthComponent.h new file mode 100644 index 0000000..ada866d --- /dev/null +++ b/Source/vampires/HealthComponent.h @@ -0,0 +1,98 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Components/ActorComponent.h" +#include "HealthComponent.generated.h" + +USTRUCT() +struct FDamageInfo +{ + GENERATED_BODY() + + UPROPERTY() + AActor* DamagedActor; + + UPROPERTY() + float Damage; + + UPROPERTY() + const UDamageType* DamageType; + + UPROPERTY() + AController* InstigatedBy; + + UPROPERTY() + AActor* DamageCauser; +}; + +DECLARE_DELEGATE_OneParam(FOnDamageDelegate, FDamageInfo) +DECLARE_DELEGATE_OneParam(FOnDeathDelegate, FDamageInfo) + +UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) +class VAMPIRES_API UHealthComponent : public UActorComponent +{ + GENERATED_BODY() + +public: + FOnDamageDelegate OnDamaged; + FOnDeathDelegate OnDeath; + +protected: + UPROPERTY(EditDefaultsOnly) + float MaxHealth = 100.f; + + UPROPERTY(VisibleAnywhere) + float CurrentHealth; + + bool IsDead = false; + + bool CanDamage = true; + +public: + // Sets default values for this component's properties + UHealthComponent(); + + UFUNCTION() + virtual void TakeDamage(AActor* damagedActor, float damage, const UDamageType* damageType, + AController* instigatedBy, + AActor* damageCauser); + + UFUNCTION() + void IncrementHealth(float value); + + UFUNCTION() + float GetMaxHealth(); + + UFUNCTION() + void SetMaxHealth(float value); + + UFUNCTION() + float GetCurrentHealth(); + + UFUNCTION() + void SetCurrentHealth(float value); + + UFUNCTION() + void ResetHealth(); + + UFUNCTION() + void RecoverHealth(float healing); + + UFUNCTION() + bool GetIsDead(); + + UFUNCTION() + void SetIsDead(bool isDead); + + UFUNCTION() + bool GetCanDamage(); + + UFUNCTION() + void SetCanDamage(bool canDamage); + +protected: + // Called when the game starts + virtual void BeginPlay() override; +}; diff --git a/Source/vampires/PlayerCharacter.cpp b/Source/vampires/PlayerCharacter.cpp index 5e84e84..62f3e91 100644 --- a/Source/vampires/PlayerCharacter.cpp +++ b/Source/vampires/PlayerCharacter.cpp @@ -26,6 +26,9 @@ APlayerCharacter::APlayerCharacter() CameraComponent->bUsePawnControlRotation = false; CameraComponent->SetProjectionMode(ECameraProjectionMode::Type::Orthographic); CameraComponent->SetOrthoWidth(4000.0f); + + // Create Health Component + HealthComponent = CreateDefaultSubobject(TEXT("Health Component")); } void APlayerCharacter::BeginPlay() diff --git a/Source/vampires/PlayerCharacter.h b/Source/vampires/PlayerCharacter.h index 50367ee..7c40b8e 100644 --- a/Source/vampires/PlayerCharacter.h +++ b/Source/vampires/PlayerCharacter.h @@ -3,6 +3,7 @@ #pragma once #include "CoreMinimal.h" +#include "HealthComponent.h" #include "VampireCharacter.h" #include "Camera/CameraComponent.h" #include "GameFramework/SpringArmComponent.h" @@ -33,6 +34,9 @@ public: UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) UInputAction* MovementAction; + UPROPERTY() + UHealthComponent* HealthComponent; + public: APlayerCharacter();