D1/Source/D1/Components/StatsComponent.cpp

164 lines
4.1 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "Components/StatsComponent.h"
#include "Components/StateManagerComponent.h"
#include "Math/UnrealMathUtility.h"
#include "Kismet/KismetSystemLibrary.h"
// Sets default values for this component's properties
UStatsComponent::UStatsComponent()
{
// 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 = true;
// ...
StaminaRegenRate = 2.f;
}
// Called when the game starts
void UStatsComponent::BeginPlay()
{
Super::BeginPlay();
// ...
}
// Called every frame
void UStatsComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// ...
}
void UStatsComponent::InitializeStats()
{
for (auto& stat : BaseStats)
SetCurrentStatValue(stat.Key, stat.Value.BaseValue);
}
void UStatsComponent::SetCurrentStatValue(EStats stat, float value)
{
CurrentStats.Add(stat, value);
OnCurrentStatValueUpdated.Broadcast(stat, value);
}
float UStatsComponent::GetCurrentStatValue(EStats stat)
{
return *CurrentStats.Find(stat);
}
void UStatsComponent::ModifyCurrentStatValue(EStats stat, float value, bool bShouldRegenerate)
{
if (FMath::IsNearlyEqual(value, 0.f))
return;
float currentValue = GetCurrentStatValue(stat) + value;
currentValue = FMath::Clamp(currentValue, 0.f, currentValue);
SetCurrentStatValue(stat, currentValue);
if (bShouldRegenerate)
StartRegen(stat);
}
void UStatsComponent::TakeDamageOnStat(float inDamage)
{
float calDamage;
float armor = GetCurrentStatValue(EStats::Armor);
calDamage = (inDamage / (inDamage + armor)) * inDamage;
calDamage = FMath::Clamp(calDamage, 0.f, calDamage);
ModifyCurrentStatValue(EStats::Health, -calDamage, false);
FString debugStr = FString::Printf(TEXT("Damage : %f"), calDamage);
GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Red, debugStr);
if (GetCurrentStatValue(EStats::Health) <= 0.f)
GetOwner()->GetComponentByClass<UStateManagerComponent>()->SetCurrentState(ECharacterState::Dead);
}
void UStatsComponent::StartRegen(EStats statType)
{
switch (statType)
{
case EStats::None:
break;
case EStats::Health:
break;
case EStats::Stamina:
{
if (GEngine)
{
UWorld* World = GEngine->GetWorldFromContextObjectChecked(this);
if (World)
{
World->GetTimerManager().ClearTimer(RegenTimerHandle);
World->GetTimerManager().SetTimer(AfterRegenTimerHandle, this, &UStatsComponent::AfterDelayExecuteRegenStamina, 1.5f, false);
}
}
}
break;
case EStats::Armor:
break;
default:
break;
}
}
void UStatsComponent::AfterDelayExecuteRegenStamina()
{
if (GEngine)
{
UWorld* World = GEngine->GetWorldFromContextObjectChecked(this);
if (World)
{
World->GetTimerManager().ClearTimer(RegenTimerHandle);
World->GetTimerManager().SetTimer(RegenTimerHandle, this, &UStatsComponent::RegenerateStamina, 0.1f, true);
}
}
}
void UStatsComponent::RegenerateStamina()
{
float curStamina = StaminaRegenRate + GetCurrentStatValue(EStats::Stamina);
curStamina = FMath::Clamp(curStamina, 0.f, GetMaxStatValue(EStats::Stamina));
SetCurrentStatValue(EStats::Stamina, curStamina);
//FString debugStr = FString::Printf(TEXT("Stamina %f"), curStamina);
//GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Blue, debugStr);
if (GetCurrentStatValue(EStats::Stamina) >= GetMaxStatValue(EStats::Stamina))
{
UWorld* World = GEngine->GetWorldFromContextObjectChecked(this);
if (World)
World->GetTimerManager().ClearTimer(RegenTimerHandle);
}
}
float UStatsComponent::GetBaseStatValue(EStats stat)
{
return BaseStats.Find(stat)->BaseValue;
}
float UStatsComponent::GetMaxStatValue(EStats stat)
{
return BaseStats.Find(stat)->MaxValue;
}
void UStatsComponent::SetBaseStatValue(EStats stat, float value)
{
if (BaseStats.Contains(stat))
BaseStats.Find(stat)->BaseValue = value;
}
void UStatsComponent::SetMaxStatValue(EStats stat, float value)
{
if (BaseStats.Contains(stat))
BaseStats.Find(stat)->MaxValue = value;
}