Added save subsystem

This commit is contained in:
2026-05-22 16:23:59 +03:00
parent eb99038785
commit dfc4cf28cf
8 changed files with 137 additions and 53 deletions
@@ -1,4 +1 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "ClothingItemInstance.h"
+1 -1
View File
@@ -2,7 +2,7 @@
#pragma once
#define SLOT_NAME "Slot2"
inline const FString DefaultSaveSlotName = TEXT("Slot1");
#define SLOT_PLAYER 0
#define IS_DEMO false
#define STARTING_MONEY 1000
@@ -152,21 +152,12 @@ void ANakedDesireCharacter::BeginPlay()
StimuliSourceComponent->RegisterForSense(TSubclassOf<UAISense_Sight>());
StimuliSourceComponent->RegisterWithPerceptionSystem();
// UGlobalSaveGameData* SaveGameData = UGlobalSaveGameData::LoadOrCreateSaveGame(DefaultPlayerClothing, DefaultWardrobeClothing);
// if (SaveGameData)
// {
// Money = FMath::RoundToInt(SaveGameData->Money);
// }
SetupClothingSlots();
ClothingManager->OnClothingEquip.AddUniqueDynamic(this, &ANakedDesireCharacter::OnClothingEquip);
ClothingManager->OnClothingUnequip.AddUniqueDynamic(this, &ANakedDesireCharacter::OnClothingUnequip);
UNakedDesireUserSettings::GetNakedDesireUserSettings()->OnSettingsChanged.AddUniqueDynamic(this, &ANakedDesireCharacter::OnSettingsChanged);
// ClothingManager->HydrateClothing(SaveGameData);
}
UAISense_Sight::EVisibilityResult ANakedDesireCharacter::CanBeSeenFrom(const FCanBeSeenFromContext& Context,
@@ -7,59 +7,47 @@
UGlobalSaveGameData* UGlobalSaveGameData::CreateNewSaveGame()
{
UGlobalSaveGameData* NewSave = Cast<UGlobalSaveGameData>(
UGameplayStatics::CreateSaveGameObject(UGlobalSaveGameData::StaticClass())
);
UGlobalSaveGameData* NewSave = Cast<UGlobalSaveGameData>(UGameplayStatics::CreateSaveGameObject(StaticClass()));
if (!NewSave)
{
return nullptr;
}
// NewSave->Money = InMoney;
// for (const UClothingItemData* Item : CurrentWardrobeClothing)
// {
// NewSave->WardrobeClothing.Add(Item->ToSaveData());
// }
//
// for (const UClothingItemData* Item : CurrentPlayerClothing)
// {
// NewSave->PlayerClothing.Add(Item->ToSaveData());
// }
return NewSave;
}
UGlobalSaveGameData* UGlobalSaveGameData::LoadOrCreateSaveGame()
UGlobalSaveGameData* UGlobalSaveGameData::LoadOrCreateSaveGame(const FString& SlotName)
{
if (UGameplayStatics::DoesSaveGameExist(SLOT_NAME, SLOT_PLAYER))
{
return Cast<UGlobalSaveGameData>(
UGameplayStatics::LoadGameFromSlot(SLOT_NAME, SLOT_PLAYER)
);
}
if (UGlobalSaveGameData* ExistingSave = LoadGame(SlotName))
return ExistingSave;
UGlobalSaveGameData* NewSave = nullptr;
// if (DefaultWardrobeClothing && DefaultPlayerClothing)
// {
// NewSave = CreateNewSaveGame(DefaultWardrobeClothing->ClothingItems, DefaultPlayerClothing->ClothingItems, STARTING_MONEY);
// }
UGlobalSaveGameData* NewSave = CreateNewSaveGame();
if (NewSave)
{
UGameplayStatics::SaveGameToSlot(NewSave, SLOT_NAME, SLOT_PLAYER);
UGameplayStatics::SaveGameToSlot(NewSave, SlotName, SLOT_PLAYER);
}
return NewSave;
}
bool UGlobalSaveGameData::SaveGame()
UGlobalSaveGameData* UGlobalSaveGameData::LoadGame(const FString& SlotName)
{
// if (UGlobalSaveGameData* Save = CreateNewSaveGame(CurrentWardrobeClothing, CurrentPlayerClothing, (float)InMoney))
// {
// return UGameplayStatics::SaveGameToSlot(Save, SLOT_NAME, SLOT_PLAYER);
// }
if (UGameplayStatics::DoesSaveGameExist(SlotName, SLOT_PLAYER))
{
return Cast<UGlobalSaveGameData>(UGameplayStatics::LoadGameFromSlot(SlotName, SLOT_PLAYER));
}
return nullptr;
}
bool UGlobalSaveGameData::SaveGame(const FString& SlotName)
{
if (UGlobalSaveGameData* Save = CreateNewSaveGame())
{
return UGameplayStatics::SaveGameToSlot(Save, SlotName, SLOT_PLAYER);
}
return false;
}
@@ -4,8 +4,10 @@
#include "CoreMinimal.h"
#include "GameFramework/SaveGame.h"
#include "NakedDesire/Global/Constants.h"
#include "GlobalSaveGameData.generated.h"
struct FItemSaveRecord;
class UClothingList;
UCLASS()
@@ -14,17 +16,27 @@ class NAKEDDESIRE_API UGlobalSaveGameData : public USaveGame
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite, SaveGame)
static UGlobalSaveGameData* LoadOrCreateSaveGame(const FString& SlotName = DefaultSaveSlotName);
static UGlobalSaveGameData* LoadGame(const FString& SlotName = DefaultSaveSlotName);
static bool SaveGame(const FString& SlotName = DefaultSaveSlotName);
UPROPERTY(SaveGame)
bool HaveSeenTutorial = false;
UPROPERTY(BlueprintReadWrite, SaveGame)
UPROPERTY(SaveGame)
float Money = 0;
UFUNCTION(BlueprintCallable)
static UGlobalSaveGameData* LoadOrCreateSaveGame();
UFUNCTION(BlueprintCallable)
static bool SaveGame();
UPROPERTY(SaveGame)
TArray<FItemSaveRecord> WardrobeItems;
UPROPERTY(SaveGame)
TArray<FItemSaveRecord> EquippedItems;
UPROPERTY(SaceGame)
int32 DaysPassed = 0;
UPROPERTY(SaveGame)
float HourOfDay = 0.0f;
private:
static UGlobalSaveGameData* CreateNewSaveGame();
@@ -0,0 +1,24 @@
#pragma once
#include "CoreMinimal.h"
#include "ItemSaveRecord.generated.h"
class UClothingItem;
USTRUCT()
struct NAKEDDESIRE_API FItemSaveRecord
{
GENERATED_BODY()
UPROPERTY(SaveGame)
FGuid InstanceId;
UPROPERTY(SaveGame)
TSoftObjectPtr<UClothingItem> Definition;
UPROPERTY(SaveGame)
float Condition = 1.0f;
UPROPERTY(SaveGame)
FGuid ParentId;
};
@@ -0,0 +1,37 @@
#include "SaveSubsystem.h"
#include "GlobalSaveGameData.h"
#include "ItemSaveRecord.h"
void USaveSubsystem::LoadGame(const FString& SlotName)
{
UGlobalSaveGameData* Save = UGlobalSaveGameData::LoadGame(SlotName);
}
bool USaveSubsystem::SaveGame(const FString& SlotName)
{
return UGlobalSaveGameData::SaveGame(SlotName);
}
void USaveSubsystem::AddItem(const FItemSaveRecord& Record)
{
Items.Add(Record);
}
void USaveSubsystem::RemoveItem(const FGuid& InstanceId)
{
FItemSaveRecord* ItemSaveRecord = Items.FindByPredicate([InstanceId](FItemSaveRecord ItemSaveRecord)
{
return ItemSaveRecord.InstanceId == InstanceId;
});
if (ItemSaveRecord)
{
Items.Remove(*ItemSaveRecord);
}
}
void USaveSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
LoadGame();
}
@@ -0,0 +1,35 @@
#pragma once
#include "CoreMinimal.h"
#include "NakedDesire/Global/Constants.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "SaveSubsystem.generated.h"
class UGlobalSaveGameData;
struct FItemSaveRecord;
UCLASS()
class NAKEDDESIRE_API USaveSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
void LoadGame(const FString& SlotName = DefaultSaveSlotName);
bool SaveGame(const FString& SlotName = DefaultSaveSlotName);
const TArray<FItemSaveRecord>& GetItems() const { return Items; }
void AddItem(const FItemSaveRecord& Record);
void RemoveItem(const FGuid& InstanceId);
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
private:
UPROPERTY()
FString ActiveSlotName = DefaultSaveSlotName;
UPROPERTY()
TArray<FItemSaveRecord> Items;
UPROPERTY()
TObjectPtr<UGlobalSaveGameData> CurrentSave;
};