Files
ProjectEleri/Source/ProjectEleri/Public/TimeOfDayManager.h

395 lines
13 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Misc/DateTime.h"
#include "Misc/Timespan.h"
#include "TimerManager.h"
#include "Math/Rotator.h"
#include "Materials/MaterialInstanceDynamic.h"
#include "Materials/MaterialInterface.h"
#include "Components/StaticMeshComponent.h"
#include "Containers/Array.h"
#include "UObject/NameTypes.h"
#include "../Items/ItemDatabase.h"
#include "GameplayTagContainer.h"
#include "Components/VolumetricCloudComponent.h"
#include "Engine/ExponentialHeightFog.h"
#include "ProjectEleri/GameEventSystem/GameEventDataAsset.h"
#include "ProjectEleri/System/TimeOfDayStruct.h"
#include "TimeOfDayManager.generated.h"
class APostProcessVolume;
class UDirectionalLightComponent;
class USkyLightComponent;
class USkyAtmosphereComponent;
class UWeatherPresetDataAsset;
UENUM(BlueprintType)
enum class EWeatherType : uint8
{
None UMETA(Hidden),
Winter,
Spring,
Summer,
Autumn,
MAX UMETA(Hidden)
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMinutesAdded, float, Minutes);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTimePassed, FTimeOfDayData, TimeOfDay);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDayPassed);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnUpdateMajorLightning);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnRainToggle, bool, active, float, fadeTime);
USTRUCT()
struct FTimeOfDaySaveData
{
GENERATED_BODY()
public:
UPROPERTY(SaveGame)
float rotator;
UPROPERTY(SaveGame)
float CurrentWeatherFadeAlpha;
UPROPERTY(SaveGame)
bool ShouldRain;
UPROPERTY(SaveGame)
float FloatMinutes;
UPROPERTY(SaveGame)
float currentMinutes;
UPROPERTY(SaveGame)
int32 currentHours;
UPROPERTY(SaveGame)
int32 daysPassed;
UPROPERTY(SaveGame)
int32 currentWeekday;
UPROPERTY(SaveGame)
int32 currentMonth;
UPROPERTY(SaveGame)
int32 currentYear;
UPROPERTY(SaveGame)
bool Raining;
UPROPERTY(SaveGame)
bool FadingOutWeather;
UPROPERTY(SaveGame)
float FadingWeatherTimer;
UPROPERTY(SaveGame)
float NextWeatherChangeMinutes;
UPROPERTY(SaveGame)
EWeatherType CurrentWeatherType;
UPROPERTY(SaveGame)
FSoftObjectPath CurrentWeatherSoftObjectPath;
UPROPERTY(SaveGame)
FSoftObjectPath QueuedWeatherSoftObjectPath;
};
USTRUCT(BlueprintType)
struct FCalendarDayData
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int32 Day = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<TSoftObjectPtr<UGameEventDataAsset>> Events;
};
UCLASS()
class PROJECTELERI_API ATimeOfDayManager : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATimeOfDayManager();
public:
UPROPERTY(VisibleAnywhere, BlueprintReadwrite)
UItemDatabase *ItemDatabase;
UPROPERTY(BlueprintAssignable)
FOnDayPassed OnDayPassed;
UPROPERTY(BlueprintAssignable)
FOnMinutesAdded OnMinutesAdded;
UPROPERTY(BlueprintAssignable)
FOnTimePassed OnTimePassed;
//Will be used to update sky textures, maybe even swap post processing
//Very expensive per frame or even a couple of times per second but it should be okay
//to run every second or every few seconds
UPROPERTY(BlueprintAssignable)
FOnUpdateMajorLightning OnMajorLightningUpdate;
UPROPERTY(BlueprintAssignable)
FOnRainToggle OnRainToggle;
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void K2_WeatherFadeToggle(float alpha, bool bIsRain);
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void K2_WeatherFadeStart(bool bIsRain);
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void K2_WeatherFadeEnd(bool bIsRain);
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void K2_RainToggle(bool bActive);
UPROPERTY(EditAnywhere)
bool enableTimeOfDay = true;
UPROPERTY(EditAnywhere)
bool WeatherEnabled = true;
UPROPERTY(EditAnywhere)
bool skipNight = true;
UPROPERTY(EditAnywhere)
bool enableDebugLogs;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Time of Day - Lightning Setting",
meta = (AllowedClasses = "/Script/ProjectEleri.GameEventDataAsset"))
TMap<FGameplayTag, FSoftObjectPath> WeatherEventDataAssetMap;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Time of Day - Lightning Setting")
TMap<FSoftObjectPath, float> WeatherPresetDistributionMapPaths;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Time of Day - Lightning Setting")
float DirectionalLightMaxIntensity;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Time of Day - Lightning Setting")
float DirectionalLightMinIntensity;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Time of Day - Lightning Setting")
float SkylightMaxIntensity;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Time of Day - Lightning Setting")
float SkylightMinIntensity;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Time of Day - Lightning Setting")
float SkyLightTimeOffsetNight;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Time of Day - Lightning Setting")
UMaterialInterface* VolumetricCloudMaterial;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
UMaterialParameterCollection *GeneralMaterialParameterCollection;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
UMaterialParameterCollection *WindMaterialParameterCollection;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
AActor *skyDomeActor;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
APostProcessVolume *MainPP;
UPROPERTY(EditAnywhere, Category = "Time of Day - Lightning Setting")
float MiutesToAdd = 1.0f;
UPROPERTY(EditAnywhere, Category = "Time of Day - Lightning Setting")
float daySpeed = 10.0f;
UPROPERTY(EditAnywhere, Category = "Time of Day - Lightning Setting")
FLinearColor SubsurfaceColorDay;
UPROPERTY(VisibleAnywhere, Category = "Time of Day - Info")
float rotator;
UPROPERTY(VisibleAnywhere, Category = "Time of Day - Info")
float CurrentWeaterFadeAlpha;
UPROPERTY(VisibleAnywhere, Category = "Time of Day - Info")
bool ShouldRain;
UPROPERTY(VisibleAnywhere, Category = "Time of Day - Info")
float FloatMinutes;
UPROPERTY(VisibleAnywhere, Category = "Time of Day - Info")
float currentMinutes;
UPROPERTY(VisibleAnywhere, Category = "Time of Day - Info")
int32 currentHours;
UPROPERTY(VisibleAnywhere, Category = "Time of Day - Info")
int32 daysPassed;
UPROPERTY(VisibleAnywhere, Category = "Time of Day - Info")
int32 currentWeekday;
UPROPERTY(VisibleAnywhere, Category = "Time of Day - Info")
int32 currentMonth;
UPROPERTY(VisibleAnywhere, Category = "Time of Day - Info")
int32 currentYear;
UPROPERTY(VisibleAnywhere, Category = "Time of Day - Info")
bool Raining;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Time of Day - Info")
bool FadingOutWeather;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Time of Day - Info")
float FadingWeatherTimer;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Time of Day - Info")
float NextWeatherChangeMinutes;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
EWeatherType CurrentWeatherType;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
float skyIntensityMultiplier = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector2D MorningSkyStartFadeTime;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector2D EveningSkyStartFadeTime;
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
bool GetTimeTicking() const { return TimeTicking; }
// Sums up all years, months, days, hours and minutes
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
float GetMinutesPassedSoFar() const;
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
inline FTimeOfDayData GetTimeOfDay() const { return FTimeOfDayData(currentYear, currentMonth, daysPassed, currentHours, GetCurrentMinutes()); }
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
inline float GetCurrentFloatMinutes() const { return FloatMinutes; }
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
inline int32 GetCurrentMinutes() const { return currentMinutes; }
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
inline int32 GetExactMinutes() const { return currentMinutes; }
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
inline float GetCurrentFloatHours() const { return FloatMinutes / 60.0f; }
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
inline int32 GetCurrentHours() const { return currentHours; }
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
inline int32 GetDaysPassed() const { return daysPassed; }
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
inline int32 GetMonth() const { return currentMonth; }
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
inline int32 GetWeekDay() const { return currentWeekday; }
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
inline int32 GetYear() const { return currentYear; }
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
inline int32 GetAllDaysPassed() const
{
return ((currentYear - 1) * 4 * 28) + ((currentMonth - 1) * 28) + daysPassed;
}
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Time of day")
void GetDateMinusDays(int32 days, int32 &daysOut, int32 &monthsOut, int32 &yearsOut);
UFUNCTION(BlueprintCallable, Category = "Time of day")
void SetTimeline(int32 minute, int32 hour, int32 day, int32 weekday, int32 month, int32 year);
UFUNCTION(BlueprintCallable, Category = "Time of day")
void SetTimeOfDay(float Minutes);
UFUNCTION(BlueprintCallable, Category = "Time of day")
void AddMinutes(float minutes);
UFUNCTION(BlueprintCallable, Category = "Time of day")
void GoToSleep();
UFUNCTION(BlueprintCallable, Category = "Time of day")
bool IsRaining() { return Raining; }
UFUNCTION(BlueprintCallable, Category = "Time of day")
void ToggleTimeActive(bool bNewActive);
UFUNCTION(BlueprintCallable, Category = "Time of day")
TArray<FCalendarDayData> GetCalendarDataForMonth(int32 Month = 1);
UFUNCTION(BlueprintImplementableEvent)
void PassOutSleeping();
FTimeOfDaySaveData GetSaveData() const;
void LoadSaveData(const FTimeOfDaySaveData &saveData);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual void PostLoad() override;
void UpdateMajorLightning();
void RotateSun(const float &_rotator);
void SetDirectionalLightIntensity(const float &_rotator);
void SetSkylightIntensity(const float &_rotator);
void CheckLateHours();
// Called every frame
virtual void Tick(float DeltaTime) override;
//Updates light intensity and directional light rotation
void UpdateLightning();
FTimerHandle timerHandle;
FTimerHandle addTimerHandle;
FTimerHandle majorLightningHandle;
FTimerHandle weatherCheckHandle;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
UDirectionalLightComponent* sunLight;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
UDirectionalLightComponent* moonLight;
UPROPERTY(EditDefaultsOnly)
USkyLightComponent* skyLight;
UPROPERTY(EditDefaultsOnly)
UExponentialHeightFogComponent* exponentialHeightFogComponent;
UPROPERTY(EditDefaultsOnly)
USkyAtmosphereComponent* skyAtmosphereComponent;
UPROPERTY(EditDefaultsOnly)
UVolumetricCloudComponent* VolumetricCloudComponent;
UPROPERTY()
TMap<UWeatherPresetDataAsset *, float> WeatherPresetDistributionMap;
UPROPERTY()
UMaterialInstanceDynamic* VolumetricCloudMaterialInstance;
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UWeatherPresetDataAsset *CurrentWeatherPreset;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UWeatherPresetDataAsset *QueuedWeatherPreset;
protected:
int32 GetWeatherDistributionMaxValue() const;
UWeatherPresetDataAsset *GetWeatherDistributionValue() const;
UPROPERTY()
bool TimeTicking;
//True intensity evaluated from curve
float CurrentSunlightIntensity;
float CurrentMoonlightIntensity;
//True intensity evaluated from curve
float CurrentSkylightIntensity;
#if WITH_EDITORONLY_DATA
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Editor Preview",
meta = (ClampMin = 0.f, ClampMax = 23.f, UIMin = 0.f, UIMax = 23.f))
float PreviewHours = 7.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Editor Preview",
meta = (ClampMin = 0.f, ClampMax = 59.f, UIMin = 0.f, UIMax = 59.f))
float PreviewMinutes = 0.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Editor Preview")
UWeatherPresetDataAsset *PresetOverride;
#endif
#if WITH_EDITOR
UFUNCTION(BlueprintCallable, CallInEditor, Category = "Editor Preview")
void UpdatePreviewTime();
#endif
};