diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp index 51b0179..806c31c 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp @@ -9,11 +9,6 @@ #include "imgui.h" #include "imgui_internal.h" -//-------------------------------------------------------------------------------------------------------------------------- -UCogAbilityWindow_Cheats::UCogAbilityWindow_Cheats() -{ -} - //-------------------------------------------------------------------------------------------------------------------------- void UCogAbilityWindow_Cheats::RenderContent() { diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Damages.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Damages.cpp deleted file mode 100644 index a1cc587..0000000 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Damages.cpp +++ /dev/null @@ -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(OldSelection)) - { - DamageActor->OnDamageEvent().Remove(OnDamageEventDelegate); - } - - if (ICogInterfaceDamageActor* DamageActor = Cast(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); - } -} \ No newline at end of file diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Metrics.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Metrics.cpp new file mode 100644 index 0000000..38f3ded --- /dev/null +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Metrics.cpp @@ -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(OldSelection)) + { + DamageActor->OnMetricEvent().Remove(OnMetricDelegate); + } + + if (ICogInterfaceMetricActor* DamageActor = Cast(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); +} \ No newline at end of file diff --git a/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Cheats.h b/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Cheats.h index 8ca287b..312f02b 100644 --- a/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Cheats.h +++ b/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Cheats.h @@ -14,7 +14,7 @@ class COGABILITY_API UCogAbilityWindow_Cheats : public UCogWindow GENERATED_BODY() public: - UCogAbilityWindow_Cheats(); + virtual void RenderContent() override; TWeakObjectPtr CheatsAsset; diff --git a/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Damages.h b/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Damages.h deleted file mode 100644 index 6c3951f..0000000 --- a/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Damages.h +++ /dev/null @@ -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; -}; diff --git a/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Metrics.h b/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Metrics.h new file mode 100644 index 0000000..04e0969 --- /dev/null +++ b/Plugins/CogAbility/Source/CogAbility/Public/CogAbilityWindow_Metrics.h @@ -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 Metrics; + + FDelegateHandle OnMetricDelegate; +}; diff --git a/Plugins/CogInterface/Source/CogInterface/Public/CogInterfaceDamageActor.h b/Plugins/CogInterface/Source/CogInterface/Public/CogInterfaceDamageActor.h deleted file mode 100644 index dc5348f..0000000 --- a/Plugins/CogInterface/Source/CogInterface/Public/CogInterfaceDamageActor.h +++ /dev/null @@ -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 DamageDealer; - TObjectPtr 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; -}; \ No newline at end of file diff --git a/Plugins/CogInterface/Source/CogInterface/Public/CogInterfaceMetricActor.h b/Plugins/CogInterface/Source/CogInterface/Public/CogInterfaceMetricActor.h new file mode 100644 index 0000000..51248c9 --- /dev/null +++ b/Plugins/CogInterface/Source/CogInterface/Public/CogInterfaceMetricActor.h @@ -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; +}; \ No newline at end of file diff --git a/Source/CogSample/CogSampleCharacter.cpp b/Source/CogSample/CogSampleCharacter.cpp index 29753ea..af9bb93 100644 --- a/Source/CogSample/CogSampleCharacter.cpp +++ b/Source/CogSample/CogSampleCharacter.cpp @@ -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 } diff --git a/Source/CogSample/CogSampleCharacter.h b/Source/CogSample/CogSampleCharacter.h index 9890554..ff1fffa 100644 --- a/Source/CogSample/CogSampleCharacter.h +++ b/Source/CogSample/CogSampleCharacter.h @@ -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> Effects; - FCogInterfaceOnDamageEvent OnDamageEventDelegate; + FCogInterfaceOnMetricEvent OnMetricEventDelegate; private: diff --git a/Source/CogSample/CogSampleGameState.cpp b/Source/CogSample/CogSampleGameState.cpp index 21e0c4a..9bb72d8 100644 --- a/Source/CogSample/CogSampleGameState.cpp +++ b/Source/CogSample/CogSampleGameState.cpp @@ -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("Gameplay.Cheats"); CheatsWindow->CheatsAsset = GetFirstAssetByClass(); - CogWindowManager->CreateWindow("Gameplay.Damages"); + CogWindowManager->CreateWindow("Gameplay.Metrics"); UCogAbilityWindow_Effects* EffectsWindow = CogWindowManager->CreateWindow("Gameplay.Effects"); EffectsWindow->NegativeEffectTag = Tag_Effect_Alignment_Negative;