From b6b81caf4e8e4061eab5f24f876a03a6adcb2b3b Mon Sep 17 00:00:00 2001 From: olehhapuk Date: Fri, 29 May 2026 18:57:20 +0300 Subject: [PATCH] Finished phase 1 --- Config/DefaultGame.ini | 4 +- .../NakedDesire/Clothing/ClothingManager.cpp | 30 ++---- .../Global/NakedDesireGameMode.cpp | 2 +- .../NakedDesire/Interactables/ItemPickup.cpp | 6 +- Source/NakedDesire/Interactables/Wardrobe.cpp | 14 +-- .../MissionBuilder/MissionsManager.cpp | 1 - .../Player/NakedDesireCharacter.cpp | 6 ++ .../NakedDesire/Player/NakedDesireCharacter.h | 3 + .../SaveGame/GlobalSaveGameData.cpp | 102 +++++++++++++++++- .../NakedDesire/SaveGame/GlobalSaveGameData.h | 37 +++++-- Source/NakedDesire/SaveGame/SaveSubsystem.cpp | 6 +- 11 files changed, 152 insertions(+), 59 deletions(-) diff --git a/Config/DefaultGame.ini b/Config/DefaultGame.ini index dcc49f71..be1cc79d 100644 --- a/Config/DefaultGame.ini +++ b/Config/DefaultGame.ini @@ -23,8 +23,8 @@ bSupportsTouch=False bSupportsGamepad=True DefaultGamepadName=Generic bCanChangeGamepadType=True -+ControllerData=/Game/Input/KeyboardControllerData.KeyboardControllerData_C -+ControllerData=/Game/Input/GamepadControllerData.GamepadControllerData_C ++ControllerData=/Game/Input/CommonUI/GamepadControllerData.GamepadControllerData_C ++ControllerData=/Game/Input/CommonUI/KeyboardControllerData.KeyboardControllerData_C [/Script/UnrealEd.ProjectPackagingSettings] Build=IfProjectHasCode diff --git a/Source/NakedDesire/Clothing/ClothingManager.cpp b/Source/NakedDesire/Clothing/ClothingManager.cpp index 5f76c218..cb7ecbee 100644 --- a/Source/NakedDesire/Clothing/ClothingManager.cpp +++ b/Source/NakedDesire/Clothing/ClothingManager.cpp @@ -61,7 +61,7 @@ bool UClothingManager::IsBodyPartExposed(const EBodyPart BodyPart) void UClothingManager::HydrateClothing() { USaveSubsystem* SaveSubsystem = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem(); - for (const FItemSaveRecord& ItemSaveRecord : SaveSubsystem->GetCurrentSave()->EquippedItems) + for (const FItemSaveRecord& ItemSaveRecord : SaveSubsystem->GetCurrentSave()->GetEquippedItems()) { UClothingItemInstance* ClothingItemInstance = UClothingItemInstance::CreateFromSave(this, ItemSaveRecord); PutOnClothing(ClothingItemInstance); @@ -125,10 +125,7 @@ void UClothingManager::SpawnClothingPickup(UClothingItemInstance* ItemInstance) } USaveSubsystem* SaveSubsystem = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem(); - FItemSaveRecord ItemSaveRecord; - ItemSaveRecord.Init(ItemInstance); - ItemSaveRecord.WorldTransform = NewItemPickup->GetActorTransform(); - SaveSubsystem->GetCurrentSave()->WorldItems.Push(ItemSaveRecord); + SaveSubsystem->GetCurrentSave()->AddWorldItem(ItemInstance, NewItemPickup->GetActorTransform()); NewItemPickup->SetItem(ItemInstance); } @@ -186,29 +183,17 @@ void UClothingManager::TakeClothing(UClothingItemInstance* ClothingItemInstance) SetClothingSlotItem(SlotType, ClothingItemInstance); USaveSubsystem* SaveSubsystem = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem(); - FItemSaveRecord ItemSaveRecord; - ItemSaveRecord.Init(ClothingItemInstance); - - SaveSubsystem->GetCurrentSave()->EquippedItems.Push(ItemSaveRecord); + SaveSubsystem->GetCurrentSave()->AddEquippedItem(ClothingItemInstance); PutOnClothing(ClothingItemInstance); } UClothingItemInstance* UClothingManager::RemoveClothing(const EClothingSlotType ClothingSlotType) { - TObjectPtr* ExistingItemRef = EquippedClothing.Find(ClothingSlotType); - if (!ExistingItemRef) - { - UE_LOG(LogTemp, Warning, TEXT("UClothingManager::RemoveClothing ExistingItemRef == nullptr")); + if (!EquippedClothing.Contains(ClothingSlotType)) return nullptr; - } - UClothingItemInstance* ExistingItem = *ExistingItemRef; - if (!ExistingItem) - { - UE_LOG(LogTemp, Warning, TEXT("UClothingManager::RemoveClothing ExistingItem == nullptr")); - return nullptr; - } + UClothingItemInstance* ExistingItem = EquippedClothing[ClothingSlotType]; SetClothingSlotItem(ClothingSlotType, nullptr); @@ -223,10 +208,7 @@ UClothingItemInstance* UClothingManager::RemoveClothing(const EClothingSlotType OnClothingUnequip.Broadcast(ExistingItem); USaveSubsystem* SaveSubsystem = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem(); - SaveSubsystem->GetCurrentSave()->EquippedItems.RemoveAll([ExistingItem](const FItemSaveRecord& Item) - { - return Item.InstanceId == ExistingItem->GetInstanceId(); - }); + SaveSubsystem->GetCurrentSave()->RemoveEquippedItem(ExistingItem); return ExistingItem; } diff --git a/Source/NakedDesire/Global/NakedDesireGameMode.cpp b/Source/NakedDesire/Global/NakedDesireGameMode.cpp index b79609e0..1201d45c 100644 --- a/Source/NakedDesire/Global/NakedDesireGameMode.cpp +++ b/Source/NakedDesire/Global/NakedDesireGameMode.cpp @@ -71,7 +71,7 @@ void ANakedDesireGameMode::BeginPlay() } USaveSubsystem* SaveSubsystem = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem(); - for (const auto& Item : SaveSubsystem->GetCurrentSave()->WorldItems) + for (const auto& Item : SaveSubsystem->GetCurrentSave()->GetWorldItems()) { UClothingItemInstance* NewItemInstance = NewObject(this); NewItemInstance->Init(Item.Definition.Get()); diff --git a/Source/NakedDesire/Interactables/ItemPickup.cpp b/Source/NakedDesire/Interactables/ItemPickup.cpp index 1539225c..dce2150b 100644 --- a/Source/NakedDesire/Interactables/ItemPickup.cpp +++ b/Source/NakedDesire/Interactables/ItemPickup.cpp @@ -10,7 +10,6 @@ #include "NakedDesire/Clothing/ClothingManager.h" #include "NakedDesire/Player/NakedDesireCharacter.h" #include "NakedDesire/SaveGame/GlobalSaveGameData.h" -#include "NakedDesire/SaveGame/ItemSaveRecord.h" #include "NakedDesire/SaveGame/SaveSubsystem.h" AItemPickup::AItemPickup() @@ -33,10 +32,7 @@ void AItemPickup::Interact_Implementation(ANakedDesireCharacter* Player) { USaveSubsystem* SaveSubsystem = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem(); Player->ClothingManager->TakeClothing(ClothingItemInstance); - SaveSubsystem->GetCurrentSave()->WorldItems.RemoveAll([this](const FItemSaveRecord& Item) - { - return ClothingItemInstance->GetInstanceId() == Item.InstanceId; - }); + SaveSubsystem->GetCurrentSave()->RemoveWorldItem(ClothingItemInstance); Destroy(); } } diff --git a/Source/NakedDesire/Interactables/Wardrobe.cpp b/Source/NakedDesire/Interactables/Wardrobe.cpp index 8c77e72f..cd70ee8b 100644 --- a/Source/NakedDesire/Interactables/Wardrobe.cpp +++ b/Source/NakedDesire/Interactables/Wardrobe.cpp @@ -10,22 +10,14 @@ void AWardrobe::AddItem(UClothingItemInstance* ClothingItemInstance) { USaveSubsystem* SaveSubsystem = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem(); - - ClothingItems.Push(ClothingItemInstance); - FItemSaveRecord ItemSaveRecord; - ItemSaveRecord.Init(ClothingItemInstance); - - SaveSubsystem->GetCurrentSave()->WardrobeItems.Push(ItemSaveRecord); + SaveSubsystem->GetCurrentSave()->AddWardrobeItem(ClothingItemInstance); } void AWardrobe::RemoveItem(UClothingItemInstance* ClothingItemInstance) const { USaveSubsystem* SaveSubsystem = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem(); - SaveSubsystem->GetCurrentSave()->WardrobeItems.RemoveAll([ClothingItemInstance](const FItemSaveRecord& Item) - { - return Item.InstanceId == ClothingItemInstance->GetInstanceId(); - }); + SaveSubsystem->GetCurrentSave()->RemoveWardrobeItem(ClothingItemInstance); } void AWardrobe::BeginPlay() @@ -35,7 +27,7 @@ void AWardrobe::BeginPlay() USaveSubsystem* SaveSubsystem = UGameplayStatics::GetGameInstance(GetWorld())->GetSubsystem(); UGlobalSaveGameData* SaveGame = SaveSubsystem->GetCurrentSave(); - for (const FItemSaveRecord& ItemSaveRecord : SaveGame->WardrobeItems) + for (const FItemSaveRecord& ItemSaveRecord : SaveGame->GetWardrobeItems()) { UClothingItemInstance* NewItemInstance = UClothingItemInstance::CreateFromSave(this, ItemSaveRecord); ClothingItems.Push(NewItemInstance); diff --git a/Source/NakedDesire/MissionBuilder/MissionsManager.cpp b/Source/NakedDesire/MissionBuilder/MissionsManager.cpp index 9de1a2dd..66dc56b3 100644 --- a/Source/NakedDesire/MissionBuilder/MissionsManager.cpp +++ b/Source/NakedDesire/MissionBuilder/MissionsManager.cpp @@ -16,7 +16,6 @@ void UMissionsManager::BeginPlay() Super::BeginPlay(); Player = Cast(GetOwner()); - UE_LOG(LogTemp, Warning, TEXT("Player is NULL %s"), Player == nullptr ? TEXT("True") : TEXT("False")); for (const auto& Mission : AvailableMissions) { diff --git a/Source/NakedDesire/Player/NakedDesireCharacter.cpp b/Source/NakedDesire/Player/NakedDesireCharacter.cpp index 21d18619..439fa50e 100644 --- a/Source/NakedDesire/Player/NakedDesireCharacter.cpp +++ b/Source/NakedDesire/Player/NakedDesireCharacter.cpp @@ -219,6 +219,12 @@ bool ANakedDesireCharacter::CheckSight(const FVector& StartLocation, const FVect return bHit; } +void ANakedDesireCharacter::LogTest() +{ + UClothingItemInstance* ClothingItemInstance = ClothingManager->GetSlotClothing(EClothingSlotType::UnderwearTop); + UE_LOG(LogTemp, Warning, TEXT("ANakedDesireCharacter::LogTest %s"), *ClothingItemInstance->GetInstanceId().ToString()); +} + void ANakedDesireCharacter::OnClothingEquip(UClothingItemInstance* ClothingItemInstance) { if (ClothingItemInstance->GetClothingItem()->HiddenBodyParts.Contains(EBodyPart::Ass)) diff --git a/Source/NakedDesire/Player/NakedDesireCharacter.h b/Source/NakedDesire/Player/NakedDesireCharacter.h index cb7701f5..c0f879f4 100644 --- a/Source/NakedDesire/Player/NakedDesireCharacter.h +++ b/Source/NakedDesire/Player/NakedDesireCharacter.h @@ -191,6 +191,9 @@ private: bool CheckSight(const FVector& StartLocation, const FVector& EndLocation, FHitResult& HitResult, const AActor* IgnoreActor); + UFUNCTION(Exec) + void LogTest(); + UPROPERTY() TObjectPtr HUD; }; diff --git a/Source/NakedDesire/SaveGame/GlobalSaveGameData.cpp b/Source/NakedDesire/SaveGame/GlobalSaveGameData.cpp index 7bbdf798..dffbf9c2 100644 --- a/Source/NakedDesire/SaveGame/GlobalSaveGameData.cpp +++ b/Source/NakedDesire/SaveGame/GlobalSaveGameData.cpp @@ -2,6 +2,8 @@ #include "GlobalSaveGameData.h" + +#include "ItemSaveRecord.h" #include "NakedDesire/Global/Constants.h" #include "Kismet/GameplayStatics.h" @@ -29,4 +31,102 @@ UGlobalSaveGameData* UGlobalSaveGameData::LoadGame(const FString& SlotName) bool UGlobalSaveGameData::SaveGame(UGlobalSaveGameData* SaveGameData, const FString& SlotName) { return UGameplayStatics::SaveGameToSlot(SaveGameData, SlotName, SLOT_PLAYER); -} \ No newline at end of file +} + +FItemSaveRecord UGlobalSaveGameData::AddWardrobeItem(const UClothingItemInstance* ItemInstance) +{ + FItemSaveRecord NewSaveRecord; + NewSaveRecord.Init(ItemInstance); + WardrobeItems.Push(NewSaveRecord); + return NewSaveRecord; +} + +bool UGlobalSaveGameData::UpdateWardrobeItem(UClothingItemInstance* ItemInstance) +{ + for (auto& ItemSaveRecord : WardrobeItems) + { + if (ItemSaveRecord.InstanceId == ItemInstance->GetInstanceId()) + { + ItemSaveRecord.Init(ItemInstance); + return true; + } + } + + return false; +} + +bool UGlobalSaveGameData::RemoveWardrobeItem(UClothingItemInstance* ItemInstance) +{ + const int32 RemovedElementsCount = WardrobeItems.RemoveAll([ItemInstance](const FItemSaveRecord& Item) + { + return Item.InstanceId == ItemInstance->GetInstanceId(); + }); + + return RemovedElementsCount > 0; +} + +FItemSaveRecord UGlobalSaveGameData::AddEquippedItem(const UClothingItemInstance* ItemInstance) +{ + FItemSaveRecord NewSaveRecord; + NewSaveRecord.Init(ItemInstance); + EquippedItems.Push(NewSaveRecord); + return NewSaveRecord; +} + +bool UGlobalSaveGameData::UpdateEquippedItem(UClothingItemInstance* ItemInstance) +{ + for (auto& ItemSaveRecord : EquippedItems) + { + if (ItemSaveRecord.InstanceId == ItemInstance->GetInstanceId()) + { + ItemSaveRecord.Init(ItemInstance); + return true; + } + } + + return false; +} + +bool UGlobalSaveGameData::RemoveEquippedItem(UClothingItemInstance* ItemInstance) +{ + const int32 RemovedElementsCount = EquippedItems.RemoveAll([ItemInstance](const FItemSaveRecord& Item) + { + return Item.InstanceId == ItemInstance->GetInstanceId(); + }); + + return RemovedElementsCount > 0; +} + +FItemSaveRecord UGlobalSaveGameData::AddWorldItem(const UClothingItemInstance* ItemInstance, FTransform Transform) +{ + FItemSaveRecord NewSaveRecord; + NewSaveRecord.Init(ItemInstance); + NewSaveRecord.WorldTransform = Transform; + WorldItems.Push(NewSaveRecord); + return NewSaveRecord; +} + +bool UGlobalSaveGameData::UpdateWorldItem(UClothingItemInstance* ItemInstance, FTransform Transform) +{ + for (auto& ItemSaveRecord : WorldItems) + { + if (ItemSaveRecord.InstanceId == ItemInstance->GetInstanceId()) + { + ItemSaveRecord.Init(ItemInstance); + ItemSaveRecord.WorldTransform = Transform; + return true; + } + } + + return false; +} + +bool UGlobalSaveGameData::RemoveWorldItem(UClothingItemInstance* ItemInstance) +{ + const int32 RemovedElementsCount = WorldItems.RemoveAll([ItemInstance](const FItemSaveRecord& Item) + { + return Item.InstanceId == ItemInstance->GetInstanceId(); + }); + + return RemovedElementsCount > 0; +} diff --git a/Source/NakedDesire/SaveGame/GlobalSaveGameData.h b/Source/NakedDesire/SaveGame/GlobalSaveGameData.h index 27d7875f..ede10cc1 100644 --- a/Source/NakedDesire/SaveGame/GlobalSaveGameData.h +++ b/Source/NakedDesire/SaveGame/GlobalSaveGameData.h @@ -5,9 +5,10 @@ #include "CoreMinimal.h" #include "GameFramework/SaveGame.h" #include "NakedDesire/Global/Constants.h" +#include "ItemSaveRecord.h" #include "GlobalSaveGameData.generated.h" -struct FItemSaveRecord; +class UClothingItemInstance; UCLASS() class NAKEDDESIRE_API UGlobalSaveGameData : public USaveGame @@ -24,19 +25,35 @@ public: UPROPERTY(SaveGame) float Money = 0; - - UPROPERTY(SaveGame) - TArray WardrobeItems; - - UPROPERTY(SaveGame) - TArray EquippedItems; - - UPROPERTY(SaveGame) - TArray WorldItems; + + FItemSaveRecord AddWardrobeItem(const UClothingItemInstance* ItemInstance); + bool UpdateWardrobeItem(UClothingItemInstance* ItemInstance); + bool RemoveWardrobeItem(UClothingItemInstance* ItemInstance); + TArray GetWardrobeItems() const { return WardrobeItems; } + + FItemSaveRecord AddEquippedItem(const UClothingItemInstance* ItemInstance); + bool UpdateEquippedItem(UClothingItemInstance* ItemInstance); + bool RemoveEquippedItem(UClothingItemInstance* ItemInstance); + TArray GetEquippedItems() const { return EquippedItems; } + + FItemSaveRecord AddWorldItem(const UClothingItemInstance* ItemInstance, FTransform Transform); + bool UpdateWorldItem(UClothingItemInstance* ItemInstance, FTransform Transform); + bool RemoveWorldItem(UClothingItemInstance* ItemInstance); + TArray GetWorldItems() const { return WorldItems; } UPROPERTY(SaveGame) int32 DaysPassed = 0; UPROPERTY(SaveGame) float HourOfDay = 0.0f; + +private: + UPROPERTY(SaveGame) + TArray WardrobeItems; + + UPROPERTY(SaveGame) + TArray EquippedItems; + + UPROPERTY(SaveGame) + TArray WorldItems; }; \ No newline at end of file diff --git a/Source/NakedDesire/SaveGame/SaveSubsystem.cpp b/Source/NakedDesire/SaveGame/SaveSubsystem.cpp index e334d2b0..bb3d641f 100644 --- a/Source/NakedDesire/SaveGame/SaveSubsystem.cpp +++ b/Source/NakedDesire/SaveGame/SaveSubsystem.cpp @@ -67,11 +67,9 @@ void USaveSubsystem::PopulateStartingData(UGlobalSaveGameData* Save) const if (!ClothingDef) continue; + // TODO: Refactor. Skip converting to ClothingItemInstance UClothingItemInstance* Instance = NewObject(Save); Instance->Init(ClothingDef); - - FItemSaveRecord Record; - Record.Init(Instance); - Save->EquippedItems.Add(Record); + Save->AddEquippedItem(Instance); } }