Bugfix Expiry Timers Not Getting Invalidated

This commit is contained in:
Philip W 2023-02-25 01:25:32 +00:00
parent 939d1e8b92
commit 2f47693608
7 changed files with 46 additions and 21 deletions

BIN
Content/Dialogue/NPCTest.uasset (Stored with Git LFS)

Binary file not shown.

View File

@ -3,10 +3,27 @@
#include "StatusEffect.h" #include "StatusEffect.h"
void UStatusEffect::Invoke(AActor* Character) #include "StatusSystem.h"
#include "Kismet/GameplayStatics.h"
void UStatusEffect::Invoke(AActor* Character, float TimeOfExpiry)
{ {
GetWorld()->GetTimerManager().SetTimer(ExpiryTimerHandle, [this, Character, TimeOfExpiry] { CheckForExpiry(TimeOfExpiry, Character); }, 1, true, 0);
} }
void UStatusEffect::OnExpiry(AActor* Character) void UStatusEffect::OnExpiry(AActor* Character)
{ {
GetWorld()->GetTimerManager().ClearTimer(ExpiryTimerHandle);
UStatusSystem* StatusSystem = Cast<UStatusSystem>(Character->GetComponentByClass(UStatusSystem::StaticClass()));
if (StatusSystem->GetActiveStatusEffect(this).StatusIcon == nullptr) return;
StatusSystem->GetActiveStatusEffect(this).StatusIcon->RemoveFromParent();
StatusSystem->RemoveStatusEffect(this);
}
void UStatusEffect::CheckForExpiry(const float TimeOfExpiry, AActor* Character)
{
if (TimeOfExpiry <= UGameplayStatics::GetRealTimeSeconds(GetWorld()))
{
OnExpiry(Character);
}
} }

View File

@ -25,8 +25,14 @@ public:
UTexture2D* Icon; UTexture2D* Icon;
UFUNCTION() UFUNCTION()
virtual void Invoke(AActor* Character); virtual void Invoke(AActor* Character, float TimeOfExpiry);
UFUNCTION() UFUNCTION()
virtual void OnExpiry(AActor* Character); virtual void OnExpiry(AActor* Character);
protected:
UPROPERTY()
FTimerHandle ExpiryTimerHandle;
UFUNCTION()
void CheckForExpiry(float TimeOfExpiry, AActor* Character);
}; };

View File

@ -17,14 +17,14 @@ void UHealOverTime::Heal(AActor* Character, const float Amount) const
} }
} }
void UHealOverTime::Invoke(AActor* Character) void UHealOverTime::Invoke(AActor* Character, float TimeOfExpiry)
{ {
Super::Invoke(Character); Super::Invoke(Character, TimeOfExpiry);
GetWorld()->GetTimerManager().SetTimer(HealTimerHandle, [Character, this] { Heal(Character, 1); }, 1, true, 0); GetWorld()->GetTimerManager().SetTimer(HealTimerHandle, [this, Character] { Heal(Character, 1); }, 1, true, 0);
} }
void UHealOverTime::OnExpiry(AActor* Character) void UHealOverTime::OnExpiry(AActor* Character)
{ {
GetWorld()->GetTimerManager().ClearTimer(HealTimerHandle);
Super::OnExpiry(Character); Super::OnExpiry(Character);
HealTimerHandle.Invalidate();
} }

View File

@ -20,6 +20,6 @@ protected:
public: public:
FTimerHandle HealTimerHandle; FTimerHandle HealTimerHandle;
virtual void Invoke(AActor* Character) override; virtual void Invoke(AActor* Character, float TimeOfExpiry) override;
virtual void OnExpiry(AActor* Character) override; virtual void OnExpiry(AActor* Character) override;
}; };

View File

@ -36,17 +36,6 @@ void UStatusSystem::BeginPlay()
void UStatusSystem::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) void UStatusSystem::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{ {
Super::TickComponent(DeltaTime, TickType, ThisTickFunction); Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
for (FActiveStatusEffect ActiveStatusEffect : ActiveStatusEffects)
{
UE_LOG(LogTemp, Warning, TEXT("TimeTillExpiry: %f"), UGameplayStatics::GetRealTimeSeconds(GetWorld()) - ActiveStatusEffect.TimeTillExpiry);
if (ActiveStatusEffect.TimeTillExpiry >= UGameplayStatics::GetRealTimeSeconds(GetWorld()))
{
ActiveStatusEffect.StatusEffect->OnExpiry(GetOwner());
ActiveStatusEffects.Remove(ActiveStatusEffect);
ActiveStatusEffect.StatusIcon->RemoveFromParent();
}
}
} }
void UStatusSystem::AddStatusEffect(UStatusEffect* StatusEffect, const float DurationMultiplier) void UStatusSystem::AddStatusEffect(UStatusEffect* StatusEffect, const float DurationMultiplier)
@ -59,7 +48,7 @@ void UStatusSystem::AddStatusEffect(UStatusEffect* StatusEffect, const float Dur
UImage* StatusIconImage = Cast<UImage>(NewStatusEffect.StatusIcon->GetWidgetFromName(TEXT("StatusIconImage"))); UImage* StatusIconImage = Cast<UImage>(NewStatusEffect.StatusIcon->GetWidgetFromName(TEXT("StatusIconImage")));
StatusIconImage->SetBrushFromTexture(StatusEffect->Icon); StatusIconImage->SetBrushFromTexture(StatusEffect->Icon);
StatusIconsBox->AddChild(NewStatusEffect.StatusIcon); StatusIconsBox->AddChild(NewStatusEffect.StatusIcon);
NewStatusEffect.StatusEffect->Invoke(GetOwner()); NewStatusEffect.StatusEffect->Invoke(GetOwner(), NewStatusEffect.TimeTillExpiry);
ActiveStatusEffects.Add(NewStatusEffect); ActiveStatusEffects.Add(NewStatusEffect);
} }
@ -75,3 +64,13 @@ void UStatusSystem::RemoveStatusEffect(UStatusEffect* StatusEffect)
UE_LOG(LogTemp, Warning, TEXT("StatusEffect not found in ActiveStatusEffects")); UE_LOG(LogTemp, Warning, TEXT("StatusEffect not found in ActiveStatusEffects"));
} }
} }
FActiveStatusEffect UStatusSystem::GetActiveStatusEffect(UStatusEffect* StatusEffect)
{
if (ActiveStatusEffects.Contains(FActiveStatusEffect{0, 0, StatusEffect, nullptr}))
{
return ActiveStatusEffects[ActiveStatusEffects.Find(FActiveStatusEffect{0, 0, StatusEffect, nullptr})];
}
UE_LOG(LogTemp, Warning, TEXT("StatusEffect not found in ActiveStatusEffects"));
return FActiveStatusEffect();
}

View File

@ -65,4 +65,7 @@ public:
UFUNCTION() UFUNCTION()
void RemoveStatusEffect(UStatusEffect* StatusEffect); void RemoveStatusEffect(UStatusEffect* StatusEffect);
UFUNCTION()
FActiveStatusEffect GetActiveStatusEffect(UStatusEffect* StatusEffect);
}; };