142 lines
4.4 KiB
C++
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;
|
|
};
|