diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp index 8c61eab..39a664e 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp @@ -130,6 +130,18 @@ namespace HyperTwistCoachDashboardWidgetInternal { return TEXT("accepted deferred-first recommended handoff history"); } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-queued")) + { + return TEXT("accepted drill-driven queued handoff history"); + } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-follow-up")) + { + return TEXT("accepted drill-driven follow-up handoff history"); + } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recommended")) + { + return TEXT("accepted drill-driven recommended handoff history"); + } if (SourceLabel == TEXT("coach-memory-dashboard-queued")) { return TEXT("accepted queued handoff history"); @@ -174,6 +186,18 @@ namespace HyperTwistCoachDashboardWidgetInternal { return TEXT("accepted deferred-first recommended dashboard handoff"); } + if (SourceLabel == TEXT("dashboard-handoff-method-drill-queued")) + { + return TEXT("accepted drill-driven queued dashboard handoff"); + } + if (SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up")) + { + return TEXT("accepted drill-driven follow-up dashboard handoff"); + } + if (SourceLabel == TEXT("dashboard-handoff-method-drill-recommended")) + { + return TEXT("accepted drill-driven recommended dashboard handoff"); + } if (SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-queued")) { return TEXT("accepted deferred-overflow queued outcome handoff"); @@ -242,8 +266,24 @@ namespace HyperTwistCoachDashboardWidgetInternal FString DashboardHandoffSourceLabel( const EHyperTwistTrainingCoachHandoffKind HandoffKind, - const bool bDeferredFirstSuppressionDriven) + const bool bDeferredFirstSuppressionDriven, + const bool bMethodDrillDriven = false) { + if (bMethodDrillDriven) + { + switch (HandoffKind) + { + case EHyperTwistTrainingCoachHandoffKind::Queue: + return TEXT("dashboard-handoff-method-drill-queued"); + case EHyperTwistTrainingCoachHandoffKind::FollowUp: + return TEXT("dashboard-handoff-method-drill-follow-up"); + case EHyperTwistTrainingCoachHandoffKind::Recommended: + return TEXT("dashboard-handoff-method-drill-recommended"); + default: + return FString(); + } + } + switch (HandoffKind) { case EHyperTwistTrainingCoachHandoffKind::Queue: @@ -3989,9 +4029,13 @@ FString UHyperTwistCoachDashboardWidget::ResolveDashboardHandoffStartActionSourc const bool bUseDeferredFirstSuppressionLabel = bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal && DisplayedCoachHandoffRecommendationKind == HandoffKind; + const bool bUseMethodDrillLabel = + bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting + && DisplayedCoachHandoffRecommendationKind == HandoffKind; return HyperTwistCoachDashboardWidgetInternal::DashboardHandoffSourceLabel( HandoffKind, - bUseDeferredFirstSuppressionLabel + bUseDeferredFirstSuppressionLabel, + bUseMethodDrillLabel ); } @@ -5826,6 +5870,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::None; DisplayedCoachHandoffRecommendationKind = EHyperTwistTrainingCoachHandoffKind::None; bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal = false; + bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting = false; FString CoachHandoffRecommendationStatusLine; FString CoachHandoffRecommendationDetailLine; const bool bQueueReadyForHandoff = CachedCoachPanelState.bCanStartQueuedRun; @@ -6161,6 +6206,8 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation() } bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal = bHandoffRecommendationUsedDeferredFirstSuppressionSignal; + bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting = + bHandoffRecommendationUsedMethodDrillWeighting; CoachHandoffRecommendationDetailLine = FString::Printf( TEXT("Closure continuation bias %d | Closure suppression bias %d | Queue ready: %s | Follow-up ready: %s | Recommended ready: %s | Preferred lane: %s | Memory source: %s%s%s%s%s%s | Launch bias: %s from %s | broadened/tightened history %d/%d | deferred tightened launches %d | deferred launch cases %d%s | Handoff history preferred: %s | accepted q/f/r %d/%d/%d | deferred-overflow accepted q/f/r %d/%d/%d | deferred-first recommendation q/f/r %d/%d/%d | recommended q/f/r %d/%d/%d"), diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp index ecb5a1e..8aa9b3e 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp @@ -95,6 +95,18 @@ namespace HyperTwistTrainingCoachLibraryInternal { return TEXT("accepted queued handoff history"); } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-queued")) + { + return TEXT("accepted drill-driven queued handoff history"); + } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-follow-up")) + { + return TEXT("accepted drill-driven follow-up handoff history"); + } + if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recommended")) + { + return TEXT("accepted drill-driven recommended handoff history"); + } if (SourceLabel == TEXT("coach-memory-queue-follow-up")) { return TEXT("queue follow-up recovery memory"); @@ -127,6 +139,18 @@ namespace HyperTwistTrainingCoachLibraryInternal { return TEXT("accepted deferred-first recommended dashboard handoff"); } + if (SourceLabel == TEXT("dashboard-handoff-method-drill-queued")) + { + return TEXT("accepted drill-driven queued dashboard handoff"); + } + if (SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up")) + { + return TEXT("accepted drill-driven follow-up dashboard handoff"); + } + if (SourceLabel == TEXT("dashboard-handoff-method-drill-recommended")) + { + return TEXT("accepted drill-driven recommended dashboard handoff"); + } if (SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-queued")) { return TEXT("accepted deferred-overflow queued outcome handoff"); diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp index ad41def..183be73 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp @@ -71,23 +71,34 @@ namespace HyperTwistTrainingRepositoryLibraryInternal || SourceLabel.StartsWith(TEXT("coach-memory-dashboard-deferred-first-")); } + bool IsMethodDrillDashboardHandoffSource(const FString& SourceLabel) + { + return SourceLabel == TEXT("dashboard-handoff-method-drill-queued") + || SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up") + || SourceLabel == TEXT("dashboard-handoff-method-drill-recommended") + || SourceLabel.StartsWith(TEXT("coach-memory-dashboard-method-drill-")); + } + EHyperTwistTrainingCoachHandoffKind DashboardHandoffKindFromSourceLabel(const FString& SourceLabel) { if (SourceLabel == TEXT("dashboard-handoff-queued") || SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-queued") - || SourceLabel == TEXT("dashboard-handoff-deferred-first-queued")) + || SourceLabel == TEXT("dashboard-handoff-deferred-first-queued") + || SourceLabel == TEXT("dashboard-handoff-method-drill-queued")) { return EHyperTwistTrainingCoachHandoffKind::Queue; } if (SourceLabel == TEXT("dashboard-handoff-follow-up") || SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-follow-up") - || SourceLabel == TEXT("dashboard-handoff-deferred-first-follow-up")) + || SourceLabel == TEXT("dashboard-handoff-deferred-first-follow-up") + || SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up")) { return EHyperTwistTrainingCoachHandoffKind::FollowUp; } if (SourceLabel == TEXT("dashboard-handoff-recommended") || SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-recommended") - || SourceLabel == TEXT("dashboard-handoff-deferred-first-recommended")) + || SourceLabel == TEXT("dashboard-handoff-deferred-first-recommended") + || SourceLabel == TEXT("dashboard-handoff-method-drill-recommended")) { return EHyperTwistTrainingCoachHandoffKind::Recommended; } @@ -98,12 +109,17 @@ namespace HyperTwistTrainingRepositoryLibraryInternal FString CoachMemoryDashboardSourceLabel( const EHyperTwistTrainingCoachHandoffKind HandoffKind, const bool bDeferredOverflowDriven, - const bool bDeferredFirstDriven = false + const bool bDeferredFirstDriven = false, + const bool bMethodDrillDriven = false ) { switch (HandoffKind) { case EHyperTwistTrainingCoachHandoffKind::Queue: + if (bMethodDrillDriven) + { + return TEXT("coach-memory-dashboard-method-drill-queued"); + } if (bDeferredFirstDriven) { return TEXT("coach-memory-dashboard-deferred-first-queued"); @@ -112,6 +128,10 @@ namespace HyperTwistTrainingRepositoryLibraryInternal ? TEXT("coach-memory-dashboard-deferred-overflow-queued") : TEXT("coach-memory-dashboard-queued"); case EHyperTwistTrainingCoachHandoffKind::FollowUp: + if (bMethodDrillDriven) + { + return TEXT("coach-memory-dashboard-method-drill-follow-up"); + } if (bDeferredFirstDriven) { return TEXT("coach-memory-dashboard-deferred-first-follow-up"); @@ -120,6 +140,10 @@ namespace HyperTwistTrainingRepositoryLibraryInternal ? TEXT("coach-memory-dashboard-deferred-overflow-follow-up") : TEXT("coach-memory-dashboard-follow-up"); case EHyperTwistTrainingCoachHandoffKind::Recommended: + if (bMethodDrillDriven) + { + return TEXT("coach-memory-dashboard-method-drill-recommended"); + } if (bDeferredFirstDriven) { return TEXT("coach-memory-dashboard-deferred-first-recommended"); @@ -469,6 +493,21 @@ namespace HyperTwistTrainingRepositoryLibraryInternal 0, 4 ); + const int32 ExplicitMethodDrillQueuedHandoffSignal = FMath::Clamp( + QueueExecutionSummary.StartedMethodDrillQueuedHandoffEventCount * 2, + 0, + 4 + ); + const int32 ExplicitMethodDrillFollowUpHandoffSignal = FMath::Clamp( + QueueExecutionSummary.StartedMethodDrillFollowUpHandoffEventCount * 2, + 0, + 4 + ); + const int32 ExplicitMethodDrillRecommendedHandoffSignal = FMath::Clamp( + QueueExecutionSummary.StartedMethodDrillRecommendedHandoffEventCount * 2, + 0, + 4 + ); if (ExplicitQueuedHandoffSignal > 0 || ExplicitFollowUpHandoffSignal > 0 || ExplicitRecommendedHandoffSignal > 0) @@ -481,7 +520,8 @@ namespace HyperTwistTrainingRepositoryLibraryInternal HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel( EHyperTwistTrainingCoachHandoffKind::Queue, ExplicitDeferredOverflowQueuedHandoffSignal > 0, - ExplicitDeferredFirstQueuedHandoffSignal > 0 + ExplicitDeferredFirstQueuedHandoffSignal > 0, + ExplicitMethodDrillQueuedHandoffSignal > 0 ); } else if (ExplicitFollowUpHandoffSignal >= ExplicitRecommendedHandoffSignal) @@ -491,7 +531,8 @@ namespace HyperTwistTrainingRepositoryLibraryInternal HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel( EHyperTwistTrainingCoachHandoffKind::FollowUp, ExplicitDeferredOverflowFollowUpHandoffSignal > 0, - ExplicitDeferredFirstFollowUpHandoffSignal > 0 + ExplicitDeferredFirstFollowUpHandoffSignal > 0, + ExplicitMethodDrillFollowUpHandoffSignal > 0 ); } else @@ -501,7 +542,8 @@ namespace HyperTwistTrainingRepositoryLibraryInternal HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel( EHyperTwistTrainingCoachHandoffKind::Recommended, ExplicitDeferredOverflowRecommendedHandoffSignal > 0, - ExplicitDeferredFirstRecommendedHandoffSignal > 0 + ExplicitDeferredFirstRecommendedHandoffSignal > 0, + ExplicitMethodDrillRecommendedHandoffSignal > 0 ); } } @@ -510,12 +552,15 @@ namespace HyperTwistTrainingRepositoryLibraryInternal + ExplicitFollowUpHandoffSignal + ExplicitDeferredOverflowFollowUpHandoffSignal + ExplicitDeferredFirstQueuedHandoffSignal - + ExplicitDeferredFirstFollowUpHandoffSignal; + + ExplicitDeferredFirstFollowUpHandoffSignal + + ExplicitMethodDrillQueuedHandoffSignal + + ExplicitMethodDrillFollowUpHandoffSignal; const int32 WeightedRecommendedRecoverySignal = ExplicitRecommendedRecoverySignal + ExplicitRecommendedHandoffSignal + ExplicitDeferredOverflowRecommendedHandoffSignal - + ExplicitDeferredFirstRecommendedHandoffSignal; + + ExplicitDeferredFirstRecommendedHandoffSignal + + ExplicitMethodDrillRecommendedHandoffSignal; const bool bQueueHistoryPrefersFollowUp = DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp || (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp @@ -6406,6 +6451,21 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der 0, 4 ); + const int32 ExplicitMethodDrillQueuedHandoffSignal = FMath::Clamp( + QueueExecutionSummary.StartedMethodDrillQueuedHandoffEventCount * 2, + 0, + 4 + ); + const int32 ExplicitMethodDrillFollowUpHandoffSignal = FMath::Clamp( + QueueExecutionSummary.StartedMethodDrillFollowUpHandoffEventCount * 2, + 0, + 4 + ); + const int32 ExplicitMethodDrillRecommendedHandoffSignal = FMath::Clamp( + QueueExecutionSummary.StartedMethodDrillRecommendedHandoffEventCount * 2, + 0, + 4 + ); if (ExplicitQueuedHandoffSignal > 0 || ExplicitFollowUpHandoffSignal > 0 || ExplicitRecommendedHandoffSignal > 0) @@ -6418,7 +6478,8 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel( EHyperTwistTrainingCoachHandoffKind::Queue, ExplicitDeferredOverflowQueuedHandoffSignal > 0, - ExplicitDeferredFirstQueuedHandoffSignal > 0 + ExplicitDeferredFirstQueuedHandoffSignal > 0, + ExplicitMethodDrillQueuedHandoffSignal > 0 ); } else if (ExplicitFollowUpHandoffSignal >= ExplicitRecommendedHandoffSignal) @@ -6428,7 +6489,8 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel( EHyperTwistTrainingCoachHandoffKind::FollowUp, ExplicitDeferredOverflowFollowUpHandoffSignal > 0, - ExplicitDeferredFirstFollowUpHandoffSignal > 0 + ExplicitDeferredFirstFollowUpHandoffSignal > 0, + ExplicitMethodDrillFollowUpHandoffSignal > 0 ); } else @@ -6438,7 +6500,8 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel( EHyperTwistTrainingCoachHandoffKind::Recommended, ExplicitDeferredOverflowRecommendedHandoffSignal > 0, - ExplicitDeferredFirstRecommendedHandoffSignal > 0 + ExplicitDeferredFirstRecommendedHandoffSignal > 0, + ExplicitMethodDrillRecommendedHandoffSignal > 0 ); } } @@ -6447,12 +6510,15 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der + ExplicitFollowUpHandoffSignal + ExplicitDeferredOverflowFollowUpHandoffSignal + ExplicitDeferredFirstQueuedHandoffSignal - + ExplicitDeferredFirstFollowUpHandoffSignal; + + ExplicitDeferredFirstFollowUpHandoffSignal + + ExplicitMethodDrillQueuedHandoffSignal + + ExplicitMethodDrillFollowUpHandoffSignal; const int32 WeightedRecommendedRecoverySignal = ExplicitRecommendedRecoverySignal + ExplicitRecommendedHandoffSignal + ExplicitDeferredOverflowRecommendedHandoffSignal - + ExplicitDeferredFirstRecommendedHandoffSignal; + + ExplicitDeferredFirstRecommendedHandoffSignal + + ExplicitMethodDrillRecommendedHandoffSignal; const bool bQueueHistoryPrefersFollowUp = DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp || (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp @@ -8316,6 +8382,9 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito const bool bDeferredFirstDashboardHandoff = HyperTwistTrainingRepositoryLibraryInternal::IsDeferredFirstDashboardHandoffSource( HistoryEntry.StartActionSourceLabel); + const bool bMethodDrillDashboardHandoff = + HyperTwistTrainingRepositoryLibraryInternal::IsMethodDrillDashboardHandoffSource( + HistoryEntry.StartActionSourceLabel); if (DashboardHandoffKind == EHyperTwistTrainingCoachHandoffKind::Queue) { Summary.StartedQueuedHandoffEventCount += 1; @@ -8327,6 +8396,10 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito { Summary.StartedDeferredFirstQueuedHandoffEventCount += 1; } + if (bMethodDrillDashboardHandoff) + { + Summary.StartedMethodDrillQueuedHandoffEventCount += 1; + } } else if (DashboardHandoffKind == EHyperTwistTrainingCoachHandoffKind::FollowUp) { @@ -8339,6 +8412,10 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito { Summary.StartedDeferredFirstFollowUpHandoffEventCount += 1; } + if (bMethodDrillDashboardHandoff) + { + Summary.StartedMethodDrillFollowUpHandoffEventCount += 1; + } } else if (DashboardHandoffKind == EHyperTwistTrainingCoachHandoffKind::Recommended) { @@ -8351,6 +8428,10 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito { Summary.StartedDeferredFirstRecommendedHandoffEventCount += 1; } + if (bMethodDrillDashboardHandoff) + { + Summary.StartedMethodDrillRecommendedHandoffEventCount += 1; + } } if (Summary.LastStartedAtUtc.IsEmpty() || HyperTwistTrainingRepositoryLibraryInternal::CompareUtcStrings( diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h index 7f6176a..b3e1474 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistCoachDashboardWidget.h @@ -1316,6 +1316,7 @@ private: EHyperTwistTrainingCoachHandoffKind DisplayedCoachHandoffRecommendationKind = EHyperTwistTrainingCoachHandoffKind::None; bool bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal = false; + bool bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting = false; EHyperTwistCoachDashboardGuidancePreviewLane ActiveGuidancePreviewLane = EHyperTwistCoachDashboardGuidancePreviewLane::None; int32 SelectedGuidancePreviewCaseIndex = INDEX_NONE; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h index 2429c7c..22d7295 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -3648,6 +3648,15 @@ struct FHyperTwistTrainingCoachSessionQueueExecutionSummary UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") int32 StartedDeferredFirstRecommendedHandoffEventCount = 0; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 StartedMethodDrillQueuedHandoffEventCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 StartedMethodDrillFollowUpHandoffEventCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 StartedMethodDrillRecommendedHandoffEventCount = 0; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") int32 PromotedFollowUpEventCount = 0;