Added commissions system
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
|
||||
#include "DayPhaseConstraint.h"
|
||||
|
||||
#include "NakedDesire/Player/NakedDesireCharacter.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Commissions.Constraints.DayPhase"
|
||||
|
||||
void UDayPhaseConstraint::OnActivate()
|
||||
{
|
||||
if (UTimeOfDaySubsystem* Time = GetTime())
|
||||
Time->OnPhaseChanged.AddUniqueDynamic(this, &UDayPhaseConstraint::HandlePhaseChanged);
|
||||
}
|
||||
|
||||
void UDayPhaseConstraint::OnDeactivate()
|
||||
{
|
||||
if (UTimeOfDaySubsystem* Time = GetTime())
|
||||
Time->OnPhaseChanged.RemoveDynamic(this, &UDayPhaseConstraint::HandlePhaseChanged);
|
||||
}
|
||||
|
||||
bool UDayPhaseConstraint::IsMet() const
|
||||
{
|
||||
const UTimeOfDaySubsystem* Time = GetTime();
|
||||
return Time && Time->GetPhase() == RequiredPhase;
|
||||
}
|
||||
|
||||
void UDayPhaseConstraint::HandlePhaseChanged(EDayPhase NewPhase)
|
||||
{
|
||||
NotifyChanged();
|
||||
}
|
||||
|
||||
UTimeOfDaySubsystem* UDayPhaseConstraint::GetTime() const
|
||||
{
|
||||
UWorld* World = Player ? Player->GetWorld() : nullptr;
|
||||
return World ? World->GetSubsystem<UTimeOfDaySubsystem>() : nullptr;
|
||||
}
|
||||
|
||||
FText UDayPhaseConstraint::GetDescription() const
|
||||
{
|
||||
return (RequiredPhase == EDayPhase::Night)
|
||||
? LOCTEXT("Night", "at night")
|
||||
: LOCTEXT("Day", "during the day");
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,32 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "NakedDesire/Commissions/CommissionConstraint.h"
|
||||
#include "NakedDesire/Global/TimeOfDaySubsystem.h"
|
||||
#include "DayPhaseConstraint.generated.h"
|
||||
|
||||
// Holds only during the chosen day phase (§10.1).
|
||||
UCLASS(EditInlineNew, DisplayName = "During Day Phase")
|
||||
class NAKEDDESIRE_API UDayPhaseConstraint : public UCommissionConstraint
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual bool IsMet() const override;
|
||||
virtual FText GetDescription() const override;
|
||||
|
||||
protected:
|
||||
virtual void OnActivate() override;
|
||||
virtual void OnDeactivate() override;
|
||||
|
||||
private:
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
EDayPhase RequiredPhase = EDayPhase::Night;
|
||||
|
||||
UFUNCTION()
|
||||
void HandlePhaseChanged(EDayPhase NewPhase);
|
||||
|
||||
UTimeOfDaySubsystem* GetTime() const;
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
|
||||
#include "LocationConstraint.h"
|
||||
|
||||
#include "NakedDesire/Locations/LocationSubsystem.h"
|
||||
#include "NakedDesire/Player/NakedDesireCharacter.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Commissions.Constraints.Location"
|
||||
|
||||
void ULocationConstraint::OnActivate()
|
||||
{
|
||||
if (ULocationSubsystem* Locations = GetLocations())
|
||||
{
|
||||
Locations->OnLocationEntered.AddUniqueDynamic(this, &ULocationConstraint::HandleLocationChanged);
|
||||
Locations->OnLocationExited.AddUniqueDynamic(this, &ULocationConstraint::HandleLocationChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void ULocationConstraint::OnDeactivate()
|
||||
{
|
||||
if (ULocationSubsystem* Locations = GetLocations())
|
||||
{
|
||||
Locations->OnLocationEntered.RemoveDynamic(this, &ULocationConstraint::HandleLocationChanged);
|
||||
Locations->OnLocationExited.RemoveDynamic(this, &ULocationConstraint::HandleLocationChanged);
|
||||
}
|
||||
}
|
||||
|
||||
bool ULocationConstraint::IsMet() const
|
||||
{
|
||||
const ULocationSubsystem* Locations = GetLocations();
|
||||
return Locations && Locations->IsPlayerInLocation(RequiredLocation);
|
||||
}
|
||||
|
||||
void ULocationConstraint::HandleLocationChanged(ULocationData* Location)
|
||||
{
|
||||
NotifyChanged();
|
||||
}
|
||||
|
||||
ULocationSubsystem* ULocationConstraint::GetLocations() const
|
||||
{
|
||||
UWorld* World = Player ? Player->GetWorld() : nullptr;
|
||||
return World ? World->GetSubsystem<ULocationSubsystem>() : nullptr;
|
||||
}
|
||||
|
||||
FText ULocationConstraint::GetDescription() const
|
||||
{
|
||||
return FText::Format(LOCTEXT("AtLocation", "while at {0}"), FText::FromName(RequiredLocation.GetTagName()));
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,35 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "NakedDesire/Commissions/CommissionConstraint.h"
|
||||
#include "LocationConstraint.generated.h"
|
||||
|
||||
class ULocationData;
|
||||
class ULocationSubsystem;
|
||||
|
||||
// Holds while the player occupies a location matching (or nesting under) RequiredLocation.
|
||||
UCLASS(EditInlineNew, DisplayName = "While At Location")
|
||||
class NAKEDDESIRE_API ULocationConstraint : public UCommissionConstraint
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual bool IsMet() const override;
|
||||
virtual FText GetDescription() const override;
|
||||
|
||||
protected:
|
||||
virtual void OnActivate() override;
|
||||
virtual void OnDeactivate() override;
|
||||
|
||||
private:
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
FGameplayTag RequiredLocation;
|
||||
|
||||
UFUNCTION()
|
||||
void HandleLocationChanged(ULocationData* Location);
|
||||
|
||||
ULocationSubsystem* GetLocations() const;
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
|
||||
#include "ObservedConstraint.h"
|
||||
|
||||
#include "NakedDesire/Player/NakedDesireCharacter.h"
|
||||
#include "NakedDesire/Stats/StatsManager.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Commissions.Constraints.Observed"
|
||||
|
||||
void UObservedConstraint::OnActivate()
|
||||
{
|
||||
if (Player && Player->StatsManager)
|
||||
Player->StatsManager->OnObserversChanged.AddUniqueDynamic(this, &UObservedConstraint::HandleObserversChanged);
|
||||
}
|
||||
|
||||
void UObservedConstraint::OnDeactivate()
|
||||
{
|
||||
if (Player && Player->StatsManager)
|
||||
Player->StatsManager->OnObserversChanged.RemoveDynamic(this, &UObservedConstraint::HandleObserversChanged);
|
||||
}
|
||||
|
||||
bool UObservedConstraint::IsMet() const
|
||||
{
|
||||
if (!Player || !Player->StatsManager)
|
||||
return false;
|
||||
|
||||
return Player->StatsManager->GetObserverCount() >= MinObservers;
|
||||
}
|
||||
|
||||
void UObservedConstraint::HandleObserversChanged()
|
||||
{
|
||||
NotifyChanged();
|
||||
}
|
||||
|
||||
FText UObservedConstraint::GetDescription() const
|
||||
{
|
||||
return (MinObservers == 1)
|
||||
? LOCTEXT("Single", "while someone is watching")
|
||||
: FText::Format(LOCTEXT("Multiple", "while {0} people are watching"), FText::AsNumber(MinObservers));
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,29 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "NakedDesire/Commissions/CommissionConstraint.h"
|
||||
#include "ObservedConstraint.generated.h"
|
||||
|
||||
// Holds only while at least MinObservers NPCs are perceiving the player (the embarrassment observer set).
|
||||
UCLASS(EditInlineNew, DisplayName = "While Observed By N NPCs")
|
||||
class NAKEDDESIRE_API UObservedConstraint : public UCommissionConstraint
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual bool IsMet() const override;
|
||||
virtual FText GetDescription() const override;
|
||||
|
||||
protected:
|
||||
virtual void OnActivate() override;
|
||||
virtual void OnDeactivate() override;
|
||||
|
||||
private:
|
||||
UPROPERTY(EditDefaultsOnly, meta = (ClampMin = 1))
|
||||
int32 MinObservers = 1;
|
||||
|
||||
UFUNCTION()
|
||||
void HandleObserversChanged();
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
|
||||
#include "WearingSlotConstraint.h"
|
||||
|
||||
#include "NakedDesire/Clothing/ClothingManager.h"
|
||||
#include "NakedDesire/Player/NakedDesireCharacter.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Commissions.Constraints.WearingSlot"
|
||||
|
||||
void UWearingSlotConstraint::OnActivate()
|
||||
{
|
||||
if (Player && Player->ClothingManager)
|
||||
{
|
||||
Player->ClothingManager->OnClothingEquip.AddUniqueDynamic(this, &UWearingSlotConstraint::HandleClothingChanged);
|
||||
Player->ClothingManager->OnClothingUnequip.AddUniqueDynamic(this, &UWearingSlotConstraint::HandleClothingChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void UWearingSlotConstraint::OnDeactivate()
|
||||
{
|
||||
if (Player && Player->ClothingManager)
|
||||
{
|
||||
Player->ClothingManager->OnClothingEquip.RemoveDynamic(this, &UWearingSlotConstraint::HandleClothingChanged);
|
||||
Player->ClothingManager->OnClothingUnequip.RemoveDynamic(this, &UWearingSlotConstraint::HandleClothingChanged);
|
||||
}
|
||||
}
|
||||
|
||||
bool UWearingSlotConstraint::IsMet() const
|
||||
{
|
||||
if (!Player || !Player->ClothingManager)
|
||||
return false;
|
||||
|
||||
return Player->ClothingManager->IsClothingTypeOn(Slot) == bMustBeWorn;
|
||||
}
|
||||
|
||||
void UWearingSlotConstraint::HandleClothingChanged(UClothingItemInstance* ClothingItemInstance)
|
||||
{
|
||||
NotifyChanged();
|
||||
}
|
||||
|
||||
FText UWearingSlotConstraint::GetDescription() const
|
||||
{
|
||||
return bMustBeWorn
|
||||
? LOCTEXT("Wearing", "while dressed in the required item")
|
||||
: LOCTEXT("NotWearing", "while that slot is bare");
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,36 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "NakedDesire/Clothing/ClothingSlotType.h"
|
||||
#include "NakedDesire/Commissions/CommissionConstraint.h"
|
||||
#include "WearingSlotConstraint.generated.h"
|
||||
|
||||
class UClothingItemInstance;
|
||||
|
||||
// Holds while the chosen slot is occupied (bMustBeWorn) or empty (!bMustBeWorn). Covers both
|
||||
// "while wearing a coat" (Outerwear occupied) and "while not wearing a top" (Top empty).
|
||||
UCLASS(EditInlineNew, DisplayName = "While Wearing / Not Wearing Slot")
|
||||
class NAKEDDESIRE_API UWearingSlotConstraint : public UCommissionConstraint
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual bool IsMet() const override;
|
||||
virtual FText GetDescription() const override;
|
||||
|
||||
protected:
|
||||
virtual void OnActivate() override;
|
||||
virtual void OnDeactivate() override;
|
||||
|
||||
private:
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
EClothingSlotType Slot = EClothingSlotType::Outerwear;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
bool bMustBeWorn = true;
|
||||
|
||||
UFUNCTION()
|
||||
void HandleClothingChanged(UClothingItemInstance* ClothingItemInstance);
|
||||
};
|
||||
Reference in New Issue
Block a user