// © 2025 Naked People Team. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Subsystems/WorldSubsystem.h" #include "SessionManagerSubsystem.h" #include "SessionLossResolver.generated.h" /** * Broadcast once a loss has been resolved transactionally. The presentation layer * (fade / cutscene / teleport) and the time skip live in Blueprint / the future * time subsystem and react to this, switching on FinalCause: * - EmbarrassmentMax → fade to apartment. No time skip. * - EnergyZero → trudge-home cutscene, then advance one sleep cycle. * - PoliceCapture (!cell) → fade to apartment. * - PoliceCapture (cell) → holding-cell cutscene, then fast-forward to next morning. * - SafeReturn → no special presentation. * The C++ side has already applied money / item / wanted changes by the time this fires. */ DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnSessionLossResolvedSignature, ESessionLossCause, FinalCause, bool, bWentToHoldingCell); /** * The single, deterministic owner of "what gets lost" on session end (GDD §4.4). * Subscribes to USessionManagerSubsystem::OnSessionEnd and routes every cause * through ResolveLoss. Per the architecture rule, no loss-handling logic should * live anywhere else. */ UCLASS() class NAKEDDESIRE_API USessionLossResolver : public UWorldSubsystem { GENERATED_BODY() public: virtual void OnWorldBeginPlay(UWorld& InWorld) override; // Single entry point for all §4.4 outcomes. Bound to OnSessionEnd; also callable // directly (e.g. from a debug command) to exercise a path. UFUNCTION(BlueprintCallable, Category = "Session") void ResolveLoss(ESessionLossCause Cause); UPROPERTY(BlueprintAssignable, Category = "Session") FOnSessionLossResolvedSignature OnSessionLossResolved; private: // EnergyZero / sleep: every clothing item left outside the apartment is guaranteed lost. void LoseAllWorldClothing(); // §7.7: cleared on police capture. No-op until the Wanted attribute exists (Phase 6). void ClearWanted(); void Autosave() const; class UGlobalSaveGameData* GetSave() const; // §21 tuning placeholder — the police-capture money penalty. float PoliceCaptureMoneyPenalty = 200.0f; };