From 69372fde4637338aa7e3b3051b5895ade29c5cee Mon Sep 17 00:00:00 2001 From: "adnan.mujkic" Date: Thu, 17 Sep 2026 20:59:12 +0200 Subject: [PATCH] Fixes for seed planting --- Config/DefaultGame.ini | 1 + .../Sprite/MI_MaskedLitSpriteMaterial.uasset | 4 +- .../Sprite/MI_SpriteShadow_Inst.uasset | 4 +- .../Sprite/M_DefaultLitSpriteMaterial.uasset | 4 +- .../Materials/Sprite/M_SpriteShadow.uasset | 4 +- .../Seed/BP_SeedBedActor.uasset | 4 +- .../UI/InventoryScreenWrapper.uasset | 4 +- .../UI/ItemWindowWidgetBP.uasset | 4 +- .../Blueprints/BP_ThirdPersonCharacter.uasset | 4 +- Content/VFX/NI_CropReady.uasset | 4 +- .../0/61/A6L7ILYYQ9VI7SFIYFHFI5.uasset | 4 +- .../Components/EleriFlipbookComponent.cpp | 23 ++++- .../Components/EleriFlipbookComponent.h | 10 +-- .../Components/EleriPaperSpriteComponent.cpp | 44 ++++++++++ .../Components/EleriPaperSpriteComponent.h | 32 +++++++ Source/ProjectEleri/Items/SeedBedActor.cpp | 85 +++++++++++++++++-- Source/ProjectEleri/Items/SeedBedActor.h | 15 +++- .../ProjectEleri/Settings/EleriGameSettings.h | 3 + 18 files changed, 215 insertions(+), 38 deletions(-) create mode 100644 Source/ProjectEleri/Components/EleriPaperSpriteComponent.cpp create mode 100644 Source/ProjectEleri/Components/EleriPaperSpriteComponent.h diff --git a/Config/DefaultGame.ini b/Config/DefaultGame.ini index 47251d16..2e02a27b 100644 --- a/Config/DefaultGame.ini +++ b/Config/DefaultGame.ini @@ -196,6 +196,7 @@ GlobalSettingsDataSheet=/Game/GameData/CSV/GlobalKeyValueSettings.GlobalKeyValue ItemSeedCarouselClass=None RemovableStaticMeshClass=/Script/Engine.BlueprintGeneratedClass'/Game/Prefabs/BP_RemovableStaticMeshActor.BP_RemovableStaticMeshActor_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] DefaultInteractionWidgetClass=/Script/UMG.WidgetBlueprintGeneratedClass'/Game/UI/InteractionUI/WBP_Eleri_Interaction.WBP_Eleri_Interaction_C' diff --git a/Content/Materials/Sprite/MI_MaskedLitSpriteMaterial.uasset b/Content/Materials/Sprite/MI_MaskedLitSpriteMaterial.uasset index 4b87260f..e901a06a 100644 --- a/Content/Materials/Sprite/MI_MaskedLitSpriteMaterial.uasset +++ b/Content/Materials/Sprite/MI_MaskedLitSpriteMaterial.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0cea89cdef0340fc1b020d9303f502d6f028f724f2abf2eeecf951e6b3216615 -size 11753 +oid sha256:9147dd3514b52bfcaf882f06c0bb30c2dddedbb1b36f9606a3a3348b9b6a60c2 +size 12666 diff --git a/Content/Materials/Sprite/MI_SpriteShadow_Inst.uasset b/Content/Materials/Sprite/MI_SpriteShadow_Inst.uasset index f491b242..dc1b6eaa 100644 --- a/Content/Materials/Sprite/MI_SpriteShadow_Inst.uasset +++ b/Content/Materials/Sprite/MI_SpriteShadow_Inst.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf9d1f773d7ef20ed61e043118e49ccd4393280abe6811e8cd462505dd334f4f -size 6776 +oid sha256:f70ae3619afafe354d24a6ca24e04c2d9bab57c889b33cb9ea88bf126c9714ca +size 7597 diff --git a/Content/Materials/Sprite/M_DefaultLitSpriteMaterial.uasset b/Content/Materials/Sprite/M_DefaultLitSpriteMaterial.uasset index d5390e19..189a4d69 100644 --- a/Content/Materials/Sprite/M_DefaultLitSpriteMaterial.uasset +++ b/Content/Materials/Sprite/M_DefaultLitSpriteMaterial.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da4926ef7f5c8e6720944db9ebe9efd6455bb3de6824555b6b456c5f146c6cd0 -size 15776 +oid sha256:b82385160d249ff9d3079aa42d0abe959a411a583da2fd2166b28e87a00c61fc +size 26257 diff --git a/Content/Materials/Sprite/M_SpriteShadow.uasset b/Content/Materials/Sprite/M_SpriteShadow.uasset index 0968d931..9cee41c0 100644 --- a/Content/Materials/Sprite/M_SpriteShadow.uasset +++ b/Content/Materials/Sprite/M_SpriteShadow.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d94c784c56a445b1f5f37f511c72956b137ce3aa26eac0d9252308ca96fbccc2 -size 13884 +oid sha256:94e1cfa386db2941d69661bfeac262988d77d73d3ded9ada919f5732f2928bb8 +size 15179 diff --git a/Content/Scripts/InventorySystem/Seed/BP_SeedBedActor.uasset b/Content/Scripts/InventorySystem/Seed/BP_SeedBedActor.uasset index 2043b993..2bf9c67a 100644 --- a/Content/Scripts/InventorySystem/Seed/BP_SeedBedActor.uasset +++ b/Content/Scripts/InventorySystem/Seed/BP_SeedBedActor.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce7fca25d7c925555ef0aade19a11fb6a42df955f9b6936eaf743083438e3226 -size 98217 +oid sha256:46748c4870cc3e00b1c88adaf4ecf962ad8143e076e3c3feea861bd35ce807f1 +size 98347 diff --git a/Content/Scripts/InventorySystem/UI/InventoryScreenWrapper.uasset b/Content/Scripts/InventorySystem/UI/InventoryScreenWrapper.uasset index 986483e3..7fdbcf32 100644 --- a/Content/Scripts/InventorySystem/UI/InventoryScreenWrapper.uasset +++ b/Content/Scripts/InventorySystem/UI/InventoryScreenWrapper.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:648a4a85b97b6c36b9769af3510da534faea40f9bc733522bcd2ab18ea37b750 -size 1336716 +oid sha256:2f49a68e33bd205e97946a9c4732053cdec1014d72099ef40341a96f1a37f443 +size 1325254 diff --git a/Content/Scripts/InventorySystem/UI/ItemWindowWidgetBP.uasset b/Content/Scripts/InventorySystem/UI/ItemWindowWidgetBP.uasset index e2ec58aa..6b7c885c 100644 --- a/Content/Scripts/InventorySystem/UI/ItemWindowWidgetBP.uasset +++ b/Content/Scripts/InventorySystem/UI/ItemWindowWidgetBP.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b97825e9b83a1ff25335582d74354820dba50bd1a256f28f5e1df8a288e4cce9 -size 314277 +oid sha256:55ae3b70de05084e3d8d8b3b47286f31eb0279f1b8ae805cb2e97140dd270848 +size 322787 diff --git a/Content/ThirdPersonBP/Blueprints/BP_ThirdPersonCharacter.uasset b/Content/ThirdPersonBP/Blueprints/BP_ThirdPersonCharacter.uasset index b046978b..a1ff3d64 100644 --- a/Content/ThirdPersonBP/Blueprints/BP_ThirdPersonCharacter.uasset +++ b/Content/ThirdPersonBP/Blueprints/BP_ThirdPersonCharacter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1c215c05ed6c5d5a58bf641478876da7284de27ca3b32bf99a821896663eb5aa -size 1286130 +oid sha256:fa78e2fc440f78aec3afa45d10b6c234439582241de7b4a3e993c4041cdb2e26 +size 1266578 diff --git a/Content/VFX/NI_CropReady.uasset b/Content/VFX/NI_CropReady.uasset index 087df01f..a180b3ba 100644 --- a/Content/VFX/NI_CropReady.uasset +++ b/Content/VFX/NI_CropReady.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9485fd9769796ebb49ed61f97ec942ef451b9419db90d5d6ae1becaddc3541f2 -size 496155 +oid sha256:e13c6ecc22be5eaf271784ebb41b38cb2eb69ab3d683be1be8dedc554dcaff74 +size 361282 diff --git a/Content/__ExternalActors__/Maps/Persistent_GameWorld/0/61/A6L7ILYYQ9VI7SFIYFHFI5.uasset b/Content/__ExternalActors__/Maps/Persistent_GameWorld/0/61/A6L7ILYYQ9VI7SFIYFHFI5.uasset index cb55b096..7ad8f7b4 100644 --- a/Content/__ExternalActors__/Maps/Persistent_GameWorld/0/61/A6L7ILYYQ9VI7SFIYFHFI5.uasset +++ b/Content/__ExternalActors__/Maps/Persistent_GameWorld/0/61/A6L7ILYYQ9VI7SFIYFHFI5.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2daf35d5acaf7f7d5613eed9d3e80e38a36b405c9c63a01764d5b4ed3bbdd818 -size 87993 +oid sha256:1a9da534e302f03004812cf727c01e84972f28ea1684808a73bcc948f21d1d6e +size 107177 diff --git a/Source/ProjectEleri/Components/EleriFlipbookComponent.cpp b/Source/ProjectEleri/Components/EleriFlipbookComponent.cpp index 519ddee6..8d81c18b 100644 --- a/Source/ProjectEleri/Components/EleriFlipbookComponent.cpp +++ b/Source/ProjectEleri/Components/EleriFlipbookComponent.cpp @@ -10,14 +10,33 @@ void UEleriFlipbookComponent::BeginPlay() Super::BeginPlay(); DecalComponent = NewObject(GetOwner(), UDecalComponent::StaticClass(), TEXT("Shadow Decal")); - DecalComponent->SetDecalMaterial(DecalMaterial); DecalComponent->DecalSize = DecalSize; DecalComponent->SetFadeScreenSize(0.f); DecalComponent->SetupAttachment(GetOwner()->GetRootComponent()); DecalComponent->RegisterComponent(); - DecalComponent->SetRelativeLocation(DecalOffset - FVector(0.f, 0.f, DecalSize.Z)); + 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(MaterialObj)) + { + DecalComponent->SetDecalMaterial(Interface); + } + })); + } +} + +void UEleriFlipbookComponent::UpdateRelativeLocation(const FVector& NewLoc) const +{ + DecalComponent->SetRelativeLocation(NewLoc + (DecalOffset - FVector(0.f, 0.f, DecalSize.Z))); } diff --git a/Source/ProjectEleri/Components/EleriFlipbookComponent.h b/Source/ProjectEleri/Components/EleriFlipbookComponent.h index 07fa4e50..badc9f64 100644 --- a/Source/ProjectEleri/Components/EleriFlipbookComponent.h +++ b/Source/ProjectEleri/Components/EleriFlipbookComponent.h @@ -15,8 +15,8 @@ class PROJECTELERI_API UEleriFlipbookComponent : public UPaperFlipbookComponent public: virtual void BeginPlay() override; - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) - UMaterialInterface* DecalMaterial = nullptr; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly) + TSoftObjectPtr DecalMaterial = nullptr; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) FVector DecalSize = FVector::OneVector; @@ -24,9 +24,9 @@ public: UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) FVector DecalOffset = FVector::ZeroVector; -protected: - 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; }; diff --git a/Source/ProjectEleri/Components/EleriPaperSpriteComponent.cpp b/Source/ProjectEleri/Components/EleriPaperSpriteComponent.cpp new file mode 100644 index 00000000..a954e274 --- /dev/null +++ b/Source/ProjectEleri/Components/EleriPaperSpriteComponent.cpp @@ -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(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(MaterialObj)) + { + DecalComponent->SetDecalMaterial(Interface); + } + })); + } +} + +void UEleriPaperSpriteComponent::UpdateRelativeLocation(const FVector& NewLoc) const +{ + DecalComponent->SetRelativeLocation(NewLoc + (DecalOffset - FVector(0.f, 0.f, DecalSize.Z))); +} + diff --git a/Source/ProjectEleri/Components/EleriPaperSpriteComponent.h b/Source/ProjectEleri/Components/EleriPaperSpriteComponent.h new file mode 100644 index 00000000..26def6cb --- /dev/null +++ b/Source/ProjectEleri/Components/EleriPaperSpriteComponent.h @@ -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 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; +}; diff --git a/Source/ProjectEleri/Items/SeedBedActor.cpp b/Source/ProjectEleri/Items/SeedBedActor.cpp index 726e90fe..69fbbd2f 100644 --- a/Source/ProjectEleri/Items/SeedBedActor.cpp +++ b/Source/ProjectEleri/Items/SeedBedActor.cpp @@ -12,11 +12,15 @@ #include "Engine/StaticMesh.h" #include "Engine/World.h" #include "ItemContainer.h" +#include "NiagaraComponent.h" #include "PaperSpriteComponent.h" #include "Kismet/GameplayStatics.h" #include "Kismet/KismetMaterialLibrary.h" #include "Materials/MaterialInstanceDynamic.h" #include "Materials/MaterialInterface.h" +#include "ProjectEleri/Components/EleriPaperSpriteComponent.h" +#include "ProjectEleri/Settings/EleriGameSettings.h" +#include "NiagaraComponent.h" namespace { @@ -31,14 +35,14 @@ namespace } /** 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 Material) + UEleriPaperSpriteComponent* CreatePaperSpriteComponent(AActor* Owner, USceneComponent* AttachParent, FName ComponentName, TSoftObjectPtr Material) { if (!IsValid(Owner) || !IsValid(AttachParent)) { return nullptr; } - UPaperSpriteComponent* SpriteComponent = NewObject(Owner, ComponentName); + UEleriPaperSpriteComponent* SpriteComponent = NewObject(Owner, ComponentName); if (!SpriteComponent) { return nullptr; @@ -46,10 +50,15 @@ namespace SpriteComponent->SetMobility(EComponentMobility::Movable); 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->SetCollisionEnabled(ECollisionEnabled::NoCollision); SpriteComponent->SetVisibility(false); - TWeakObjectPtr SpriteComp = SpriteComponent; + SpriteComponent->DecalComponent->SetVisibility(false); + TWeakObjectPtr SpriteComp = SpriteComponent; if (Material.IsValid()) { 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 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)) @@ -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; + + if (SlotData.bBloomed) + { + return; + } // 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; @@ -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.bBloomed = SlotData.SeedAgeHours >= SlotData.GrowTime * SeedBedHoursPerDay; + if (SlotData.bBloomed) + { + RefreshSlotVisual(SlotCoordinate); + } } 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.NiagaraComponent = NewObject(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); @@ -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 Slot.PlantSprite->SetVisibility(false); + Slot.PlantSprite->DecalComponent->SetVisibility(false); return; } @@ -645,6 +677,13 @@ void ASeedBedActor::ApplySlotVisuals(FIntVector2 SlotCoordinate, FSeedBedSeedSlo FVector PlantScale = FVector(5.f); 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; if (IsValid(SeedData) && SeedData->SeedStages.IsValidIndex(StageIndex)) { @@ -654,11 +693,13 @@ void ASeedBedActor::ApplySlotVisuals(FIntVector2 SlotCoordinate, FSeedBedSeedSlo Slot.PlantSprite->SetRelativeScale3D(PlantScale); Slot.PlantSprite->SetRelativeLocation(PlantOffset); + Slot.PlantSprite->UpdateRelativeLocation(FVector(PlantOffset.X, PlantOffset.Y, 0.f)); if (SeedData->SeedStages[StageIndex].Sprite.IsValid()) { Slot.PlantSprite->SetSprite(SeedData->SeedStages[StageIndex].Sprite.Get()); Slot.PlantSprite->SetVisibility(true); + Slot.PlantSprite->DecalComponent->SetVisibility(true); } else { @@ -673,8 +714,36 @@ void ASeedBedActor::ApplySlotVisuals(FIntVector2 SlotCoordinate, FSeedBedSeedSlo 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(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); if (!Slot) @@ -698,7 +767,7 @@ void ASeedBedActor::RefreshAllSlotVisuals() bool ASeedBedActor::IsPlantableSeedData(const UItemDataAsset* SeedData) { // 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) @@ -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 - int32 StageIndex = 0; + int32 StageIndex = INDEX_NONE; for (int32 Index = 0; Index < SeedData->SeedStages.Num(); ++Index) { diff --git a/Source/ProjectEleri/Items/SeedBedActor.h b/Source/ProjectEleri/Items/SeedBedActor.h index 07d41c26..afed8830 100644 --- a/Source/ProjectEleri/Items/SeedBedActor.h +++ b/Source/ProjectEleri/Items/SeedBedActor.h @@ -7,6 +7,9 @@ #include "ProjectEleri/System/TimeOfDayStruct.h" #include "SeedBedActor.generated.h" +class UNiagaraSystem; +class UNiagaraComponent; +class UEleriPaperSpriteComponent; class UPaperSpriteComponent; class ATimeOfDayManager; class UDecalComponent; @@ -81,7 +84,10 @@ struct FSeedBedSeedSlot UMaterialInstanceDynamic* SeedBedDynamicMat = nullptr; UPROPERTY(VisibleAnywhere, BlueprintReadOnly) - UPaperSpriteComponent* PlantSprite; + UEleriPaperSpriteComponent* PlantSprite = nullptr; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly) + UNiagaraComponent* NiagaraComponent = nullptr; }; USTRUCT(BlueprintType) @@ -143,6 +149,9 @@ public: /** Dimensions of the grid generated by GenerateSeedBedGrid, X = columns, Y = rows */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Seed Bed|Setup") FIntVector2 GridSize = FIntVector2(3, 3); + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Seed Bed|Setup") + TSoftObjectPtr PlantBloomedVfx; //------------------------------------------------------------------------------------------------ // HIGHLIGHT DECAL @@ -249,7 +258,7 @@ public: /** Re-applies mesh, material and decal of a single slot */ 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 */ UFUNCTION(BlueprintCallable, Category = "Seed Bed|Visuals") @@ -287,7 +296,7 @@ protected: void BindToTimeOfDay(); /** 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 */ void ApplyOfflineProgression(); diff --git a/Source/ProjectEleri/Settings/EleriGameSettings.h b/Source/ProjectEleri/Settings/EleriGameSettings.h index ff4b5087..41da2cea 100644 --- a/Source/ProjectEleri/Settings/EleriGameSettings.h +++ b/Source/ProjectEleri/Settings/EleriGameSettings.h @@ -50,6 +50,9 @@ public: UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "Ability System|Settings") TSoftObjectPtr GlobalSettingsDataSheet; + + UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "Materials") + TSoftObjectPtr SpriteShadowMaterial; public: