Make the damage window more generic

The goal was to handle gameplay event other than damage, such as heals. Renamed it to metric.
This commit is contained in:
Arnaud Jamin
2023-10-03 01:00:06 -04:00
parent 82dca91a89
commit 60b1578e96
11 changed files with 434 additions and 415 deletions
@@ -9,11 +9,6 @@
#include "imgui.h"
#include "imgui_internal.h"
//--------------------------------------------------------------------------------------------------------------------------
UCogAbilityWindow_Cheats::UCogAbilityWindow_Cheats()
{
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Cheats::RenderContent()
{
@@ -1,271 +0,0 @@
#include "CogAbilityWindow_Damages.h"
#include "CogInterfaceDamageActor.h"
#include "CogImguiHelper.h"
#include "imgui.h"
//--------------------------------------------------------------------------------------------------------------------------
float FCogDamageStats::MaxDurationSetting = 0.0f;
float FCogDamageStats::RestartDelaySetting = 5.0f;
//--------------------------------------------------------------------------------------------------------------------------
void FCogDamageInstance::Restart()
{
DamageLast = 0.0f;
DamageMin = 0.0f;
DamageMax = 0.0f;
DamagePerSecond = 0.0f;
DamagePerFrame = 0.0f;
DamageTotal = 0.0f;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDamageInstance::AddDamage(const float Damage)
{
DamageLast = Damage;
DamageMin = DamageMin == 0.0f ? Damage : FMath::Min(DamageMin, Damage);
DamageMax = FMath::Max(DamageMax, Damage);
DamagePerFrame += Damage;
DamageTotal += Damage;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDamageInstance::UpdateDamagePerSecond(const float Duration)
{
DamagePerSecond = Duration > 1.0f ? DamageTotal / Duration : DamageTotal;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDamageStats::Restart()
{
Count = 0;
Crits = 0;
TotalCritChances = 0.0f;
IsInProgress = false;
Timer = 0.0f;
RestartTimer = 0.0f;
Mitigated.Restart();
Unmitigated.Restart();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDamageStats::AddDamage(const float InMitigatedDamage, const float InUnmitigatedDamage, const bool bIsCrit)
{
// If the max duration is reached, stop adding
if (MaxDuration != 0 && Timer >= MaxDuration)
{
return;
}
IsInProgress = true;
Count++;
Crits += bIsCrit ? 1 : 0;
MaxDuration = MaxDurationSetting;
Mitigated.AddDamage(InMitigatedDamage);
Unmitigated.AddDamage(InUnmitigatedDamage);
Mitigated.UpdateDamagePerSecond(Timer);
Unmitigated.UpdateDamagePerSecond(Timer);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDamageStats::Tick(const float DeltaSeconds)
{
if (IsInProgress)
{
// If the max duration is reached, stop increasing time.
if (MaxDuration <= 0 || Timer < MaxDuration)
{
Timer += DeltaSeconds;
}
else
{
IsInProgress = false;
Timer = MaxDuration;
Mitigated.UpdateDamagePerSecond(Timer);
Unmitigated.UpdateDamagePerSecond(Timer);
}
}
if (RestartDelaySetting > 0.0f)
{
if (Unmitigated.DamagePerFrame == 0.0f)
{
RestartTimer += DeltaSeconds;
if (RestartTimer > RestartDelaySetting)
{
Restart();
}
}
else
{
RestartTimer = 0.0f;
}
}
Mitigated.DamagePerFrame = 0.0f;
Unmitigated.DamagePerFrame = 0.0f;
}
//--------------------------------------------------------------------------------------------------------------------------
static void DrawRow(const char* Title, float MitigatedValue, float UnmitigatedValue, ImVec4 Color)
{
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Selectable(Title, false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap | ImGuiSelectableFlags_AllowDoubleClick);
ImGui::TableNextColumn();
ImGui::TextColored(Color, "%.1f", MitigatedValue);
ImGui::TableNextColumn();
ImGui::Text("%.1f", UnmitigatedValue);
ImGui::TableNextColumn();
ImGui::Text("%.0f%%", UnmitigatedValue <= 0 ? 0.0 : 100.0f * (1.0f - (MitigatedValue / UnmitigatedValue)));
}
//--------------------------------------------------------------------------------------------------------------------------
static void DrawDamages(FCogDamageStats& Damage)
{
ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(150, 150, 150, 60));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, IM_COL32(150, 150, 150, 80));
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, IM_COL32(150, 150, 150, 120));
ImGui::PushStyleColor(ImGuiCol_CheckMark, IM_COL32(150, 150, 150, 200));
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, IM_COL32(120, 120, 120, 255));
if (ImGui::BeginTable("Damages", 4, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_RowBg))
{
ImGui::TableSetupColumn("");
ImGui::TableSetupColumn("Mitigated");
ImGui::TableSetupColumn("Unmitigated");
ImGui::TableSetupColumn("Mitigation %");
ImGui::TableHeadersRow();
DrawRow("Damage Per Second", Damage.Mitigated.DamagePerSecond, Damage.Unmitigated.DamagePerSecond, ImVec4(1.0f, 1.0, 0.0f, 1.0f));
DrawRow("Damage Total", Damage.Mitigated.DamageTotal, Damage.Unmitigated.DamageTotal, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
DrawRow("Damage Last", Damage.Mitigated.DamageLast, Damage.Unmitigated.DamageLast, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
DrawRow("Damage Min", Damage.Mitigated.DamageMin, Damage.Unmitigated.DamageMin, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
DrawRow("Damage Min", Damage.Mitigated.DamageMax, Damage.Unmitigated.DamageMax, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
ImGui::EndTable();
}
ImGui::Text("Timer");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
ImGui::Text("%0.2f", Damage.Timer);
ImGui::Text("Crits");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
FCogWindowWidgets::ProgressBarCentered(Damage.Count == 0 ? 0.0f : Damage.Crits / (float)Damage.Count, ImVec2(-1, 0), TCHAR_TO_ANSI(*FString::Printf(TEXT("%d / %d"), Damage.Crits, Damage.Count)));
if (FCogDamageStats::MaxDurationSetting > 0)
{
ImGui::Text("Timer");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
FCogWindowWidgets::ProgressBarCentered(Damage.Timer / Damage.MaxDuration, ImVec2(-1, 0), TCHAR_TO_ANSI(*FString::Printf(TEXT("%0.1f / %0.1f"), Damage.Timer, Damage.MaxDuration)));
}
ImGui::Spacing();
if (ImGui::Button("Restart"))
{
Damage.Restart();
}
ImGui::PopStyleColor(5);
ImGui::Spacing();
ImGui::Spacing();
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Damages::RenderContent()
{
Super::RenderContent();
AActor* Selection = GetSelection();
if (Selection == nullptr)
{
return;
}
if (ImGui::CollapsingHeader("Damage Dealt"))
{
ImGui::PushID("Damage Dealt");
DrawDamages(DamageDealtStats);
ImGui::PopID();
}
if (ImGui::CollapsingHeader("Damage Received"))
{
ImGui::PushID("Damage Received");
DrawDamages(DamageReceivedStats);
ImGui::PopID();
}
if (ImGui::CollapsingHeader("Settings"))
{
ImGui::PushItemWidth(-1);
ImGui::Text("Auto Restart");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
bool AutoRestart = FCogDamageStats::RestartDelaySetting > 0;
if (ImGui::Checkbox("##Auto Restart", &AutoRestart))
{
FCogDamageStats::RestartDelaySetting = AutoRestart ? 5.0f : 0.0f;
}
if (AutoRestart)
{
ImGui::Text("Auto Restart Delay");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
ImGui::InputFloat("##Auto Restart Delay", &FCogDamageStats::RestartDelaySetting);
}
ImGui::Text("Max Time");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
if (ImGui::InputFloat("##Max Time", &FCogDamageStats::MaxDurationSetting, 0.0f, 0.0f, "%0.1f"))
{
DamageDealtStats.Restart();
DamageReceivedStats.Restart();
}
ImGui::PopItemWidth();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Damages::OnSelectionChanged(AActor* OldSelection, AActor* NewSelection)
{
if (ICogInterfaceDamageActor* DamageActor = Cast<ICogInterfaceDamageActor>(OldSelection))
{
DamageActor->OnDamageEvent().Remove(OnDamageEventDelegate);
}
if (ICogInterfaceDamageActor* DamageActor = Cast<ICogInterfaceDamageActor>(NewSelection))
{
OnDamageEventDelegate = DamageActor->OnDamageEvent().AddUObject(this, &UCogAbilityWindow_Damages::OnDamageEvent);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Damages::GameTick(float DeltaSeconds)
{
Super::GameTick(DeltaSeconds);
DamageReceivedStats.Tick(DeltaSeconds);
DamageDealtStats.Tick(DeltaSeconds);
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Damages::OnDamageEvent(const FCogInterfaceDamageParams& Params)
{
AActor* Selection = GetSelection();
if (Params.Type == ECogInterfaceDamageEventType::DamageDealt)
{
DamageDealtStats.AddDamage(Params.MitigatedDamage, Params.IncomingDamage, Params.IsCritical);
}
else if (Params.Type == ECogInterfaceDamageEventType::DamageReceived)
{
DamageReceivedStats.AddDamage(Params.MitigatedDamage, Params.IncomingDamage, Params.IsCritical);
}
}
@@ -0,0 +1,280 @@
#include "CogAbilityWindow_Metrics.h"
#include "CogInterfaceMetricActor.h"
#include "CogImguiHelper.h"
#include "imgui.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogMetricInstance::Restart()
{
Last = 0.0f;
Min = 0.0f;
Max = 0.0f;
PerSecond = 0.0f;
PerFrame = 0.0f;
Total = 0.0f;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogMetricInstance::AddMetric(const float Metric)
{
Last = Metric;
Min = Min == 0.0f ? Metric : FMath::Min(Min, Metric);
Max = FMath::Max(Max, Metric);
PerFrame += Metric;
Total += Metric;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogMetricInstance::UpdateMetricPerSecond(const float Duration)
{
PerSecond = Duration > 1.0f ? Total / Duration : Total;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogMetricInfo::Restart()
{
Count = 0;
Crits = 0;
TotalCritChances = 0.0f;
IsInProgress = false;
Timer = 0.0f;
RestartTimer = 0.0f;
Mitigated.Restart();
Unmitigated.Restart();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogMetricInfo::AddEvent(const FCogInterfaceMetricEventParams& Params)
{
// If the max duration is reached, stop adding
if (MaxDurationSetting != 0 && Timer >= MaxDurationSetting)
{
return;
}
IsInProgress = true;
Count++;
Crits += Params.IsCritical ? 1 : 0;
Mitigated.AddMetric(Params.MitigatedValue);
Unmitigated.AddMetric(Params.UnmitigatedValue);
Mitigated.UpdateMetricPerSecond(Timer);
Unmitigated.UpdateMetricPerSecond(Timer);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogMetricInfo::Tick(const float DeltaSeconds)
{
if (IsInProgress)
{
// If the max duration is reached, stop increasing time.
if (MaxDurationSetting <= 0 || Timer < MaxDurationSetting)
{
Timer += DeltaSeconds;
}
else
{
IsInProgress = false;
Timer = MaxDurationSetting;
Mitigated.UpdateMetricPerSecond(Timer);
Unmitigated.UpdateMetricPerSecond(Timer);
}
}
if (RestartDelaySetting > 0.0f)
{
if (Unmitigated.PerFrame == 0.0f)
{
RestartTimer += DeltaSeconds;
if (RestartTimer > RestartDelaySetting)
{
Restart();
}
}
else
{
RestartTimer = 0.0f;
}
}
Mitigated.PerFrame = 0.0f;
Unmitigated.PerFrame = 0.0f;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Metrics::DrawMetricRow(const char* Title, float MitigatedValue, float UnmitigatedValue, const ImVec4& Color)
{
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Selectable(Title, false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap | ImGuiSelectableFlags_AllowDoubleClick);
ImGui::TableNextColumn();
ImGui::TextColored(Color, "%.1f", MitigatedValue);
ImGui::TableNextColumn();
ImGui::Text("%.1f", UnmitigatedValue);
ImGui::TableNextColumn();
ImGui::Text("%.0f%%", UnmitigatedValue <= 0 ? 0.0 : 100.0f * (1.0f - (MitigatedValue / UnmitigatedValue)));
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Metrics::DrawMetrics(FCogMetricInfo& Metric)
{
FCogWindowWidgets::PushBackColor(ImVec4(0.8f, 0.8f, 0.8f, 1.0f));
if (ImGui::BeginTable("MetricTable", 4, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_RowBg))
{
ImGui::TableSetupColumn("");
ImGui::TableSetupColumn("Mitigated");
ImGui::TableSetupColumn("Unmitigated");
ImGui::TableSetupColumn("Mitigation %");
ImGui::TableHeadersRow();
DrawMetricRow("Per Second", Metric.Mitigated.PerSecond, Metric.Unmitigated.PerSecond, ImVec4(1.0f, 1.0, 0.0f, 1.0f));
DrawMetricRow("Total", Metric.Mitigated.Total, Metric.Unmitigated.Total, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
DrawMetricRow("Last", Metric.Mitigated.Last, Metric.Unmitigated.Last, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
DrawMetricRow("Min", Metric.Mitigated.Min, Metric.Unmitigated.Min, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
DrawMetricRow("Min", Metric.Mitigated.Max, Metric.Unmitigated.Max, ImVec4(1.0f, 1.0, 1.0f, 1.0f));
ImGui::EndTable();
}
ImGui::Text("Crits");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
FCogWindowWidgets::ProgressBarCentered(Metric.Count == 0 ? 0.0f : Metric.Crits / (float)Metric.Count, ImVec2(-1, 0), TCHAR_TO_ANSI(*FString::Printf(TEXT("%d / %d"), Metric.Crits, Metric.Count)));
if (Metric.MaxDurationSetting > 0.0f)
{
ImGui::Text("Timer");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
FCogWindowWidgets::ProgressBarCentered(Metric.Timer / (float)Metric.MaxDurationSetting, ImVec2(-1, 0), TCHAR_TO_ANSI(*FString::Printf(TEXT("%0.1f / %0.1f"), Metric.Timer, Metric.MaxDurationSetting)));
}
else
{
ImGui::Text("Timer");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
ImGui::Text("%0.1f", Metric.Timer);
}
ImGui::Spacing();
if (ImGui::Button("Restart"))
{
Metric.Restart();
}
FCogWindowWidgets::PopBackColor();
ImGui::Spacing();
ImGui::Spacing();
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Metrics::RenderContent()
{
Super::RenderContent();
AActor* Selection = GetSelection();
if (Selection == nullptr)
{
return;
}
int32 Index = 0;
for (auto& Entry : Metrics)
{
FName MetricName = Entry.Key;
FCogMetricInfo& Metric = Entry.Value;
if (ImGui::CollapsingHeader(TCHAR_TO_ANSI(*MetricName.ToString())))
{
ImGui::PushID(Index);
DrawMetrics(Metric);
ImGui::PopID();
}
Index++;
}
if (ImGui::CollapsingHeader("Settings"))
{
ImGui::PushItemWidth(-1);
bool Reset = false;
ImGui::Text("Auto Restart");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
bool AutoRestart = RestartDelaySetting > 0;
if (ImGui::Checkbox("##Auto Restart", &AutoRestart))
{
RestartDelaySetting = AutoRestart ? 5.0f : 0.0f;
Reset = true;
}
if (AutoRestart)
{
ImGui::Text("Auto Restart Delay");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
if (ImGui::InputFloat("##Auto Restart Delay", &RestartDelaySetting))
{
Reset = true;
}
}
ImGui::Text("Max Time");
ImGui::SameLine(FCogWindowWidgets::TextBaseWidth * 20);
if (ImGui::InputFloat("##Max Time", &MaxDurationSetting, 0.0f, 0.0f, "%0.1f"))
{
Reset = true;
}
if (Reset)
{
for (auto& Entry : Metrics)
{
FCogMetricInfo& Metric = Entry.Value;
Metric.MaxDurationSetting = MaxDurationSetting;
Metric.RestartDelaySetting = RestartDelaySetting;
Metric.Restart();
}
}
ImGui::PopItemWidth();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Metrics::OnSelectionChanged(AActor* OldSelection, AActor* NewSelection)
{
if (ICogInterfaceMetricActor* DamageActor = Cast<ICogInterfaceMetricActor>(OldSelection))
{
DamageActor->OnMetricEvent().Remove(OnMetricDelegate);
}
if (ICogInterfaceMetricActor* DamageActor = Cast<ICogInterfaceMetricActor>(NewSelection))
{
OnMetricDelegate = DamageActor->OnMetricEvent().AddUObject(this, &UCogAbilityWindow_Metrics::OnEvent);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Metrics::GameTick(float DeltaSeconds)
{
Super::GameTick(DeltaSeconds);
for (auto& Entry : Metrics)
{
FCogMetricInfo& Metric = Entry.Value;
Metric.Tick(DeltaSeconds);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAbilityWindow_Metrics::OnEvent(const FCogInterfaceMetricEventParams& Params)
{
FCogMetricInfo& MetricInfo = Metrics.FindOrAdd(Params.Name);
MetricInfo.AddEvent(Params);
}
@@ -14,7 +14,7 @@ class COGABILITY_API UCogAbilityWindow_Cheats : public UCogWindow
GENERATED_BODY()
public:
UCogAbilityWindow_Cheats();
virtual void RenderContent() override;
TWeakObjectPtr<UCogAbilityDataAsset_Cheats> CheatsAsset;
@@ -1,72 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "CogWindow.h"
#include "CogAbilityWindow_Damages.generated.h"
struct FCogInterfaceDamageParams;
//--------------------------------------------------------------------------------------------------------------------------
class FCogDamageInstance
{
public:
void Restart();
void AddDamage(const float Damage);
void UpdateDamagePerSecond(const float Duration);
float DamageLast = 0.0f;
float DamageMin = 0.0f;
float DamageMax = 0.0f;
float DamagePerFrame = 0.0f;
float DamagePerSecond = 0.0f;
float DamageTotal = 0.0f;
};
//--------------------------------------------------------------------------------------------------------------------------
class FCogDamageStats
{
public:
void AddDamage(const float Damage, const float UnmitigatedDamage, const bool bIsCrit);
void Tick(const float DeltaSeconds);
void Restart();
int Count = 0;
int Crits = 0;
bool IsInProgress = false;
float TotalCritChances = 0.0f;
float Timer = 0.0f;
float MaxDuration = 0.0f;
float RestartTimer = 0.0f;
FCogDamageInstance Mitigated;
FCogDamageInstance Unmitigated;
static float MaxDurationSetting;
static float RestartDelaySetting;
};
//--------------------------------------------------------------------------------------------------------------------------
UCLASS()
class COGABILITY_API UCogAbilityWindow_Damages : public UCogWindow
{
GENERATED_BODY()
public:
protected:
virtual void RenderContent() override;
virtual void GameTick(float DeltaSeconds) override;
virtual void OnSelectionChanged(AActor* OldSelection, AActor* NewSelection) override;
private:
UFUNCTION()
void OnDamageEvent(const FCogInterfaceDamageParams& Params);
FCogDamageStats DamageDealtStats;
FCogDamageStats DamageReceivedStats;
FDelegateHandle OnDamageEventDelegate;
};
@@ -0,0 +1,99 @@
#pragma once
#include "CoreMinimal.h"
#include "CogWindow.h"
#include "CogAbilityWindow_Metrics.generated.h"
struct FCogInterfaceMetricEventParams;
//--------------------------------------------------------------------------------------------------------------------------
class FCogMetricInstance
{
public:
void Restart();
void AddMetric(const float Damage);
void UpdateMetricPerSecond(const float Duration);
float Last = 0.0f;
float Min = 0.0f;
float Max = 0.0f;
float PerFrame = 0.0f;
float PerSecond = 0.0f;
float Total = 0.0f;
};
//--------------------------------------------------------------------------------------------------------------------------
class FCogMetricInfo
{
public:
void AddEvent(const FCogInterfaceMetricEventParams& Params);
void Tick(const float DeltaSeconds);
void Restart();
FName Name;
int Count = 0;
int Crits = 0;
bool IsInProgress = false;
float TotalCritChances = 0.0f;
float Timer = 0.0f;
float RestartTimer = 0.0f;
FCogMetricInstance Mitigated;
FCogMetricInstance Unmitigated;
float MaxDurationSetting = 0.0f;
float RestartDelaySetting = 0.0f;
};
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(Config = Cog)
class COGABILITY_API UCogAbilityWindow_Metrics : public UCogWindow
{
GENERATED_BODY()
public:
protected:
virtual void RenderContent() override;
virtual void GameTick(float DeltaSeconds) override;
virtual void OnSelectionChanged(AActor* OldSelection, AActor* NewSelection) override;
virtual void DrawMetrics(FCogMetricInfo& Metric);
virtual void DrawMetricRow(const char* Title, float MitigatedValue, float UnmitigatedValue, const ImVec4& Color);
private:
UFUNCTION()
void OnEvent(const FCogInterfaceMetricEventParams& Params);
UPROPERTY(Config)
float MaxDurationSetting = 0.0f;
UPROPERTY(Config)
float RestartDelaySetting = 5.0f;
TMap<FName, FCogMetricInfo> Metrics;
FDelegateHandle OnMetricDelegate;
};
@@ -1,46 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "CogInterfaceDamageActor.generated.h"
//--------------------------------------------------------------------------------------------------------------------------
UENUM(BlueprintType)
enum class ECogInterfaceDamageEventType : uint8
{
DamageDealt,
DamageReceived,
};
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT()
struct FCogInterfaceDamageParams
{
GENERATED_BODY()
ECogInterfaceDamageEventType Type;
TObjectPtr<AActor> DamageDealer;
TObjectPtr<AActor> DamageReceiver;
float MitigatedDamage = 0;
float IncomingDamage = 0;
bool IsCritical = false;
};
//--------------------------------------------------------------------------------------------------------------------------
DECLARE_MULTICAST_DELEGATE_OneParam(FCogInterfaceOnDamageEvent, const FCogInterfaceDamageParams&);
//--------------------------------------------------------------------------------------------------------------------------
UINTERFACE(MinimalAPI, Blueprintable)
class UCogInterfaceDamageActor : public UInterface
{
GENERATED_BODY()
};
//--------------------------------------------------------------------------------------------------------------------------
class ICogInterfaceDamageActor
{
GENERATED_BODY()
public:
virtual FCogInterfaceOnDamageEvent& OnDamageEvent() = 0;
};
@@ -0,0 +1,38 @@
#pragma once
#include "CoreMinimal.h"
#include "CogInterfaceMetricActor.generated.h"
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT()
struct FCogInterfaceMetricEventParams
{
GENERATED_BODY()
FName Name;
float MitigatedValue = 0;
float UnmitigatedValue = 0;
bool IsCritical = false;
};
//--------------------------------------------------------------------------------------------------------------------------
DECLARE_MULTICAST_DELEGATE_OneParam(FCogInterfaceOnMetricEvent, const FCogInterfaceMetricEventParams&);
//--------------------------------------------------------------------------------------------------------------------------
UINTERFACE(MinimalAPI, Blueprintable)
class UCogInterfaceMetricActor : public UInterface
{
GENERATED_BODY()
};
//--------------------------------------------------------------------------------------------------------------------------
class ICogInterfaceMetricActor
{
GENERATED_BODY()
public:
virtual FCogInterfaceOnMetricEvent& OnMetricEvent() = 0;
};
+10 -14
View File
@@ -348,13 +348,11 @@ void ACogSampleCharacter::Look(const FInputActionValue& Value)
void ACogSampleCharacter::OnDamageReceived(float ReceivedDamage, float IncomingDamage, AActor* DamageDealer, const FGameplayEffectSpec& EffectSpec)
{
#if USE_COG
FCogInterfaceDamageParams Params;
Params.Type = ECogInterfaceDamageEventType::DamageReceived;
Params.MitigatedDamage = ReceivedDamage;
Params.IncomingDamage = IncomingDamage;
Params.DamageDealer = DamageDealer;
Params.DamageReceiver = this;
OnDamageEventDelegate.Broadcast(Params);
FCogInterfaceMetricEventParams Params;
Params.Name = "Damage Received";
Params.MitigatedValue = ReceivedDamage;
Params.UnmitigatedValue = IncomingDamage;
OnMetricEventDelegate.Broadcast(Params);
#endif //USE_COG
}
@@ -362,13 +360,11 @@ void ACogSampleCharacter::OnDamageReceived(float ReceivedDamage, float IncomingD
void ACogSampleCharacter::OnDamageDealt(float ReceivedDamage, float IncomingDamage, AActor* DamageReceiver, const FGameplayEffectSpec& EffectSpec)
{
#if USE_COG
FCogInterfaceDamageParams Params;
Params.Type = ECogInterfaceDamageEventType::DamageDealt;
Params.MitigatedDamage = ReceivedDamage;
Params.IncomingDamage = IncomingDamage;
Params.DamageDealer = this;
Params.DamageReceiver = DamageReceiver;
OnDamageEventDelegate.Broadcast(Params);
FCogInterfaceMetricEventParams Params;
Params.Name = "Damage Dealt";
Params.MitigatedValue = ReceivedDamage;
Params.UnmitigatedValue = IncomingDamage;
OnMetricEventDelegate.Broadcast(Params);
#endif //USE_COG
}
+4 -4
View File
@@ -5,7 +5,7 @@
#include "ActiveGameplayEffectHandle.h"
#include "AttributeSet.h"
#include "CogDefines.h"
#include "CogInterfaceDamageActor.h"
#include "CogInterfaceMetricActor.h"
#include "CogInterfaceFilteredActor.h"
#include "GameFramework/Character.h"
#include "GameplayAbilitySpecHandle.h"
@@ -59,7 +59,7 @@ UCLASS(config=Game)
class ACogSampleCharacter : public ACharacter
, public IAbilitySystemInterface
, public ICogInterfacesFilteredActor
, public ICogInterfaceDamageActor
, public ICogInterfaceMetricActor
{
GENERATED_BODY()
@@ -75,7 +75,7 @@ public:
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
virtual void PossessedBy(AController* NewController) override;
virtual FCogInterfaceOnDamageEvent& OnDamageEvent() override { return OnDamageEventDelegate; }
virtual FCogInterfaceOnMetricEvent& OnMetricEvent() override { return OnMetricEventDelegate; }
virtual bool IsActorFilteringDebug() const override { return true; }
void OnAcknowledgePossession(APlayerController* InController);
@@ -146,7 +146,7 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Ability)
TArray<TSubclassOf<UGameplayEffect>> Effects;
FCogInterfaceOnDamageEvent OnDamageEventDelegate;
FCogInterfaceOnMetricEvent OnMetricEventDelegate;
private:
+2 -2
View File
@@ -17,8 +17,8 @@
#include "CogAbilityWindow_Abilities.h"
#include "CogAbilityWindow_Attributes.h"
#include "CogAbilityWindow_Cheats.h"
#include "CogAbilityWindow_Damages.h"
#include "CogAbilityWindow_Effects.h"
#include "CogAbilityWindow_Metrics.h"
#include "CogAbilityWindow_Pools.h"
#include "CogAbilityWindow_Tags.h"
#include "CogAbilityWindow_Tweaks.h"
@@ -194,7 +194,7 @@ void ACogSampleGameState::InitializeCog()
UCogAbilityWindow_Cheats* CheatsWindow = CogWindowManager->CreateWindow<UCogAbilityWindow_Cheats>("Gameplay.Cheats");
CheatsWindow->CheatsAsset = GetFirstAssetByClass<UCogAbilityDataAsset_Cheats>();
CogWindowManager->CreateWindow<UCogAbilityWindow_Damages>("Gameplay.Damages");
CogWindowManager->CreateWindow<UCogAbilityWindow_Metrics>("Gameplay.Metrics");
UCogAbilityWindow_Effects* EffectsWindow = CogWindowManager->CreateWindow<UCogAbilityWindow_Effects>("Gameplay.Effects");
EffectsWindow->NegativeEffectTag = Tag_Effect_Alignment_Negative;