Fixes for seed planting

This commit is contained in:
2026-09-17 20:59:12 +02:00
parent 07568a4193
commit 69372fde46
18 changed files with 215 additions and 38 deletions

View File

@@ -196,6 +196,7 @@ GlobalSettingsDataSheet=/Game/GameData/CSV/GlobalKeyValueSettings.GlobalKeyValue
ItemSeedCarouselClass=None ItemSeedCarouselClass=None
RemovableStaticMeshClass=/Script/Engine.BlueprintGeneratedClass'/Game/Prefabs/BP_RemovableStaticMeshActor.BP_RemovableStaticMeshActor_C' RemovableStaticMeshClass=/Script/Engine.BlueprintGeneratedClass'/Game/Prefabs/BP_RemovableStaticMeshActor.BP_RemovableStaticMeshActor_C'
MovementDisableEffectClass=/Script/Engine.BlueprintGeneratedClass'/Game/Blueprints/GameEffects/GSE_MovementDisabled.GSE_MovementDisabled_C' MovementDisableEffectClass=/Script/Engine.BlueprintGeneratedClass'/Game/Blueprints/GameEffects/GSE_MovementDisabled.GSE_MovementDisabled_C'
SpriteShadowMaterial=/Game/Materials/Sprite/MI_SpriteShadow_Inst.MI_SpriteShadow_Inst
[/Script/InteractionSystem.InteractionSettings] [/Script/InteractionSystem.InteractionSettings]
DefaultInteractionWidgetClass=/Script/UMG.WidgetBlueprintGeneratedClass'/Game/UI/InteractionUI/WBP_Eleri_Interaction.WBP_Eleri_Interaction_C' DefaultInteractionWidgetClass=/Script/UMG.WidgetBlueprintGeneratedClass'/Game/UI/InteractionUI/WBP_Eleri_Interaction.WBP_Eleri_Interaction_C'

Binary file not shown.

View File

@@ -10,14 +10,33 @@ void UEleriFlipbookComponent::BeginPlay()
Super::BeginPlay(); Super::BeginPlay();
DecalComponent = NewObject<UDecalComponent>(GetOwner(), UDecalComponent::StaticClass(), TEXT("Shadow Decal")); DecalComponent = NewObject<UDecalComponent>(GetOwner(), UDecalComponent::StaticClass(), TEXT("Shadow Decal"));
DecalComponent->SetDecalMaterial(DecalMaterial);
DecalComponent->DecalSize = DecalSize; DecalComponent->DecalSize = DecalSize;
DecalComponent->SetFadeScreenSize(0.f); DecalComponent->SetFadeScreenSize(0.f);
DecalComponent->SetupAttachment(GetOwner()->GetRootComponent()); DecalComponent->SetupAttachment(GetOwner()->GetRootComponent());
DecalComponent->RegisterComponent(); DecalComponent->RegisterComponent();
DecalComponent->SetRelativeLocation(DecalOffset - FVector(0.f, 0.f, DecalSize.Z)); UpdateRelativeLocation(FVector::ZeroVector);
DecalComponent->SetUsingAbsoluteRotation(true); DecalComponent->SetUsingAbsoluteRotation(true);
DecalComponent->SetRelativeRotation(FRotator(-90.f, 0.f, 0.f)); DecalComponent->SetRelativeRotation(FRotator(-90.f, 0.f, 0.f));
SetCastShadow(false); SetCastShadow(false);
if (DecalMaterial.IsValid())
{
DecalComponent->SetDecalMaterial(DecalMaterial.Get());
}
else
{
DecalMaterial.LoadAsync(FLoadSoftObjectPathAsyncDelegate::CreateWeakLambda(this, [this](const FSoftObjectPath& Path, UObject* MaterialObj)
{
if (UMaterialInterface* Interface = Cast<UMaterialInterface>(MaterialObj))
{
DecalComponent->SetDecalMaterial(Interface);
}
}));
}
}
void UEleriFlipbookComponent::UpdateRelativeLocation(const FVector& NewLoc) const
{
DecalComponent->SetRelativeLocation(NewLoc + (DecalOffset - FVector(0.f, 0.f, DecalSize.Z)));
} }

View File

@@ -15,8 +15,8 @@ class PROJECTELERI_API UEleriFlipbookComponent : public UPaperFlipbookComponent
public: public:
virtual void BeginPlay() override; virtual void BeginPlay() override;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UMaterialInterface* DecalMaterial = nullptr; TSoftObjectPtr<UMaterialInterface> DecalMaterial = nullptr;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
FVector DecalSize = FVector::OneVector; FVector DecalSize = FVector::OneVector;
@@ -24,9 +24,9 @@ public:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
FVector DecalOffset = FVector::ZeroVector; FVector DecalOffset = FVector::ZeroVector;
protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly) UPROPERTY(EditAnywhere, BlueprintReadOnly)
UDecalComponent* DecalComponent = nullptr; UDecalComponent* DecalComponent = nullptr;
// Will provide a new relative location that we will update with the offset
void UpdateRelativeLocation(const FVector& NewLoc) const;
}; };

View File

@@ -0,0 +1,44 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "EleriPaperSpriteComponent.h"
#include "Components/DecalComponent.h"
void UEleriPaperSpriteComponent::BeginPlay()
{
Super::BeginPlay();
DecalComponent = NewObject<UDecalComponent>(GetOwner(), UDecalComponent::StaticClass(), TEXT("Shadow Decal"));
DecalComponent->DecalSize = DecalSize;
DecalComponent->SetFadeScreenSize(0.f);
DecalComponent->SetupAttachment(GetOwner()->GetRootComponent());
DecalComponent->RegisterComponent();
UpdateRelativeLocation(FVector::ZeroVector);
DecalComponent->SetUsingAbsoluteRotation(true);
DecalComponent->SetRelativeRotation(FRotator(-90.f, 0.f, 0.f));
SetCastShadow(false);
if (DecalMaterial.IsValid())
{
DecalComponent->SetDecalMaterial(DecalMaterial.Get());
}
else
{
DecalMaterial.LoadAsync(FLoadSoftObjectPathAsyncDelegate::CreateWeakLambda(this, [this](const FSoftObjectPath& Path, UObject* MaterialObj)
{
if (UMaterialInterface* Interface = Cast<UMaterialInterface>(MaterialObj))
{
DecalComponent->SetDecalMaterial(Interface);
}
}));
}
}
void UEleriPaperSpriteComponent::UpdateRelativeLocation(const FVector& NewLoc) const
{
DecalComponent->SetRelativeLocation(NewLoc + (DecalOffset - FVector(0.f, 0.f, DecalSize.Z)));
}

View File

@@ -0,0 +1,32 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "PaperSpriteComponent.h"
#include "EleriPaperSpriteComponent.generated.h"
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class PROJECTELERI_API UEleriPaperSpriteComponent : public UPaperSpriteComponent
{
GENERATED_BODY()
public:
virtual void BeginPlay() override;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
TSoftObjectPtr<UMaterialInterface> DecalMaterial = nullptr;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
FVector DecalSize = FVector::OneVector;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
FVector DecalOffset = FVector::ZeroVector;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
UDecalComponent* DecalComponent = nullptr;
// Will provide a new relative location that we will update with the offset
void UpdateRelativeLocation(const FVector& NewLoc) const;
};

View File

@@ -12,11 +12,15 @@
#include "Engine/StaticMesh.h" #include "Engine/StaticMesh.h"
#include "Engine/World.h" #include "Engine/World.h"
#include "ItemContainer.h" #include "ItemContainer.h"
#include "NiagaraComponent.h"
#include "PaperSpriteComponent.h" #include "PaperSpriteComponent.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "Kismet/KismetMaterialLibrary.h" #include "Kismet/KismetMaterialLibrary.h"
#include "Materials/MaterialInstanceDynamic.h" #include "Materials/MaterialInstanceDynamic.h"
#include "Materials/MaterialInterface.h" #include "Materials/MaterialInterface.h"
#include "ProjectEleri/Components/EleriPaperSpriteComponent.h"
#include "ProjectEleri/Settings/EleriGameSettings.h"
#include "NiagaraComponent.h"
namespace namespace
{ {
@@ -31,14 +35,14 @@ namespace
} }
/** Slots are created at runtime as well, so the components are created with stable, deterministic names */ /** Slots are created at runtime as well, so the components are created with stable, deterministic names */
UPaperSpriteComponent* CreatePaperSpriteComponent(AActor* Owner, USceneComponent* AttachParent, FName ComponentName, TSoftObjectPtr<UMaterialInterface> Material) UEleriPaperSpriteComponent* CreatePaperSpriteComponent(AActor* Owner, USceneComponent* AttachParent, FName ComponentName, TSoftObjectPtr<UMaterialInterface> Material)
{ {
if (!IsValid(Owner) || !IsValid(AttachParent)) if (!IsValid(Owner) || !IsValid(AttachParent))
{ {
return nullptr; return nullptr;
} }
UPaperSpriteComponent* SpriteComponent = NewObject<UPaperSpriteComponent>(Owner, ComponentName); UEleriPaperSpriteComponent* SpriteComponent = NewObject<UEleriPaperSpriteComponent>(Owner, ComponentName);
if (!SpriteComponent) if (!SpriteComponent)
{ {
return nullptr; return nullptr;
@@ -46,10 +50,15 @@ namespace
SpriteComponent->SetMobility(EComponentMobility::Movable); SpriteComponent->SetMobility(EComponentMobility::Movable);
SpriteComponent->SetupAttachment(AttachParent); SpriteComponent->SetupAttachment(AttachParent);
SpriteComponent->DecalSize = FVector(150.f);
SpriteComponent->DecalOffset = FVector(0.f, 0.f, 40.f);
SpriteComponent->DecalMaterial = UEleriGameSettings::GetEleriGameSettings()->SpriteShadowMaterial;
SpriteComponent->SetReceivesDecals(false);
SpriteComponent->RegisterComponent(); SpriteComponent->RegisterComponent();
SpriteComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision); SpriteComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
SpriteComponent->SetVisibility(false); SpriteComponent->SetVisibility(false);
TWeakObjectPtr<UPaperSpriteComponent> SpriteComp = SpriteComponent; SpriteComponent->DecalComponent->SetVisibility(false);
TWeakObjectPtr<UEleriPaperSpriteComponent> SpriteComp = SpriteComponent;
if (Material.IsValid()) if (Material.IsValid())
{ {
SpriteComp->SetMaterial(0, Material.Get()); SpriteComp->SetMaterial(0, Material.Get());
@@ -265,7 +274,7 @@ void ASeedBedActor::AdvanceSeedBedByHours(int32 Hours)
// Every hour is applied on its own, a jump over several of them grows, dries and kills hour by hour // Every hour is applied on its own, a jump over several of them grows, dries and kills hour by hour
for (int32 HourIndex = 0; HourIndex < Hours && SlotHasLivingPlant(SlotPair.Value); ++HourIndex) for (int32 HourIndex = 0; HourIndex < Hours && SlotHasLivingPlant(SlotPair.Value); ++HourIndex)
{ {
ApplyHourPassedToSlot(SlotPair.Value, Now); ApplyHourPassedToSlot(SlotPair.Value, Now, SlotPair.Key);
} }
if (bWasAlive && !SlotHasLivingPlant(SlotPair.Value)) if (bWasAlive && !SlotHasLivingPlant(SlotPair.Value))
@@ -283,9 +292,14 @@ void ASeedBedActor::AdvanceSeedBedByHours(int32 Hours)
} }
} }
void ASeedBedActor::ApplyHourPassedToSlot(FSeedBedSeedSlot& Slot, const FTimeOfDayData& Now) void ASeedBedActor::ApplyHourPassedToSlot(FSeedBedSeedSlot& Slot, const FTimeOfDayData& Now, const FIntVector2& SlotCoordinate)
{ {
FSeedBedSeedSlotData& SlotData = Slot.SlotData; FSeedBedSeedSlotData& SlotData = Slot.SlotData;
if (SlotData.bBloomed)
{
return;
}
// The moisture of the soil drains with every in game hour, so the wetness is a clock of its own // The moisture of the soil drains with every in game hour, so the wetness is a clock of its own
const bool bWasMoist = SlotData.MoistureHoursRemaining > 0; const bool bWasMoist = SlotData.MoistureHoursRemaining > 0;
@@ -308,6 +322,11 @@ void ASeedBedActor::ApplyHourPassedToSlot(FSeedBedSeedSlot& Slot, const FTimeOfD
} }
SlotData.SeedAgeHours = FMath::Min(SlotData.SeedAgeHours + 1, FMath::Max(0, SlotData.GrowTime) * SeedBedHoursPerDay); SlotData.SeedAgeHours = FMath::Min(SlotData.SeedAgeHours + 1, FMath::Max(0, SlotData.GrowTime) * SeedBedHoursPerDay);
SlotData.bBloomed = SlotData.SeedAgeHours >= SlotData.GrowTime * SeedBedHoursPerDay;
if (SlotData.bBloomed)
{
RefreshSlotVisual(SlotCoordinate);
}
} }
void ASeedBedActor::ApplyOfflineProgression() void ASeedBedActor::ApplyOfflineProgression()
@@ -604,6 +623,18 @@ FSeedBedSeedSlot& ASeedBedActor::CreateSlot(FIntVector2 SlotCoordinate, bool bRe
{ {
Slot.PlantSprite = CreatePaperSpriteComponent(this, GetRootComponent(), GetSlotComponentName(SlotCoordinate, TEXT("Plant")), DefaultPlantSpriteMaterial); Slot.PlantSprite = CreatePaperSpriteComponent(this, GetRootComponent(), GetSlotComponentName(SlotCoordinate, TEXT("Plant")), DefaultPlantSpriteMaterial);
} }
Slot.NiagaraComponent = NewObject<UNiagaraComponent>(this, GetSlotComponentName(SlotCoordinate, TEXT("Vfx")));
Slot.NiagaraComponent->SetMobility(EComponentMobility::Movable);
Slot.NiagaraComponent->SetupAttachment(GetRootComponent());
Slot.NiagaraComponent->SetAutoActivate(false);
Slot.NiagaraComponent->RegisterComponent();
Slot.NiagaraComponent->SetRelativeLocation(FVector(
Offset.X + X + SeedBedDecalSize.Z,
Offset.Y + Y + SeedBedDecalSize.Y,
50.f));
Slot.NiagaraComponent->SetVisibility(false);
AddInstanceComponent(Slot.NiagaraComponent);
ApplySlotVisuals(SlotCoordinate, Slot); ApplySlotVisuals(SlotCoordinate, Slot);
@@ -638,6 +669,7 @@ void ASeedBedActor::ApplySlotVisuals(FIntVector2 SlotCoordinate, FSeedBedSeedSlo
{ {
// A plant that died or was harvested keeps its mesh, the slot is only emptied when it is cleared for real // A plant that died or was harvested keeps its mesh, the slot is only emptied when it is cleared for real
Slot.PlantSprite->SetVisibility(false); Slot.PlantSprite->SetVisibility(false);
Slot.PlantSprite->DecalComponent->SetVisibility(false);
return; return;
} }
@@ -645,6 +677,13 @@ void ASeedBedActor::ApplySlotVisuals(FIntVector2 SlotCoordinate, FSeedBedSeedSlo
FVector PlantScale = FVector(5.f); FVector PlantScale = FVector(5.f);
const int32 StageIndex = ResolveGrowthStageIndex(Slot); const int32 StageIndex = ResolveGrowthStageIndex(Slot);
if (StageIndex == INDEX_NONE)
{
Slot.PlantSprite->SetVisibility(false);
Slot.PlantSprite->DecalComponent->SetVisibility(false);
return;
}
const UItemDataAsset* SeedData = Slot.SlotData.ItemDataAsset; const UItemDataAsset* SeedData = Slot.SlotData.ItemDataAsset;
if (IsValid(SeedData) && SeedData->SeedStages.IsValidIndex(StageIndex)) if (IsValid(SeedData) && SeedData->SeedStages.IsValidIndex(StageIndex))
{ {
@@ -654,11 +693,13 @@ void ASeedBedActor::ApplySlotVisuals(FIntVector2 SlotCoordinate, FSeedBedSeedSlo
Slot.PlantSprite->SetRelativeScale3D(PlantScale); Slot.PlantSprite->SetRelativeScale3D(PlantScale);
Slot.PlantSprite->SetRelativeLocation(PlantOffset); Slot.PlantSprite->SetRelativeLocation(PlantOffset);
Slot.PlantSprite->UpdateRelativeLocation(FVector(PlantOffset.X, PlantOffset.Y, 0.f));
if (SeedData->SeedStages[StageIndex].Sprite.IsValid()) if (SeedData->SeedStages[StageIndex].Sprite.IsValid())
{ {
Slot.PlantSprite->SetSprite(SeedData->SeedStages[StageIndex].Sprite.Get()); Slot.PlantSprite->SetSprite(SeedData->SeedStages[StageIndex].Sprite.Get());
Slot.PlantSprite->SetVisibility(true); Slot.PlantSprite->SetVisibility(true);
Slot.PlantSprite->DecalComponent->SetVisibility(true);
} }
else else
{ {
@@ -673,8 +714,36 @@ void ASeedBedActor::ApplySlotVisuals(FIntVector2 SlotCoordinate, FSeedBedSeedSlo
Slot->PlantSprite->SetSprite(Sprite); Slot->PlantSprite->SetSprite(Sprite);
})); }));
} }
if (Slot.SlotData.bBloomed && !Slot.NiagaraComponent->IsActive())
{
Slot.NiagaraComponent->SetAsset(nullptr);
Slot.NiagaraComponent->Activate(false);
if (PlantBloomedVfx.IsValid())
{
Slot.NiagaraComponent->SetAsset(PlantBloomedVfx.Get());
Slot.NiagaraComponent->Activate(true);
Slot.NiagaraComponent->SetVisibility(true);
}
else
{
PlantBloomedVfx.LoadAsync(FLoadSoftObjectPathAsyncDelegate::CreateWeakLambda(this, [this, SlotCoordinate](const FSoftObjectPath& Path, UObject* EffectObj)
{
FSeedBedSeedSlot* Slot = SeedBedSeedSlotsMap.Find(SlotCoordinate);
if (!Slot || !IsValid(Slot->NiagaraComponent)) return;
UNiagaraSystem* NiagaraSystem = Cast<UNiagaraSystem>(EffectObj);
if (!IsValid(NiagaraSystem)) return;
Slot->NiagaraComponent->SetAsset(NiagaraSystem);
Slot->NiagaraComponent->ResetSystem();
Slot->NiagaraComponent->SetVisibility(true);
}));
}
}
} }
void ASeedBedActor::RefreshSlotVisual(FIntVector2 SlotCoordinate) void ASeedBedActor::RefreshSlotVisual(const FIntVector2& SlotCoordinate)
{ {
FSeedBedSeedSlot* Slot = SeedBedSeedSlotsMap.Find(SlotCoordinate); FSeedBedSeedSlot* Slot = SeedBedSeedSlotsMap.Find(SlotCoordinate);
if (!Slot) if (!Slot)
@@ -698,7 +767,7 @@ void ASeedBedActor::RefreshAllSlotVisuals()
bool ASeedBedActor::IsPlantableSeedData(const UItemDataAsset* SeedData) bool ASeedBedActor::IsPlantableSeedData(const UItemDataAsset* SeedData)
{ {
// Only seeds of plants make it into a bed, the meshes are optional and fall back to DefaultPlantMesh // Only seeds of plants make it into a bed, the meshes are optional and fall back to DefaultPlantMesh
return IsValid(SeedData) && SeedData->IsSeed; return IsValid(SeedData) && SeedData->ItemCategory == Category::Seed;
} }
void ASeedBedActor::HighlightSlot(FIntVector2 SlotCoordinate) void ASeedBedActor::HighlightSlot(FIntVector2 SlotCoordinate)
@@ -816,7 +885,7 @@ int32 ASeedBedActor::ResolveGrowthStageIndex(const FSeedBedSeedSlot& Slot) const
} }
// Stages are set up per day while the age of a plant counts hours, so the last day that was reached wins // Stages are set up per day while the age of a plant counts hours, so the last day that was reached wins
int32 StageIndex = 0; int32 StageIndex = INDEX_NONE;
for (int32 Index = 0; Index < SeedData->SeedStages.Num(); ++Index) for (int32 Index = 0; Index < SeedData->SeedStages.Num(); ++Index)
{ {

View File

@@ -7,6 +7,9 @@
#include "ProjectEleri/System/TimeOfDayStruct.h" #include "ProjectEleri/System/TimeOfDayStruct.h"
#include "SeedBedActor.generated.h" #include "SeedBedActor.generated.h"
class UNiagaraSystem;
class UNiagaraComponent;
class UEleriPaperSpriteComponent;
class UPaperSpriteComponent; class UPaperSpriteComponent;
class ATimeOfDayManager; class ATimeOfDayManager;
class UDecalComponent; class UDecalComponent;
@@ -81,7 +84,10 @@ struct FSeedBedSeedSlot
UMaterialInstanceDynamic* SeedBedDynamicMat = nullptr; UMaterialInstanceDynamic* SeedBedDynamicMat = nullptr;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly) UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UPaperSpriteComponent* PlantSprite; UEleriPaperSpriteComponent* PlantSprite = nullptr;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UNiagaraComponent* NiagaraComponent = nullptr;
}; };
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
@@ -143,6 +149,9 @@ public:
/** Dimensions of the grid generated by GenerateSeedBedGrid, X = columns, Y = rows */ /** Dimensions of the grid generated by GenerateSeedBedGrid, X = columns, Y = rows */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Seed Bed|Setup") UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Seed Bed|Setup")
FIntVector2 GridSize = FIntVector2(3, 3); FIntVector2 GridSize = FIntVector2(3, 3);
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Seed Bed|Setup")
TSoftObjectPtr<UNiagaraSystem> PlantBloomedVfx;
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
// HIGHLIGHT DECAL // HIGHLIGHT DECAL
@@ -249,7 +258,7 @@ public:
/** Re-applies mesh, material and decal of a single slot */ /** Re-applies mesh, material and decal of a single slot */
UFUNCTION(BlueprintCallable, Category = "Seed Bed|Visuals") UFUNCTION(BlueprintCallable, Category = "Seed Bed|Visuals")
void RefreshSlotVisual(FIntVector2 SlotCoordinate); void RefreshSlotVisual(const FIntVector2& SlotCoordinate);
/** Re-applies mesh, material and decal of every slot of the bed */ /** Re-applies mesh, material and decal of every slot of the bed */
UFUNCTION(BlueprintCallable, Category = "Seed Bed|Visuals") UFUNCTION(BlueprintCallable, Category = "Seed Bed|Visuals")
@@ -287,7 +296,7 @@ protected:
void BindToTimeOfDay(); void BindToTimeOfDay();
/** Applies one in game hour of growth, moisture handling and death checks to a single slot */ /** Applies one in game hour of growth, moisture handling and death checks to a single slot */
void ApplyHourPassedToSlot(FSeedBedSeedSlot& Slot, const FTimeOfDayData& Now); void ApplyHourPassedToSlot(FSeedBedSeedSlot& Slot, const FTimeOfDayData& Now, const FIntVector2& SlotCoordinate);
/** Catches the plants up on the in game time that passed while the bed was not in the world */ /** Catches the plants up on the in game time that passed while the bed was not in the world */
void ApplyOfflineProgression(); void ApplyOfflineProgression();

View File

@@ -50,6 +50,9 @@ public:
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "Ability System|Settings") UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "Ability System|Settings")
TSoftObjectPtr<UDataTable> GlobalSettingsDataSheet; TSoftObjectPtr<UDataTable> GlobalSettingsDataSheet;
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "Materials")
TSoftObjectPtr<UMaterialInterface> SpriteShadowMaterial;
public: public: