diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp index 3bc11fa..2e64b63 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp @@ -46,6 +46,45 @@ namespace HyperTwistTrainingSubsystemInternal return TEXT("Start queued coach run"); } + EHyperTwistTrainingCoachGuidanceLane GuidanceLaneFromQueueSourceLabel(const FString& SourceLabel) + { + if (SourceLabel == TEXT("primary-brief")) + { + return EHyperTwistTrainingCoachGuidanceLane::Recommended; + } + if (SourceLabel == TEXT("follow-up-brief")) + { + return EHyperTwistTrainingCoachGuidanceLane::FollowUp; + } + + return EHyperTwistTrainingCoachGuidanceLane::None; + } + + int32 ResolvePreferredCoachCaseBudget( + const int32 MaxCases, + const EHyperTwistTrainingCoachGuidanceLane DeckLane, + const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot) + { + int32 DesiredCaseCount = MaxCases > 0 ? MaxCases : 3; + if (CoachMemorySnapshot.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp + && DeckLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp) + { + return FMath::Max(1, DesiredCaseCount - 1); + } + + if (CoachMemorySnapshot.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::Recommended + && DeckLane == EHyperTwistTrainingCoachGuidanceLane::Recommended + && DesiredCaseCount <= 3 + && (CoachMemorySnapshot.bHasRepeatRecommendationPressure + || CoachMemorySnapshot.RecommendedGuidanceContinueBias > 0 + || CoachMemorySnapshot.RecurringCoachCaseIds.Num() >= 3)) + { + return DesiredCaseCount + 1; + } + + return DesiredCaseCount; + } + const FHyperTwistTrainingCoachSessionQueueStateEntry* FindNextRunnableCoachQueueEntry( const FHyperTwistTrainingCoachSessionQueueState& QueueState ) @@ -96,10 +135,15 @@ namespace HyperTwistTrainingSubsystemInternal FHyperTwistTrainingDeck BuildCoachQueueDeckFromEntry( const FHyperTwistTrainingCoachSessionQueueStateEntry& QueueEntry, const FHyperTwistTrainingRunState& ActiveRunState, + const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot, int32 MaxCases ) { - const int32 DesiredCaseCount = MaxCases > 0 ? MaxCases : 3; + const int32 DesiredCaseCount = ResolvePreferredCoachCaseBudget( + MaxCases, + GuidanceLaneFromQueueSourceLabel(QueueEntry.SourceLabel), + CoachMemorySnapshot + ); FHyperTwistTrainingDeck SourceDeck; if (!QueueEntry.FocusDeckId.IsEmpty()) { @@ -319,6 +363,7 @@ FHyperTwistTrainingCoachPanelState UHyperTwistTrainingSubsystem::GetActiveCoachP || HyperTwistTrainingSubsystemInternal::BuildCoachQueueDeckFromEntry( *NextRunnableEntry, ActiveRunState, + ActiveCoachMemorySnapshot, 3 ).IsStructurallyValid()); @@ -1069,7 +1114,11 @@ FHyperTwistTrainingDeck UHyperTwistTrainingSubsystem::BuildActiveCoachRecommende return FHyperTwistTrainingDeck(); } - const int32 DesiredCaseCount = MaxCases > 0 ? MaxCases : 3; + const int32 DesiredCaseCount = HyperTwistTrainingSubsystemInternal::ResolvePreferredCoachCaseBudget( + MaxCases, + EHyperTwistTrainingCoachGuidanceLane::Recommended, + ActiveCoachMemorySnapshot + ); TArray FocusCases; for (const FString& FocusCaseId : ActiveCoachBrief.FocusCaseIds) { @@ -1143,7 +1192,11 @@ FHyperTwistTrainingDeck UHyperTwistTrainingSubsystem::BuildActiveCoachFollowUpDe return FHyperTwistTrainingDeck(); } - const int32 DesiredCaseCount = MaxCases > 0 ? MaxCases : 3; + const int32 DesiredCaseCount = HyperTwistTrainingSubsystemInternal::ResolvePreferredCoachCaseBudget( + MaxCases, + EHyperTwistTrainingCoachGuidanceLane::FollowUp, + ActiveCoachMemorySnapshot + ); TArray FocusCases; for (const FString& FocusCaseId : ActiveCoachFollowUpBrief.FocusCaseIds) { @@ -1436,6 +1489,7 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartNextQueuedCoachRu const FHyperTwistTrainingDeck QueueDeck = HyperTwistTrainingSubsystemInternal::BuildCoachQueueDeckFromEntry( *NextRunnableEntry, ActiveRunState, + ActiveCoachMemorySnapshot, MaxCases ); if (!QueueDeck.IsStructurallyValid()) @@ -1553,6 +1607,7 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartCoachQueueEntry( QueueDeck = HyperTwistTrainingSubsystemInternal::BuildCoachQueueDeckFromEntry( *SelectedEntry, ActiveRunState, + ActiveCoachMemorySnapshot, MaxCases ); QueueBrief = HyperTwistTrainingSubsystemInternal::BuildCoachBriefFromQueueEntry(