Files
ProjectEleri/Source/ProjectEleri/Public/EleriSaveGame.h

142 lines
4.4 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/SaveGame.h"
#include "ProjectEleri/DialogueSystem/QuestDatabase.h"
#include "BookOfAlchemyManager.h"
#include "InventoryComponent.h"
#include "../System/Subsystem/ObjectPersistenceSubsystem.h"
#include "Interface/SaveableObjectInterface.h"
#include "ProjectEleri/GameEventSystem/GameEventSubsystem.h"
#include "ProjectEleri/QuestSystem/QuestTypes.h"
#include "Data/GameplayStatEffect.h"
#include "Data/StatForgeDefs.h"
#include "ProjectEleri/Items/SeedBedActor.h"
#include "ProjectEleri/System/TimeOfDayStruct.h"
#include "TimeOfDayManager.h"
#include "EleriSaveGame.generated.h"
USTRUCT()
struct FActiveGameplayStatEffect_SerializedData {
GENERATED_BODY()
public:
UPROPERTY()
TSubclassOf<UGameplayStatEffect> GameplayEffectClass;
UPROPERTY()
TMap<FName, float> DataValueMap;
UPROPERTY()
int32 StackCount = 1;
UPROPERTY()
float RemainingDuration = -1.f;
UPROPERTY()
float NextTickDuration = -1.f;
};
USTRUCT(BlueprintType)
struct FSaveData {
GENERATED_BODY()
/* The whole clock, not just the date: the schedules every NPC is driven by are a function of the
* minute of the day, so restoring anything less than the running time restores nothing useful. */
UPROPERTY()
FTimeOfDaySaveData TimeOfDaySave;
UPROPERTY()
TArray<FBookProgressionInfo> BookProgression;
UPROPERTY()
TMap<FName, FInventorySaveData> InventoryData;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Quest")
TArray<FQuestItem> QuestList;
/**
* The quest system's own state, one entry per quest the player has touched.
*
* Kept next to the legacy list above rather than replacing it, because the order manager is still
* the only thing writing that one and a save that carried both is a save both can read. An empty
* array is what a fresh quest state is, so a save made before any of this existed loads through
* here without needing a migration.
*/
UPROPERTY()
TArray<FQuestSaveEntry> QuestSaveData;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Seeds")
TMap<int32, FSeedBedSaveData> SeedBedData;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Placed Objects")
TArray<FPlaceableActorInfo> PlacedActors;
UPROPERTY()
TMap<FGuid, FActorSaveData> ActorSaveData;
/* Where every scheduled NPC stood and what it was doing, one entry per NpcTag */
UPROPERTY()
TArray<FNpcScheduleSaveData> NpcScheduleData;
UPROPERTY()
TMap<FSoftObjectPath, FEventData> EventDataMap;
UPROPERTY()
FTransform PlayerTransform;
UPROPERTY()
TArray<FActiveGameplayStatEffect_SerializedData> GameEffects;
UPROPERTY()
TArray<FStatRuntimeDef> StatData;
void Initialize();
void SaveQuests(const TArray<FQuestItem>& Quests);
void SetBookProgressionData(TArray<FBookProgressionInfo> _BookProgression);
void SetInventoryDataForActor(AActor* Actor, UInventoryComponent* Inventory);
void SetPlantedSeedData(int32 Index, const FSeedBedSaveData& SeedSaveData);
/** Refills the soil of every planted seed of the cached seed beds, used by rain */
void WaterAllPlantedSeeds(const FTimeOfDayData& WateredTime);
void SetPlacedObjectsData(TArray<FPlaceableActorInfo> InPlacedActors);
void CollectSaveableActorsData(const UWorld* World);
/** Reads the schedule component of every NPC in the world, so a load can put all of them back */
void CollectNpcScheduleData(const UWorld* World);
void SetGameEventData(const UWorld* World);
void SetPlayerData(const UWorld* World);
void SetAbilitySystemData(const UWorld* World);
};
/**
*
*/
UCLASS()
class PROJECTELERI_API UEleriSaveGame : public USaveGame
{
GENERATED_BODY()
public:
UEleriSaveGame();
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FSaveData SaveData;
/**
* Which layout this file was written with.
*
* Zero, the default, is what a save made before this field existed deserializes to: an absent
* property is left at the value the constructor gave it, which is why the stamp is applied when a
* save is written rather than being set in the constructor. Without that, every old save would read
* as current and there would be no way to tell them apart.
*/
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Version")
int32 SaveVersion = 0;
/** The layout this build writes. Raise it when something is added to FSaveData that an older save
* cannot be read through, and handle the difference where that field is read back. */
static constexpr int32 CurrentSaveVersion = 1;
};