// © 2025 Naked People Team. All Rights Reserved. #include "ClothingManager.h" #include "ClothingItemData.h" #include "GameFramework/Character.h" #include "NakedDesire/SaveGame/GlobalSaveGameData.h" UClothingManager::UClothingManager() { PrimaryComponentTick.bCanEverTick = false; } bool UClothingManager::IsBodyTypeExposed(const EPrivateBodyPartType PrivateBodyPartType) { for (const auto& ClothingSlot : ClothingSlots) { if (ClothingSlot.ClothingData && ClothingSlot.ClothingData->Info->CoveredBodyParts.Contains(PrivateBodyPartType)) { return false; } } return true; } bool UClothingManager::GetClothingSlotData(const EClothingSlotType ClothingSlotType, FClothingSlotData& OutClothingSlotData) { for (const auto& ClothingSlot : ClothingSlots) { if (ClothingSlot.ClothingSlotType == ClothingSlotType) { OutClothingSlotData = ClothingSlot; return true; } } return false; } void UClothingManager::SetClothingSlotItem(const EClothingSlotType ClothingSlotType, UClothingItemData* ClothingItem) { for (FClothingSlotData& ClothingSlot : ClothingSlots) { if (ClothingSlot.ClothingSlotType == ClothingSlotType) { ClothingSlot.ClothingData = ClothingItem; } } } TArray UClothingManager::GetEquippedClothing() { TArray EquippedClothingItems; for (FClothingSlotData ClothingSlot : ClothingSlots) { if (ClothingSlot.ClothingData) { EquippedClothingItems.Add(ClothingSlot.ClothingData); } } return EquippedClothingItems; } void UClothingManager::HydrateClothing(UGlobalSaveGameData* SaveGameData) { for (const FClothingItemSaveData& ClothingItemSaveData : SaveGameData->PlayerClothing) { UClothingItemData* ClothingItemData = UClothingItemData::CreateFromSaveData(ClothingItemSaveData); PutOnClothing(ClothingItemData); } } float UClothingManager::GetHeelHeight() { if (FClothingSlotData ClothingSlotData; GetClothingSlotData(EClothingSlotType::Shoes, ClothingSlotData)) { if (ClothingSlotData.ClothingData) { return ClothingSlotData.ClothingData->Info->ShoesOffset; } } return 0; } void UClothingManager::PutOnClothing(UClothingItemData* ClothingData) { if (!ClothingData) { return; } const EClothingSlotType ClothingSlotType = ClothingData->Info->SlotType; FClothingSlotData ClothingSlotData; GetClothingSlotData(ClothingSlotType, ClothingSlotData); ClothingSlotData.MeshComponent->SetSkeletalMesh(ClothingData->Info->SkeletalMesh); if (!ClothingData->Info->Materials.IsEmpty()) { for (const TPair& Material : ClothingData->Info->Materials) { ClothingSlotData.MeshComponent->SetMaterialByName(Material.Key, Material.Value); } } SetClothingSlotItem(ClothingSlotType, ClothingData); if (ClothingData->Info->UseLeaderPose) { ClothingSlotData.MeshComponent->SetLeaderPoseComponent(Cast(GetOwner())->GetMesh()); } OnClothingEquip.Broadcast(ClothingData); } void UClothingManager::TakeClothing(UClothingItemData* ClothingData) { if (!ClothingData->Info) { return; } FClothingSlotData ClothingSlotData; GetClothingSlotData(ClothingData->Info->SlotType, ClothingSlotData); if (ClothingSlotData.ClothingData->Info) { DropClothing(ClothingData->Info->SlotType); } ClothingSlotData.ClothingData = ClothingData; PutOnClothing(ClothingData); } UClothingItemData* UClothingManager::RemoveClothing(const EClothingSlotType ClothingSlotType) { FClothingSlotData ClothingSlotData; if (!GetClothingSlotData(ClothingSlotType, ClothingSlotData) || !ClothingSlotData.ClothingData) { UE_LOG(LogTemp, Error, TEXT("Couldn't find clothing slot")); return nullptr; } UClothingItemData* ClothingData = ClothingSlotData.ClothingData; SetClothingSlotItem(ClothingSlotType, nullptr); USkeletalMeshComponent* MeshComponent = ClothingSlotData.MeshComponent; MeshComponent->SetSkeletalMesh(nullptr); if (ClothingData->Info->UseLeaderPose) { ClothingSlotData.MeshComponent->SetLeaderPoseComponent(nullptr); } OnClothingUnequip.Broadcast(ClothingData); return ClothingData; } void UClothingManager::DropClothing(const EClothingSlotType ClothingType) { const UClothingItemData* ClothingData = RemoveClothing(ClothingType); if (!ClothingData) { return; } OnClothingDropped.Broadcast(ClothingData); } bool UClothingManager::IsClothingTypeOn(const EClothingSlotType ClothingType) { FClothingSlotData ClothingSlotData; GetClothingSlotData(ClothingType, ClothingSlotData); const bool IsTypeOn = ClothingSlotData.ClothingData != nullptr; return IsTypeOn; } bool UClothingManager::IsPartiallyNaked() { return IsBodyTypeExposed(EPrivateBodyPartType::BackBottom) || IsBodyTypeExposed(EPrivateBodyPartType::FrontBottom) || IsBodyTypeExposed(EPrivateBodyPartType::FrontTop); }