Files
Naked-Desire/Source/NakedDesire/Global/SessionLossResolver.h
T

63 lines
2.5 KiB
C++

// © 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);
// Voluntary sleep at the apartment bed (§4.4 step 2). Not a session-loss cause — the
// session already ended on entering the apartment — but any clothing left outside is
// still guaranteed lost. Lives here so ALL "what gets lost" logic stays in one place.
UFUNCTION(BlueprintCallable, Category = "Session")
void ResolveSleepLoss();
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;
};