// © 2025 Naked People Team. All Rights Reserved. #include "Wardrobe.h" #include "Components/BoxComponent.h" #include "Components/WidgetComponent.h" #include "Kismet/GameplayStatics.h" #include "NakedDesire/Clothing/ClothingItemInstance.h" #include "NakedDesire/Global/NakedDesireHUD.h" #include "NakedDesire/Inventory/InventorySubsystem.h" #include "NakedDesire/Player/NakedDesireCharacter.h" #include "NakedDesire/UI/GameLayoutWidget.h" #define LOCTEXT_NAMESPACE "Wardrobe" AWardrobe::AWardrobe() { ColliderComponent = CreateDefaultSubobject(TEXT("Collider")); SetRootComponent(ColliderComponent); // Trace-only: detected by the interaction LOS/focus line traces (ECC_Visibility), // transparent to movement and physics. ColliderComponent->SetCollisionEnabled(ECollisionEnabled::QueryOnly); ColliderComponent->SetCollisionObjectType(ECC_WorldStatic); ColliderComponent->SetCollisionResponseToAllChannels(ECR_Ignore); ColliderComponent->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block); MeshComponent = CreateDefaultSubobject(TEXT("Mesh")); MeshComponent->SetupAttachment(RootComponent); // Movement blocker only: stops the character capsule (ECC_Pawn), but is invisible // to line traces so it never occludes the interaction LOS check. MeshComponent->SetCollisionEnabled(ECollisionEnabled::QueryOnly); MeshComponent->SetCollisionObjectType(ECC_WorldStatic); MeshComponent->SetCollisionResponseToAllChannels(ECR_Ignore); MeshComponent->SetCollisionResponseToChannel(ECC_Pawn, ECR_Block); InteractionHint = CreateDefaultSubobject(TEXT("Interaction Hint")); InteractionHint->SetupAttachment(RootComponent); } void AWardrobe::Interact_Implementation(ANakedDesireCharacter* Player) { APlayerController* PC = Cast(Player->GetController()); if (!PC) return; ANakedDesireHUD* HUD = Cast(PC->GetHUD()); if (!HUD) return; HUD->GetGameLayoutWidget()->OpenWardrobe(); } void AWardrobe::AddItem(UClothingItemInstance* ClothingItemInstance) { if (UInventorySubsystem* Inventory = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem()) Inventory->AddToWardrobe(ClothingItemInstance); } void AWardrobe::RemoveItem(UClothingItemInstance* ClothingItemInstance) { if (UInventorySubsystem* Inventory = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem()) Inventory->RemoveFromWardrobe(ClothingItemInstance); } void AWardrobe::BeginPlay() { Super::BeginPlay(); InteractionHint->SetVisibility(false); } bool AWardrobe::CanInteract_Implementation(ANakedDesireCharacter* Player) const { return true; } FText AWardrobe::GetInteractionPrompt_Implementation() const { return LOCTEXT("WardrobePrompt", "Open wardrobe"); } void AWardrobe::HideInteractionHint_Implementation() { ApplyOutline(false, 0); InteractionHint->SetVisibility(false); } void AWardrobe::ShowInteractionFocusHint_Implementation() { ApplyOutline(true, 2); InteractionHint->SetVisibility(true); } void AWardrobe::ShowInteractionProximityHint_Implementation() { ApplyOutline(true, 1); InteractionHint->SetVisibility(false); } void AWardrobe::ApplyOutline(bool bEnabled, int32 StencilValue) { MeshComponent->SetRenderCustomDepth(bEnabled); MeshComponent->SetCustomDepthStencilValue(StencilValue); } #undef LOCTEXT_NAMESPACE