95 lines
3.2 KiB
C++
95 lines
3.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "LyraDamageLogDebuggerComponent.h"
|
|
#include "Messages/LyraVerbMessage.h"
|
|
#include "NativeGameplayTags.h"
|
|
#include "LyraLogChannels.h"
|
|
|
|
UE_DECLARE_GAMEPLAY_TAG_EXTERN(TAG_Lyra_Damage_Message);
|
|
|
|
ULyraDamageLogDebuggerComponent::ULyraDamageLogDebuggerComponent(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
PrimaryComponentTick.bCanEverTick = true;
|
|
PrimaryComponentTick.SetTickFunctionEnable(true);
|
|
}
|
|
|
|
void ULyraDamageLogDebuggerComponent::BeginPlay()
|
|
{
|
|
Super::BeginPlay();
|
|
|
|
UGameplayMessageSubsystem& MessageSubsystem = UGameplayMessageSubsystem::Get(this);
|
|
ListenerHandle = MessageSubsystem.RegisterListener(TAG_Lyra_Damage_Message, this, &ThisClass::OnDamageMessage);
|
|
}
|
|
|
|
void ULyraDamageLogDebuggerComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
|
{
|
|
UGameplayMessageSubsystem& MessageSubsystem = UGameplayMessageSubsystem::Get(this);
|
|
MessageSubsystem.UnregisterListener(ListenerHandle);
|
|
|
|
Super::EndPlay(EndPlayReason);
|
|
}
|
|
|
|
void ULyraDamageLogDebuggerComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
|
{
|
|
const double TimeSinceDamage = GetWorld()->GetTimeSeconds() - LastDamageEntryTime;
|
|
if ((TimeSinceDamage >= SecondsBetweenDamageBeforeLogging) && (DamageLog.Num() > 0))
|
|
{
|
|
TArray<FFrameDamageEntry> Entries;
|
|
DamageLog.GenerateValueArray(/*out*/ Entries);
|
|
DamageLog.Reset();
|
|
|
|
Entries.Sort([](const FFrameDamageEntry& A, const FFrameDamageEntry& B) { return A.TimeOfFirstHit < B.TimeOfFirstHit; });
|
|
|
|
double TotalDamage = 0.0;
|
|
int32 NumImpacts = 0;
|
|
int32 NumFrames = Entries.Num();
|
|
double MinInterval = TNumericLimits<double>::Max();
|
|
double MaxInterval = -TNumericLimits<double>::Max();
|
|
double TotalInterval = 0.0;
|
|
|
|
for (int32 i = 0; i < Entries.Num(); ++i)
|
|
{
|
|
FFrameDamageEntry& EntryA = Entries[i];
|
|
NumImpacts += EntryA.NumImpacts;
|
|
TotalDamage += EntryA.SumDamage;
|
|
|
|
if (i + 1 < Entries.Num())
|
|
{
|
|
FFrameDamageEntry& EntryB = Entries[i+1];
|
|
|
|
const double TimeGap = EntryB.TimeOfFirstHit - EntryA.TimeOfFirstHit;
|
|
MinInterval = FMath::Min(MinInterval, TimeGap);
|
|
MaxInterval = FMath::Max(MaxInterval, TimeGap);
|
|
TotalInterval += TimeGap;
|
|
}
|
|
}
|
|
|
|
UE_LOG(LogLyra, Warning, TEXT("%d impacts in %d distinct frames over %.2f seconds did %.2f damage"),
|
|
NumImpacts, NumFrames, TotalInterval, TotalDamage);
|
|
if (TotalInterval > 0.0)
|
|
{
|
|
UE_LOG(LogLyra, Warning, TEXT("Interval ranged from %.1f ms to %.1f ms (avg %.1f ms)"),
|
|
MinInterval * 1000.0, MaxInterval * 1000.0, (MaxInterval + MinInterval) / 2.0 * 1000.0);
|
|
UE_LOG(LogLyra, Warning, TEXT("DPS %.2f"), TotalDamage / TotalInterval);
|
|
}
|
|
UE_LOG(LogLyra, Warning, TEXT("\n"));
|
|
}
|
|
}
|
|
|
|
void ULyraDamageLogDebuggerComponent::OnDamageMessage(FGameplayTag Channel, const FLyraVerbMessage& Payload)
|
|
{
|
|
if (Payload.Target == GetOwner())
|
|
{
|
|
FFrameDamageEntry& LogEntry = DamageLog.FindOrAdd(GFrameCounter);
|
|
|
|
if (LogEntry.TimeOfFirstHit == 0.0)
|
|
{
|
|
LogEntry.TimeOfFirstHit = GetWorld()->GetTimeSeconds();
|
|
LastDamageEntryTime = LogEntry.TimeOfFirstHit;
|
|
}
|
|
LogEntry.NumImpacts++;
|
|
LogEntry.SumDamage += -Payload.Magnitude;
|
|
}
|
|
}
|