Refactor censorship
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
|
||||
#include "CensorshipComponent.h"
|
||||
|
||||
#include "Components/StaticMeshComponent.h"
|
||||
#include "NakedDesire/Clothing/BodyPart.h"
|
||||
#include "NakedDesire/Clothing/ClothingManager.h"
|
||||
#include "NakedDesire/Global/Constants.h"
|
||||
#include "NakedDesire/Global/NakedDesireUserSettings.h"
|
||||
|
||||
UCensorshipComponent::UCensorshipComponent()
|
||||
{
|
||||
PrimaryComponentTick.bCanEverTick = false;
|
||||
}
|
||||
|
||||
void UCensorshipComponent::Initialize(UClothingManager* InClothingManager,
|
||||
UStaticMeshComponent* InBoobL, UStaticMeshComponent* InBoobR,
|
||||
UStaticMeshComponent* InVagina, UStaticMeshComponent* InAnal)
|
||||
{
|
||||
ClothingManager = InClothingManager;
|
||||
BoobLCensorship = InBoobL;
|
||||
BoobRCensorship = InBoobR;
|
||||
VaginaCensorship = InVagina;
|
||||
AnalCensorship = InAnal;
|
||||
|
||||
if (ClothingManager)
|
||||
{
|
||||
ClothingManager->OnClothingEquip.AddUniqueDynamic(this, &UCensorshipComponent::HandleClothingChanged);
|
||||
ClothingManager->OnClothingUnequip.AddUniqueDynamic(this, &UCensorshipComponent::HandleClothingChanged);
|
||||
}
|
||||
|
||||
if (UNakedDesireUserSettings* Settings = UNakedDesireUserSettings::GetNakedDesireUserSettings())
|
||||
{
|
||||
Settings->OnSettingsChanged.AddUniqueDynamic(this, &UCensorshipComponent::HandleSettingsChanged);
|
||||
}
|
||||
|
||||
RefreshCensorship();
|
||||
}
|
||||
|
||||
void UCensorshipComponent::RefreshCensorship()
|
||||
{
|
||||
if (!ClothingManager)
|
||||
return;
|
||||
|
||||
const bool bCensor = ShouldCensor();
|
||||
|
||||
SetBodyPartCensored(EBodyPart::Boobs, bCensor && ClothingManager->IsBodyPartExposed(EBodyPart::Boobs));
|
||||
SetBodyPartCensored(EBodyPart::Genitals, bCensor && ClothingManager->IsBodyPartExposed(EBodyPart::Genitals));
|
||||
SetBodyPartCensored(EBodyPart::Ass, bCensor && ClothingManager->IsBodyPartExposed(EBodyPart::Ass));
|
||||
}
|
||||
|
||||
void UCensorshipComponent::HandleClothingChanged(UClothingItemInstance* ClothingItemInstance)
|
||||
{
|
||||
RefreshCensorship();
|
||||
}
|
||||
|
||||
void UCensorshipComponent::HandleSettingsChanged(UNakedDesireUserSettings* Settings)
|
||||
{
|
||||
RefreshCensorship();
|
||||
}
|
||||
|
||||
bool UCensorshipComponent::ShouldCensor() const
|
||||
{
|
||||
if (IS_DEMO)
|
||||
return true;
|
||||
|
||||
const UNakedDesireUserSettings* Settings = UNakedDesireUserSettings::GetNakedDesireUserSettings();
|
||||
return Settings && Settings->GetIsCensorshipEnabled();
|
||||
}
|
||||
|
||||
void UCensorshipComponent::SetBodyPartCensored(EBodyPart BodyPart, bool bCensored)
|
||||
{
|
||||
switch (BodyPart)
|
||||
{
|
||||
case EBodyPart::Boobs:
|
||||
if (BoobLCensorship)
|
||||
BoobLCensorship->SetVisibility(bCensored);
|
||||
if (BoobRCensorship)
|
||||
BoobRCensorship->SetVisibility(bCensored);
|
||||
break;
|
||||
case EBodyPart::Genitals:
|
||||
if (VaginaCensorship)
|
||||
VaginaCensorship->SetVisibility(bCensored);
|
||||
break;
|
||||
case EBodyPart::Ass:
|
||||
if (AnalCensorship)
|
||||
AnalCensorship->SetVisibility(bCensored);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "CensorshipComponent.generated.h"
|
||||
|
||||
class UClothingManager;
|
||||
class UClothingItemInstance;
|
||||
class UNakedDesireUserSettings;
|
||||
class UStaticMeshComponent;
|
||||
enum class EBodyPart : uint8;
|
||||
|
||||
/**
|
||||
* Owns the show/hide logic for the body-part censorship meshes. The meshes
|
||||
* themselves stay on the character (BP-authored assets + fitted transforms);
|
||||
* this component just drives their visibility from the equipped set + setting.
|
||||
*/
|
||||
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
||||
class NAKEDDESIRE_API UCensorshipComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCensorshipComponent();
|
||||
|
||||
/**
|
||||
* Wire dependencies and apply the initial censorship state. Call from the
|
||||
* owning character's BeginPlay *after* Super::BeginPlay, so clothing
|
||||
* hydration has already populated the equipped set.
|
||||
*/
|
||||
void Initialize(UClothingManager* InClothingManager,
|
||||
UStaticMeshComponent* InBoobL, UStaticMeshComponent* InBoobR,
|
||||
UStaticMeshComponent* InVagina, UStaticMeshComponent* InAnal);
|
||||
|
||||
/** Recompute every censor mesh from the current equipped set + setting. Idempotent. */
|
||||
void RefreshCensorship();
|
||||
|
||||
private:
|
||||
UFUNCTION()
|
||||
void HandleClothingChanged(UClothingItemInstance* ClothingItemInstance);
|
||||
|
||||
UFUNCTION()
|
||||
void HandleSettingsChanged(UNakedDesireUserSettings* Settings);
|
||||
|
||||
/** Censorship is forced on in the demo build regardless of the user setting. */
|
||||
bool ShouldCensor() const;
|
||||
|
||||
void SetBodyPartCensored(EBodyPart BodyPart, bool bCensored);
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UClothingManager> ClothingManager;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UStaticMeshComponent> BoobLCensorship;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UStaticMeshComponent> BoobRCensorship;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UStaticMeshComponent> VaginaCensorship;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UStaticMeshComponent> AnalCensorship;
|
||||
};
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "EnhancedInputSubsystems.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "Internationalization/Text.h"
|
||||
#include "NakedDesire/Censorship/CensorshipComponent.h"
|
||||
#include "NakedDesire/Clothing/ClothingItemDefinition.h"
|
||||
#include "NakedDesire/Clothing/ClothingItemInstance.h"
|
||||
#include "NakedDesire/Global/Constants.h"
|
||||
@@ -78,6 +79,8 @@ ANakedDesireCharacter::ANakedDesireCharacter()
|
||||
AnalCensorship = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Anal Censorship"));
|
||||
AnalCensorship->SetupAttachment(GetMesh(), FName(TEXT("pelvis")));
|
||||
|
||||
CensorshipComponent = CreateDefaultSubobject<UCensorshipComponent>(TEXT("Censorship Component"));
|
||||
|
||||
StimuliSourceComponent = CreateDefaultSubobject<UAIPerceptionStimuliSourceComponent>(TEXT("Stimuli Source Component"));
|
||||
InteractionComponent = CreateDefaultSubobject<UInteractionComponent>(TEXT("Interaction Component"));
|
||||
}
|
||||
@@ -153,12 +156,11 @@ void ANakedDesireCharacter::BeginPlay()
|
||||
StimuliSourceComponent->RegisterForSense(TSubclassOf<UAISense_Sight>());
|
||||
StimuliSourceComponent->RegisterWithPerceptionSystem();
|
||||
|
||||
ClothingManager->OnClothingEquip.AddUniqueDynamic(this, &ANakedDesireCharacter::OnClothingEquip);
|
||||
ClothingManager->OnClothingUnequip.AddUniqueDynamic(this, &ANakedDesireCharacter::OnClothingUnequip);
|
||||
|
||||
HUD = Cast<ANakedDesireHUD>(UGameplayStatics::GetPlayerController(GetWorld(), 0)->GetHUD());
|
||||
// Initialize after Super::BeginPlay so clothing hydration has populated the
|
||||
// equipped set; the component recomputes censorship from that final state.
|
||||
CensorshipComponent->Initialize(ClothingManager, BoobLCensorship, BoobRCensorship, VaginaCensorship, AnalCensorship);
|
||||
|
||||
UNakedDesireUserSettings::GetNakedDesireUserSettings()->OnSettingsChanged.AddUniqueDynamic(this, &ANakedDesireCharacter::OnSettingsChanged);
|
||||
HUD = Cast<ANakedDesireHUD>(UGameplayStatics::GetPlayerController(GetWorld(), 0)->GetHUD());
|
||||
}
|
||||
|
||||
UAISense_Sight::EVisibilityResult ANakedDesireCharacter::CanBeSeenFrom(const FCanBeSeenFromContext& Context,
|
||||
@@ -225,70 +227,6 @@ void ANakedDesireCharacter::LogTest()
|
||||
UE_LOG(LogTemp, Warning, TEXT("ANakedDesireCharacter::LogTest %s"), *ClothingItemInstance->GetInstanceId().ToString());
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnClothingEquip(UClothingItemInstance* ClothingItemInstance)
|
||||
{
|
||||
if (ClothingItemInstance->GetClothingItemDefinition()->HiddenBodyParts.Contains(EBodyPart::Ass))
|
||||
{
|
||||
AnalCensorship->SetVisibility(false);
|
||||
}
|
||||
if (ClothingItemInstance->GetClothingItemDefinition()->HiddenBodyParts.Contains(EBodyPart::Genitals))
|
||||
{
|
||||
VaginaCensorship->SetVisibility(false);
|
||||
}
|
||||
if (ClothingItemInstance->GetClothingItemDefinition()->HiddenBodyParts.Contains(EBodyPart::Boobs))
|
||||
{
|
||||
BoobLCensorship->SetVisibility(false);
|
||||
BoobRCensorship->SetVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnClothingUnequip(UClothingItemInstance* ClothingItemInstance)
|
||||
{
|
||||
if (!UNakedDesireUserSettings::GetNakedDesireUserSettings()->GetIsCensorshipEnabled() && !IS_DEMO)
|
||||
return;
|
||||
|
||||
if (ClothingManager->IsBodyPartExposed(EBodyPart::Ass))
|
||||
{
|
||||
AnalCensorship->SetVisibility(true);
|
||||
}
|
||||
if (ClothingManager->IsBodyPartExposed(EBodyPart::Genitals))
|
||||
{
|
||||
VaginaCensorship->SetVisibility(true);
|
||||
}
|
||||
if (ClothingManager->IsBodyPartExposed(EBodyPart::Boobs))
|
||||
{
|
||||
BoobLCensorship->SetVisibility(true);
|
||||
BoobRCensorship->SetVisibility(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnSettingsChanged(UNakedDesireUserSettings* Settings)
|
||||
{
|
||||
if (Settings->GetIsCensorshipEnabled())
|
||||
{
|
||||
if (ClothingManager->IsBodyPartExposed(EBodyPart::Ass))
|
||||
{
|
||||
AnalCensorship->SetVisibility(true);
|
||||
}
|
||||
if (ClothingManager->IsBodyPartExposed(EBodyPart::Genitals))
|
||||
{
|
||||
VaginaCensorship->SetVisibility(true);
|
||||
}
|
||||
if (ClothingManager->IsBodyPartExposed(EBodyPart::Boobs))
|
||||
{
|
||||
BoobLCensorship->SetVisibility(true);
|
||||
BoobRCensorship->SetVisibility(true);
|
||||
}
|
||||
}
|
||||
else if (!IS_DEMO)
|
||||
{
|
||||
AnalCensorship->SetVisibility(false);
|
||||
VaginaCensorship->SetVisibility(false);
|
||||
BoobLCensorship->SetVisibility(false);
|
||||
BoobRCensorship->SetVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnLook(const FInputActionValue& Value)
|
||||
{
|
||||
const FVector2D MouseValue = Value.Get<FVector2D>();
|
||||
|
||||
@@ -19,6 +19,7 @@ class UClothingItemInstance;
|
||||
class UClothingSlotsData;
|
||||
class UAIPerceptionStimuliSourceComponent;
|
||||
class UClothingManager;
|
||||
class UCensorshipComponent;
|
||||
class UStatsManager;
|
||||
class UMissionsManager;
|
||||
class ANPCAIController;
|
||||
@@ -123,6 +124,9 @@ public:
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Censorship")
|
||||
UStaticMeshComponent* AnalCensorship;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Censorship")
|
||||
UCensorshipComponent* CensorshipComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Clothing")
|
||||
TObjectPtr<UClothingSlotsData> SlotsData;
|
||||
|
||||
@@ -172,15 +176,6 @@ private:
|
||||
EGait Gait = EGait::Walk;
|
||||
EStance Stance = EStance::Stand;
|
||||
|
||||
UFUNCTION()
|
||||
void OnClothingEquip(UClothingItemInstance* ClothingItemInstance);
|
||||
|
||||
UFUNCTION()
|
||||
void OnClothingUnequip(UClothingItemInstance* ClothingItemInstance);
|
||||
|
||||
UFUNCTION()
|
||||
void OnSettingsChanged(UNakedDesireUserSettings* Settings);
|
||||
|
||||
void OnLook(const FInputActionValue& Value);
|
||||
void OnMove(const FInputActionValue& Value);
|
||||
void OnRunPress(const FInputActionValue& Value);
|
||||
|
||||
Reference in New Issue
Block a user