Added starting save data

This commit is contained in:
koritsa
2026-05-27 19:43:00 +03:00
parent 1d6c77998e
commit 7dc63b87af
12 changed files with 109 additions and 53 deletions
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -14,10 +14,10 @@ struct NAKEDDESIRE_API FBodyPartCoverage
{ {
GENERATED_BODY() GENERATED_BODY()
UPROPERTY() UPROPERTY(EditDefaultsOnly)
float Coverage = 1.0f; float Coverage = 1.0f;
UPROPERTY() UPROPERTY(EditDefaultsOnly)
EBodyPart BodyPart = EBodyPart::Ass; EBodyPart BodyPart = EBodyPart::Ass;
}; };
@@ -153,7 +153,7 @@ void UClothingManager::PutOnClothing(UClothingItemInstance* ClothingItemInstance
void UClothingManager::TakeClothing(UClothingItemInstance* ClothingItemInstance) void UClothingManager::TakeClothing(UClothingItemInstance* ClothingItemInstance)
{ {
const EClothingSlotType SlotType = ClothingItemInstance->GetClothingItem()->SlotType; const EClothingSlotType SlotType = ClothingItemInstance->GetClothingItem()->SlotType;
if (const UClothingItemInstance* ExistingClothing = *EquippedClothing.Find(SlotType)) if (EquippedClothing.Contains(SlotType))
{ {
DropClothing(SlotType); DropClothing(SlotType);
} }
@@ -175,10 +175,17 @@ void UClothingManager::TakeClothing(UClothingItemInstance* ClothingItemInstance)
UClothingItemInstance* UClothingManager::RemoveClothing(const EClothingSlotType ClothingSlotType) UClothingItemInstance* UClothingManager::RemoveClothing(const EClothingSlotType ClothingSlotType)
{ {
UClothingItemInstance* ExistingItem = *EquippedClothing.Find(ClothingSlotType); TObjectPtr<UClothingItemInstance>* ExistingItemRef = EquippedClothing.Find(ClothingSlotType);
if (!ExistingItemRef)
{
UE_LOG(LogTemp, Warning, TEXT("UClothingManager::RemoveClothing ExistingItemRef == nullptr"));
return nullptr;
}
UClothingItemInstance* ExistingItem = *ExistingItemRef;
if (!ExistingItem) if (!ExistingItem)
{ {
UE_LOG(LogTemp, Warning, TEXT("UClothingManager::RemoveClothing No clothing found")); UE_LOG(LogTemp, Warning, TEXT("UClothingManager::RemoveClothing ExistingItem == nullptr"));
return nullptr; return nullptr;
} }
@@ -5,11 +5,14 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "NakedDesireGameInstance.generated.h" #include "NakedDesireGameInstance.generated.h"
/** class UStartingSaveData;
*
*/
UCLASS() UCLASS()
class NAKEDDESIRE_API UNakedDesireGameInstance : public UGameInstance class NAKEDDESIRE_API UNakedDesireGameInstance : public UGameInstance
{ {
GENERATED_BODY() GENERATED_BODY()
};
public:
UPROPERTY(EditDefaultsOnly, Category = "Save")
TObjectPtr<UStartingSaveData> StartingSaveData;
};
@@ -14,6 +14,7 @@
#include "NakedDesireCharacter.generated.h" #include "NakedDesireCharacter.generated.h"
class ANakedDesireHUD; class ANakedDesireHUD;
class UClothingItem;
class UClothingItemInstance; class UClothingItemInstance;
class UClothingSlotsData; class UClothingSlotsData;
class URadialMenuController; class URadialMenuController;
@@ -10,38 +10,23 @@ UGlobalSaveGameData* UGlobalSaveGameData::CreateNewSaveGame()
UGlobalSaveGameData* NewSave = Cast<UGlobalSaveGameData>(UGameplayStatics::CreateSaveGameObject(StaticClass())); UGlobalSaveGameData* NewSave = Cast<UGlobalSaveGameData>(UGameplayStatics::CreateSaveGameObject(StaticClass()));
if (!NewSave) if (!NewSave)
return nullptr; return nullptr;
NewSave->Money = STARTING_MONEY; NewSave->Money = STARTING_MONEY;
return NewSave; return NewSave;
} }
UGlobalSaveGameData* UGlobalSaveGameData::LoadOrCreateSaveGame(const FString& SlotName)
{
if (UGlobalSaveGameData* ExistingSave = LoadGame(SlotName))
return ExistingSave;
UGlobalSaveGameData* NewSave = CreateNewSaveGame();
if (NewSave)
{
UGameplayStatics::SaveGameToSlot(NewSave, SlotName, SLOT_PLAYER);
}
return NewSave;
}
UGlobalSaveGameData* UGlobalSaveGameData::LoadGame(const FString& SlotName) UGlobalSaveGameData* UGlobalSaveGameData::LoadGame(const FString& SlotName)
{ {
if (UGameplayStatics::DoesSaveGameExist(SlotName, SLOT_PLAYER)) if (UGameplayStatics::DoesSaveGameExist(SlotName, SLOT_PLAYER))
{ {
return Cast<UGlobalSaveGameData>(UGameplayStatics::LoadGameFromSlot(SlotName, SLOT_PLAYER)); return Cast<UGlobalSaveGameData>(UGameplayStatics::LoadGameFromSlot(SlotName, SLOT_PLAYER));
} }
return nullptr; return nullptr;
} }
bool UGlobalSaveGameData::SaveGame(UGlobalSaveGameData* SaveGameData, const FString& SlotName) bool UGlobalSaveGameData::SaveGame(UGlobalSaveGameData* SaveGameData, const FString& SlotName)
{ {
return UGameplayStatics::SaveGameToSlot(SaveGameData, SlotName, SLOT_PLAYER); return UGameplayStatics::SaveGameToSlot(SaveGameData, SlotName, SLOT_PLAYER);
} }
@@ -15,31 +15,28 @@ class NAKEDDESIRE_API UGlobalSaveGameData : public USaveGame
GENERATED_BODY() GENERATED_BODY()
public: public:
static UGlobalSaveGameData* LoadOrCreateSaveGame(const FString& SlotName = DefaultSaveSlotName); static UGlobalSaveGameData* CreateNewSaveGame();
static UGlobalSaveGameData* LoadGame(const FString& SlotName = DefaultSaveSlotName); static UGlobalSaveGameData* LoadGame(const FString& SlotName = DefaultSaveSlotName);
static bool SaveGame(UGlobalSaveGameData* SaveGameData, const FString& SlotName = DefaultSaveSlotName); static bool SaveGame(UGlobalSaveGameData* SaveGameData, const FString& SlotName = DefaultSaveSlotName);
UPROPERTY(SaveGame) UPROPERTY(SaveGame)
bool HaveSeenTutorial = false; bool HaveSeenTutorial = false;
UPROPERTY(SaveGame) UPROPERTY(SaveGame)
float Money = 0; float Money = 0;
UPROPERTY(SaveGame) UPROPERTY(SaveGame)
TArray<FItemSaveRecord> WardrobeItems; TArray<FItemSaveRecord> WardrobeItems;
UPROPERTY(SaveGame) UPROPERTY(SaveGame)
TArray<FItemSaveRecord> EquippedItems; TArray<FItemSaveRecord> EquippedItems;
UPROPERTY(SaveGame) UPROPERTY(SaveGame)
TArray<FItemSaveRecord> DroppedItems; TArray<FItemSaveRecord> DroppedItems;
UPROPERTY(SaveGame) UPROPERTY(SaveGame)
int32 DaysPassed = 0; int32 DaysPassed = 0;
UPROPERTY(SaveGame) UPROPERTY(SaveGame)
float HourOfDay = 0.0f; float HourOfDay = 0.0f;
};
private:
static UGlobalSaveGameData* CreateNewSaveGame();
};
+40 -3
View File
@@ -1,6 +1,14 @@
// © 2025 Naked People Team. All Rights Reserved.
#include "SaveSubsystem.h" #include "SaveSubsystem.h"
#include "GlobalSaveGameData.h" #include "GlobalSaveGameData.h"
#include "ItemSaveRecord.h" #include "ItemSaveRecord.h"
#include "StartingSaveData.h"
#include "NakedDesire/Clothing/ClothingItem.h"
#include "NakedDesire/Clothing/ClothingItemInstance.h"
#include "NakedDesire/Global/NakedDesireGameInstance.h"
void USaveSubsystem::LoadGame(const FString& SlotName) void USaveSubsystem::LoadGame(const FString& SlotName)
{ {
@@ -28,7 +36,7 @@ void USaveSubsystem::RemoveItem(const FGuid& InstanceId)
void USaveSubsystem::Initialize(FSubsystemCollectionBase& Collection) void USaveSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{ {
Super::Initialize(Collection); Super::Initialize(Collection);
LoadGame(); LoadGame();
} }
@@ -36,8 +44,37 @@ UGlobalSaveGameData* USaveSubsystem::GetCurrentSave()
{ {
if (!CurrentSave) if (!CurrentSave)
{ {
CurrentSave = UGlobalSaveGameData::LoadOrCreateSaveGame(ActiveSlotName); CurrentSave = UGlobalSaveGameData::LoadGame(ActiveSlotName);
if (!CurrentSave)
{
CurrentSave = UGlobalSaveGameData::CreateNewSaveGame();
PopulateStartingData(CurrentSave);
UGlobalSaveGameData::SaveGame(CurrentSave, ActiveSlotName);
}
} }
return CurrentSave; return CurrentSave;
} }
void USaveSubsystem::PopulateStartingData(UGlobalSaveGameData* Save) const
{
if (!Save)
return;
const UNakedDesireGameInstance* GameInstance = Cast<UNakedDesireGameInstance>(GetGameInstance());
if (!GameInstance || !GameInstance->StartingSaveData)
return;
for (UClothingItem* ClothingDef : GameInstance->StartingSaveData->StartingClothing)
{
if (!ClothingDef)
continue;
UClothingItemInstance* Instance = NewObject<UClothingItemInstance>(Save);
Instance->Init(ClothingDef);
FItemSaveRecord Record;
Record.Init(Instance);
Save->EquippedItems.Add(Record);
}
}
+12 -8
View File
@@ -1,3 +1,5 @@
// © 2025 Naked People Team. All Rights Reserved.
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
@@ -12,26 +14,28 @@ UCLASS()
class NAKEDDESIRE_API USaveSubsystem : public UGameInstanceSubsystem class NAKEDDESIRE_API USaveSubsystem : public UGameInstanceSubsystem
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
void LoadGame(const FString& SlotName = DefaultSaveSlotName); void LoadGame(const FString& SlotName = DefaultSaveSlotName);
bool SaveGame(const FString& SlotName = DefaultSaveSlotName) const; bool SaveGame(const FString& SlotName = DefaultSaveSlotName) const;
const TArray<FItemSaveRecord>& GetItems() const { return Items; } const TArray<FItemSaveRecord>& GetItems() const { return Items; }
void AddItem(const FItemSaveRecord& Record); void AddItem(const FItemSaveRecord& Record);
void RemoveItem(const FGuid& InstanceId); void RemoveItem(const FGuid& InstanceId);
virtual void Initialize(FSubsystemCollectionBase& Collection) override; virtual void Initialize(FSubsystemCollectionBase& Collection) override;
UGlobalSaveGameData* GetCurrentSave(); UGlobalSaveGameData* GetCurrentSave();
private: private:
void PopulateStartingData(UGlobalSaveGameData* Save) const;
UPROPERTY() UPROPERTY()
FString ActiveSlotName = DefaultSaveSlotName; FString ActiveSlotName = DefaultSaveSlotName;
UPROPERTY() UPROPERTY()
TArray<FItemSaveRecord> Items; TArray<FItemSaveRecord> Items;
UPROPERTY() UPROPERTY()
TObjectPtr<UGlobalSaveGameData> CurrentSave; TObjectPtr<UGlobalSaveGameData> CurrentSave;
}; };
@@ -0,0 +1,19 @@
// © 2025 Naked People Team. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "StartingSaveData.generated.h"
class UClothingItem;
UCLASS()
class NAKEDDESIRE_API UStartingSaveData : public UPrimaryDataAsset
{
GENERATED_BODY()
public:
UPROPERTY(EditDefaultsOnly, Category = "Starting State")
TArray<TObjectPtr<UClothingItem>> StartingClothing;
};