// © 2025 Naked People Team. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "UObject/Object.h" #include "CommissionConstraint.generated.h" class ANakedDesireCharacter; DECLARE_MULTICAST_DELEGATE(FOnConstraintChangedSignature); /** * A "while Y" gate attached to a UCommissionObjective. The objective only counts progress while every * constraint reports IsMet(). A constraint subscribes to whatever world signal it watches and fires * OnConstraintChanged so the owning objective re-evaluates. Constraints compose with any objective, so * "expose boobs" + "while at the beach" + "during night" is data, not new objective code (see §13.4). */ UCLASS(Abstract, EditInlineNew, BlueprintType) class NAKEDDESIRE_API UCommissionConstraint : public UObject { GENERATED_BODY() public: FOnConstraintChangedSignature OnConstraintChanged; void Activate(ANakedDesireCharacter* InPlayer); void Deactivate(); virtual bool IsMet() const { return true; } UFUNCTION(BlueprintPure) virtual FText GetDescription() const; protected: UPROPERTY() ANakedDesireCharacter* Player = nullptr; virtual void OnActivate() {} virtual void OnDeactivate() {} // Subclasses call this when the thing they watch changes; the owning objective re-evaluates. void NotifyChanged() { OnConstraintChanged.Broadcast(); } };