Improvements to watering and some stat forge fixes
This commit is contained in:
@@ -195,6 +195,7 @@ ExpIncreaseEffectClass=/Script/Engine.BlueprintGeneratedClass'/Game/Blueprints/G
|
|||||||
GlobalSettingsDataSheet=/Game/GameData/CSV/GlobalKeyValueSettings.GlobalKeyValueSettings
|
GlobalSettingsDataSheet=/Game/GameData/CSV/GlobalKeyValueSettings.GlobalKeyValueSettings
|
||||||
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'
|
||||||
|
|
||||||
[/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'
|
||||||
|
|||||||
BIN
Content/Blueprints/GameEffects/GSE_MovementDisabled.uasset
LFS
Normal file
BIN
Content/Blueprints/GameEffects/GSE_MovementDisabled.uasset
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -15,7 +15,7 @@ FActiveGameplayStatEffect FActiveGameplayStatEffect::CreateNew(UObject* SourceOb
|
|||||||
ActiveEffect.GameplayEffectClass = Effect->GetClass();
|
ActiveEffect.GameplayEffectClass = Effect->GetClass();
|
||||||
ActiveEffect.StackCount = Stacks;
|
ActiveEffect.StackCount = Stacks;
|
||||||
ActiveEffect.GameplayEffectInstance = Effect;
|
ActiveEffect.GameplayEffectInstance = Effect;
|
||||||
ActiveEffect.RemainingDuration = Effect->Duration;
|
ActiveEffect.RemainingDuration = Effect->GetDuration();
|
||||||
ActiveEffect.NextTickDuration = Effect->TickPeriod;
|
ActiveEffect.NextTickDuration = Effect->TickPeriod;
|
||||||
ActiveEffect.bIsTicking = ActiveEffect.NextTickDuration > 0.f;
|
ActiveEffect.bIsTicking = ActiveEffect.NextTickDuration > 0.f;
|
||||||
ActiveEffect.Handle = FGuid::NewGuid();
|
ActiveEffect.Handle = FGuid::NewGuid();
|
||||||
@@ -192,7 +192,7 @@ FGuid UStatForgeComponent::ApplyGameplayStatEffect(const TSubclassOf<UGameplaySt
|
|||||||
Effect->AppendDataValueMap(DataValueMap);
|
Effect->AppendDataValueMap(DataValueMap);
|
||||||
FGuid GuidToReturn;
|
FGuid GuidToReturn;
|
||||||
|
|
||||||
if (Effect->Duration == GameplayStatEffectDuration_Instant)
|
if (Effect->DurationType == EDurationType::Instant)
|
||||||
{
|
{
|
||||||
Internal_ApplyGameplayStatEffect(Effect);
|
Internal_ApplyGameplayStatEffect(Effect);
|
||||||
}
|
}
|
||||||
@@ -340,21 +340,24 @@ void UStatForgeComponent::TickEffects(float DeltaTime)
|
|||||||
for (int32 i = ActiveEffectsArray.Num() - 1; i >= 0; --i)
|
for (int32 i = ActiveEffectsArray.Num() - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
StatNames.Append(GetAffectedStatsFromEffect(ActiveEffectsArray[i].GameplayEffectInstance));
|
StatNames.Append(GetAffectedStatsFromEffect(ActiveEffectsArray[i].GameplayEffectInstance));
|
||||||
|
|
||||||
if (!CanTickEffect(ActiveEffectsArray[i].GameplayEffectInstance.Get()))
|
|
||||||
{
|
|
||||||
ActiveEffectsArray[i].RemainingDuration = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ActiveEffectsArray[i].RemainingDuration -= DeltaTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ActiveEffectsArray[i].RemainingDuration <= 0.f)
|
if (ActiveEffectsArray[i].GameplayEffectInstance->DurationType == EDurationType::Duration)
|
||||||
{
|
{
|
||||||
RemoveGameplayStatEffect(ActiveEffectsArray[i].Handle);
|
if (!CanTickEffect(ActiveEffectsArray[i].GameplayEffectInstance.Get()))
|
||||||
|
{
|
||||||
|
ActiveEffectsArray[i].RemainingDuration = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ActiveEffectsArray[i].RemainingDuration -= DeltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ActiveEffectsArray[i].RemainingDuration <= 0.f)
|
||||||
|
{
|
||||||
|
RemoveGameplayStatEffect(ActiveEffectsArray[i].Handle);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ActiveEffectsArray[i].GameplayEffectInstance->TickPeriod > 0.f)
|
if (ActiveEffectsArray[i].GameplayEffectInstance->TickPeriod > 0.f)
|
||||||
|
|||||||
@@ -15,8 +15,18 @@ float UStatForgeFunctionLibrary::GetStatValue(const FName StatName, AActor* Acto
|
|||||||
return StatForgeComponent->GetStatValue(StatName);
|
return StatForgeComponent->GetStatValue(StatName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UStatForgeFunctionLibrary::HasTag(const FGameplayTag& Tag, AActor* Actor)
|
||||||
|
{
|
||||||
|
if (!Actor) return false;
|
||||||
|
|
||||||
|
const UStatForgeComponent* StatForgeComponent = Actor->GetComponentByClass<UStatForgeComponent>();
|
||||||
|
if(!StatForgeComponent) return false;
|
||||||
|
|
||||||
|
return StatForgeComponent->GetGameplayTags().HasTagExact(Tag);
|
||||||
|
}
|
||||||
|
|
||||||
FGuid UStatForgeFunctionLibrary::ApplyGameplayStatEffect(const TSubclassOf<UGameplayStatEffect> EffectClass,
|
FGuid UStatForgeFunctionLibrary::ApplyGameplayStatEffect(const TSubclassOf<UGameplayStatEffect> EffectClass,
|
||||||
TMap<FName, float> DataValueMap, AActor* Actor, int32 Stacks)
|
TMap<FName, float> DataValueMap, AActor* Actor, int32 Stacks)
|
||||||
{
|
{
|
||||||
if (!EffectClass || !Actor) return FGuid();
|
if (!EffectClass || !Actor) return FGuid();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,14 @@
|
|||||||
|
|
||||||
class UGameplayStatEffect;
|
class UGameplayStatEffect;
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EDurationType : uint8
|
||||||
|
{
|
||||||
|
Instant,
|
||||||
|
Duration,
|
||||||
|
Infinite
|
||||||
|
};
|
||||||
|
|
||||||
UENUM(BlueprintType)
|
UENUM(BlueprintType)
|
||||||
enum class EModOperation : uint8
|
enum class EModOperation : uint8
|
||||||
{
|
{
|
||||||
@@ -64,9 +72,12 @@ class STATFORGE_API UGameplayStatEffect : public UObject
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Duration")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Duration")
|
||||||
|
EDurationType DurationType;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Duration", meta=(EditCondition = "DurationType==EDurationType::Duration", EditConditionHides))
|
||||||
float Duration = 0.f;
|
float Duration = 0.f;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Duration")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Duration", meta=(EditCondition = "DurationType==EDurationType::Duration", EditConditionHides))
|
||||||
float TickPeriod = 0.f;
|
float TickPeriod = 0.f;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Modifiers")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Modifiers")
|
||||||
@@ -78,17 +89,30 @@ public:
|
|||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tags")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tags")
|
||||||
FGameplayTagContainer CharacterTags;
|
FGameplayTagContainer CharacterTags;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tags|Requirements", meta = (EditCondition = "Duration==0"))
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tags|Requirements", meta = (EditCondition = "DurationType!=EDurationType::Duration"))
|
||||||
FGameplayTagContainer TagsRequiredToApply;
|
FGameplayTagContainer TagsRequiredToApply;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tags|Requirements", meta = (EditCondition = "Duration!=0"))
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tags|Requirements", meta = (EditCondition = "DurationType==EDurationType::Duration"))
|
||||||
FGameplayTagContainer TagsRequiredToTick;
|
FGameplayTagContainer TagsRequiredToTick;
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Stat Forge|Effect")
|
UFUNCTION(BlueprintCallable, Category = "Stat Forge|Effect")
|
||||||
void AppendDataValueMap(TMap<FName, float> InDataValueMap) { DataValueMap.Append(InDataValueMap); }
|
void AppendDataValueMap(TMap<FName, float> InDataValueMap) { DataValueMap.Append(InDataValueMap); }
|
||||||
|
|
||||||
const TMap<FName, float>& GetDataValueMap() { return DataValueMap; }
|
const TMap<FName, float>& GetDataValueMap() { return DataValueMap; }
|
||||||
|
float GetDuration() const
|
||||||
|
{
|
||||||
|
switch (DurationType)
|
||||||
|
{
|
||||||
|
case EDurationType::Instant:
|
||||||
|
return 0.f;
|
||||||
|
case EDurationType::Duration:
|
||||||
|
return Duration;
|
||||||
|
case EDurationType::Infinite:
|
||||||
|
return -1.f;
|
||||||
|
}
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
#include "GameplayTagContainer.h"
|
||||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
#include "StatForgeFunctionLibrary.generated.h"
|
#include "StatForgeFunctionLibrary.generated.h"
|
||||||
|
|
||||||
@@ -14,10 +15,13 @@ UCLASS()
|
|||||||
class STATFORGE_API UStatForgeFunctionLibrary : public UBlueprintFunctionLibrary
|
class STATFORGE_API UStatForgeFunctionLibrary : public UBlueprintFunctionLibrary
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
UFUNCTION(BlueprintPure, Category = "Stat Forge")
|
UFUNCTION(BlueprintPure, Category = "Stat Forge")
|
||||||
static float GetStatValue(UPARAM(meta = (GetOptions = "StatForgeDeveloperSettings.GetStatNames")) const FName StatName, AActor* Actor);
|
static float GetStatValue(UPARAM(meta = (GetOptions = "StatForgeDeveloperSettings.GetStatNames")) const FName StatName, AActor* Actor);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Stat Forge")
|
||||||
|
static bool HasTag(UPARAM(ref) const FGameplayTag& Tag, AActor* Actor);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Stat Forge", meta = (AutoCreateRefTerm = "DataValueMap"))
|
UFUNCTION(BlueprintCallable, Category = "Stat Forge", meta = (AutoCreateRefTerm = "DataValueMap"))
|
||||||
static FGuid ApplyGameplayStatEffect(const TSubclassOf<UGameplayStatEffect> EffectClass, TMap<FName, float> DataValueMap, AActor* Actor, int32 Stacks = 1);
|
static FGuid ApplyGameplayStatEffect(const TSubclassOf<UGameplayStatEffect> EffectClass, TMap<FName, float> DataValueMap, AActor* Actor, int32 Stacks = 1);
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ STATFORGE_MAKE_STAT(FriendPointsMultiplier)
|
|||||||
STATFORGE_MAKE_STAT(AlchemyMultiplier)
|
STATFORGE_MAKE_STAT(AlchemyMultiplier)
|
||||||
STATFORGE_MAKE_STAT(BazarCustomerSpawnRate)
|
STATFORGE_MAKE_STAT(BazarCustomerSpawnRate)
|
||||||
STATFORGE_MAKE_STAT(BazarCustomerWill)
|
STATFORGE_MAKE_STAT(BazarCustomerWill)
|
||||||
|
STATFORGE_MAKE_STAT(WateringAreaScaleMultiplier)
|
||||||
|
|
||||||
STATFORGE_MAKE_STAT(AlchemyXp)
|
STATFORGE_MAKE_STAT(AlchemyXp)
|
||||||
STATFORGE_MAKE_STAT(BotanyXp)
|
STATFORGE_MAKE_STAT(BotanyXp)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ STATFORGE_DECLARE_STAT(FriendPointsMultiplier)
|
|||||||
STATFORGE_DECLARE_STAT(AlchemyMultiplier)
|
STATFORGE_DECLARE_STAT(AlchemyMultiplier)
|
||||||
STATFORGE_DECLARE_STAT(BazarCustomerSpawnRate)
|
STATFORGE_DECLARE_STAT(BazarCustomerSpawnRate)
|
||||||
STATFORGE_DECLARE_STAT(BazarCustomerWill)
|
STATFORGE_DECLARE_STAT(BazarCustomerWill)
|
||||||
|
STATFORGE_DECLARE_STAT(WateringAreaScaleMultiplier)
|
||||||
|
|
||||||
STATFORGE_DECLARE_STAT(AlchemyXp)
|
STATFORGE_DECLARE_STAT(AlchemyXp)
|
||||||
STATFORGE_DECLARE_STAT(BotanyXp)
|
STATFORGE_DECLARE_STAT(BotanyXp)
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
#include "WaterBall.h"
|
#include "WaterBall.h"
|
||||||
#include "Kismet/GameplayStatics.h"
|
#include "Kismet/GameplayStatics.h"
|
||||||
#include "Kismet/KismetMathLibrary.h"
|
#include "Kismet/KismetMathLibrary.h"
|
||||||
#include "DrawDebugHelpers.h"
|
#include "DrawDebugHelpers.h"
|
||||||
#include "Engine/OverlapResult.h"
|
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
#include "ProjectEleri/Items/SeedCarousel.h"
|
#include "Helpers/StatForgeFunctionLibrary.h"
|
||||||
|
#include "ProjectEleri/Data/StatDefinitions.h"
|
||||||
|
|
||||||
// Sets default values
|
// Sets default values
|
||||||
AWaterBall::AWaterBall()
|
AWaterBall::AWaterBall()
|
||||||
@@ -27,18 +25,14 @@ void AWaterBall::BeginPlay()
|
|||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
PlayerCharacter = Cast<AMyCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
|
PlayerCharacter = Cast<AMyCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
|
||||||
PlayerCameraManager = Cast<APlayerCameraManager>(UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0));
|
PlayerCameraManager = Cast<APlayerCameraManager>(UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0));
|
||||||
MaxPitch = FMath::Abs(PlayerCameraManager->ViewPitchMin) + PlayerCameraManager->ViewPitchMax;
|
|
||||||
if (MaxPitch == 0) MaxPitch = 1;
|
|
||||||
|
|
||||||
PitchOffset = FMath::Abs(PlayerCameraManager->ViewPitchMax);
|
|
||||||
HighlightBox->SetStaticMesh(HighlightBoxMesh);
|
HighlightBox->SetStaticMesh(HighlightBoxMesh);
|
||||||
HighlightBox->SetVisibility(true);
|
HighlightBox->SetVisibility(true);
|
||||||
HighlightBox->SetMaterial(0, HighlightBoxMaterial);
|
HighlightBox->SetMaterial(0, HighlightBoxMaterial);
|
||||||
HighlightBox->SetRelativeScale3D(FVector(10.0f, 10.0f, 10.0f));
|
|
||||||
|
const float ScaleMultiplier = FMath::Min(UStatForgeFunctionLibrary::GetStatValue(FStat::WateringAreaScaleMultiplier, PlayerCharacter), 1.f);
|
||||||
|
HighlightBox->SetRelativeScale3D(FVector(5.0f * ScaleMultiplier));
|
||||||
HighlightBox->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
HighlightBox->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
||||||
|
|
||||||
ActorsToIgnore.Add(this);
|
|
||||||
ActorsToIgnore.Add(PlayerCharacter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called every frame
|
// Called every frame
|
||||||
@@ -52,64 +46,14 @@ void AWaterBall::Tick(float DeltaTime)
|
|||||||
HighlightBox->SetVisibility(false);
|
HighlightBox->SetVisibility(false);
|
||||||
if (!PlayerCharacter->IsWatering()) return;
|
if (!PlayerCharacter->IsWatering()) return;
|
||||||
|
|
||||||
CurrentPitch = PlayerCharacter->Pitch;
|
|
||||||
CurrentPitch += PitchOffset;
|
|
||||||
if (CurrentPitch > 100.0f)
|
|
||||||
{
|
|
||||||
CurrentPitch -= 360.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
FPredictProjectilePathParams PredictParams;
|
|
||||||
|
|
||||||
float Drag = FMath::Lerp(4.0f, 1.1f, FMath::Abs(CurrentPitch / MaxPitch));
|
|
||||||
FVector ForwardVec = UKismetMathLibrary::FindLookAtRotation(PlayerCharacter->GetCameraWorldPosition(), PlayerCharacter->GetActorLocation()).Quaternion().GetForwardVector();
|
|
||||||
FVector Offset = (ForwardVec * FVector(2000.f, 2000.f, 0.f));
|
|
||||||
FVector EndLocation = PlayerCharacter->GetActorLocation() + Offset;
|
|
||||||
FVector StartingLoc = PlayerCharacter->GetActorLocation();
|
|
||||||
PredictParams.StartLocation = StartingLoc;
|
|
||||||
LaunchVelocity =
|
|
||||||
UKismetMathLibrary::GetDirectionUnitVector(StartingLoc, EndLocation) * FVector(500.0f * Drag, 500.0f * Drag, -30000.f);
|
|
||||||
|
|
||||||
PredictParams.LaunchVelocity = LaunchVelocity;
|
|
||||||
PredictParams.MaxSimTime = 10.0f;
|
|
||||||
PredictParams.bTraceWithCollision = true;
|
|
||||||
PredictParams.SimFrequency = 10.0f;
|
|
||||||
PredictParams.bTraceComplex = true;
|
|
||||||
for (int32 i = 0; i < ActorsToIgnore.Num(); i++)
|
|
||||||
{
|
|
||||||
PredictParams.ActorsToIgnore.Add(ActorsToIgnore[i]);
|
|
||||||
}
|
|
||||||
FPredictProjectilePathResult PredictResults;
|
|
||||||
UGameplayStatics::PredictProjectilePath(GetWorld(), PredictParams, PredictResults);
|
|
||||||
|
|
||||||
HighlightBox->SetVisibility(true);
|
HighlightBox->SetVisibility(true);
|
||||||
FVector HighlightBoxLocation = PredictResults.PathData[PredictResults.PathData.Num() - 1].Location;
|
|
||||||
HighlightBoxLocation.Z += 5;
|
const FVector ForwardVec = UKismetMathLibrary::FindLookAtRotation(PlayerCharacter->GetCameraWorldPosition(), PlayerCharacter->GetActorLocation()).Quaternion().GetForwardVector();
|
||||||
HighlightBox->SetWorldLocation(HighlightBoxLocation);
|
const FVector Offset = (ForwardVec * FVector(700.f, 700.f, 0.f)) + FVector(0.f, 0.f, -115.f);
|
||||||
|
|
||||||
|
HighlightBox->SetWorldLocation(PlayerCharacter->GetActorLocation() + Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<ASeedCarousel*> AWaterBall::GetOverlappingSeeds()
|
|
||||||
{
|
|
||||||
TArray<ASeedCarousel*> Seeds;
|
|
||||||
TArray<FOverlapResult> OverlapResults;
|
|
||||||
FCollisionObjectQueryParams OverlapParams;
|
|
||||||
OverlapParams.AddObjectTypesToQuery(ECC_WorldDynamic);
|
|
||||||
|
|
||||||
FVector BoundsMin, BoundsMax;
|
|
||||||
HighlightBox->GetLocalBounds(BoundsMin, BoundsMax);
|
|
||||||
float Radius = (FVector::Distance(BoundsMin, BoundsMax) * HighlightBox->GetComponentScale().X) / PI;
|
|
||||||
GetWorld()->OverlapMultiByObjectType(OverlapResults, HighlightBox->GetComponentLocation(), FQuat::Identity, OverlapParams, FCollisionShape::MakeSphere(Radius));
|
|
||||||
//DrawDebugSphere(GetWorld(), HighlightBox->GetComponentLocation(), Radius, 16, FColor::Red, false, 5.f);
|
|
||||||
for (const FOverlapResult& OverlapResult : OverlapResults)
|
|
||||||
{
|
|
||||||
if (ASeedCarousel* Carousel = Cast<ASeedCarousel>(OverlapResult.GetActor()))
|
|
||||||
{
|
|
||||||
Seeds.Add(Carousel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Seeds;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AWaterBall::ThrowBall_Implementation()
|
void AWaterBall::ThrowBall_Implementation()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,10 +36,6 @@ protected:
|
|||||||
FVector LaunchVelocity;
|
FVector LaunchVelocity;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
|
||||||
TArray<AActor*> ActorsToIgnore;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
AMyCharacter* PlayerCharacter;
|
AMyCharacter* PlayerCharacter;
|
||||||
|
|
||||||
@@ -49,15 +45,6 @@ public:
|
|||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
UMaterialInstance* HighlightBoxMaterial;
|
UMaterialInstance* HighlightBoxMaterial;
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
|
||||||
float CurrentPitch;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
|
||||||
float PitchOffset;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
|
||||||
float MaxPitch;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
bool bThrowing;
|
bool bThrowing;
|
||||||
|
|
||||||
@@ -79,6 +66,4 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
FVector GetLaunchVelocity() { return LaunchVelocity; }
|
FVector GetLaunchVelocity() { return LaunchVelocity; }
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable)
|
|
||||||
TArray<ASeedCarousel*> GetOverlappingSeeds();
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -357,6 +357,68 @@ void ASeedBedActor::WaterAllSeedSlots()
|
|||||||
WaterSeedInSlot(SlotCoordinate);
|
WaterSeedInSlot(SlotCoordinate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 ASeedBedActor::GatherSlotsInRadius(const FVector& WorldLocation, float Radius, TArray<FIntVector2>& OutSlotCoordinates) const
|
||||||
|
{
|
||||||
|
OutSlotCoordinates.Reset();
|
||||||
|
|
||||||
|
// A radius of zero only ever covers the point itself, so there is nothing to gather
|
||||||
|
if (Radius <= 0.f)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float RadiusSquared = FMath::Square(Radius);
|
||||||
|
|
||||||
|
for (const TPair<FIntVector2, FSeedBedSeedSlot>& SlotPair : SeedBedSeedSlotsMap)
|
||||||
|
{
|
||||||
|
// Only living plants are watered, an empty or dead slot has nothing to soak up
|
||||||
|
if (!SlotHasLivingPlant(SlotPair.Value))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FVector SlotWorldLocation;
|
||||||
|
if (!GetSlotWorldLocation(SlotPair.Key, SlotWorldLocation))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only the plane of the bed counts, so watering from above or from uphill reaches the same slots
|
||||||
|
if (FVector::DistSquaredXY(WorldLocation, SlotWorldLocation) > RadiusSquared)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutSlotCoordinates.Add(SlotPair.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OutSlotCoordinates.Num();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 ASeedBedActor::WaterSlotsInRadius(const FVector& WorldLocation, float Radius)
|
||||||
|
{
|
||||||
|
// The slots are gathered first, a listener of the refresh is free to change the map while we water
|
||||||
|
TArray<FIntVector2> SlotCoordinates;
|
||||||
|
const int32 WateredSlotCount = GatherSlotsInRadius(WorldLocation, Radius, SlotCoordinates);
|
||||||
|
|
||||||
|
for (const FIntVector2& SlotCoordinate : SlotCoordinates)
|
||||||
|
{
|
||||||
|
WaterSeedInSlot(SlotCoordinate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The cache is what the game state falls back to once the bed is streamed out, so it has to know
|
||||||
|
// about the watering right away. Nothing was watered, so there is nothing to cache either.
|
||||||
|
if (WateredSlotCount > 0)
|
||||||
|
{
|
||||||
|
if (AEleriGameState* GameState = Cast<AEleriGameState>(UGameplayStatics::GetGameState(this)))
|
||||||
|
{
|
||||||
|
GameState->CacheSeedData(SeedBedIndex, PrepareSeedSaveData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return WateredSlotCount;
|
||||||
|
}
|
||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
// GRID GENERATION
|
// GRID GENERATION
|
||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
@@ -623,7 +685,12 @@ void ASeedBedActor::HighlightSlot(FIntVector2 SlotCoordinate)
|
|||||||
|
|
||||||
void ASeedBedActor::StopHighlightingSlot()
|
void ASeedBedActor::StopHighlightingSlot()
|
||||||
{
|
{
|
||||||
HighlightDecal->SetVisibility(false);
|
// The decal only exists once BeginPlay created it, a highlight is stopped on beds that never got one as well
|
||||||
|
if (IsValid(HighlightDecal))
|
||||||
|
{
|
||||||
|
HighlightDecal->SetVisibility(false);
|
||||||
|
}
|
||||||
|
|
||||||
HighlightedSlotIndex = FIntVector2::NoneValue;
|
HighlightedSlotIndex = FIntVector2::NoneValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,6 +717,14 @@ int32 ASeedBedActor::GetFreeSlotCount() const
|
|||||||
return FreeSlotCount;
|
return FreeSlotCount;
|
||||||
}
|
}
|
||||||
bool ASeedBedActor::FindClosestFreeSlot(const FVector& WorldLocation, FIntVector2& OutSlotCoordinate) const
|
bool ASeedBedActor::FindClosestFreeSlot(const FVector& WorldLocation, FIntVector2& OutSlotCoordinate) const
|
||||||
|
{
|
||||||
|
float DistanceSquared = 0.f;
|
||||||
|
|
||||||
|
// The distance of the slot is only interesting for the planting highlight, the plain lookup ignores it
|
||||||
|
return FindClosestFreeSlotWithDistance(WorldLocation, OutSlotCoordinate, DistanceSquared);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ASeedBedActor::FindClosestFreeSlotWithDistance(const FVector& WorldLocation, FIntVector2& OutSlotCoordinate, float& OutDistanceSquared) const
|
||||||
{
|
{
|
||||||
bool bFoundSlot = false;
|
bool bFoundSlot = false;
|
||||||
float ClosestDistanceSquared = 0.f;
|
float ClosestDistanceSquared = 0.f;
|
||||||
@@ -667,7 +742,8 @@ bool ASeedBedActor::FindClosestFreeSlot(const FVector& WorldLocation, FIntVector
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float DistanceSquared = FVector::DistSquared(WorldLocation, SlotWorldLocation);
|
// Only the plane of the bed counts, a player standing uphill has to reach the slot just as well
|
||||||
|
const float DistanceSquared = FVector::DistSquaredXY(WorldLocation, SlotWorldLocation);
|
||||||
if (!bFoundSlot || DistanceSquared < ClosestDistanceSquared)
|
if (!bFoundSlot || DistanceSquared < ClosestDistanceSquared)
|
||||||
{
|
{
|
||||||
bFoundSlot = true;
|
bFoundSlot = true;
|
||||||
@@ -676,6 +752,8 @@ bool ASeedBedActor::FindClosestFreeSlot(const FVector& WorldLocation, FIntVector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OutDistanceSquared = ClosestDistanceSquared;
|
||||||
|
|
||||||
return bFoundSlot;
|
return bFoundSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -196,10 +196,24 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
||||||
void WaterAllSeedSlots();
|
void WaterAllSeedSlots();
|
||||||
|
|
||||||
|
/** Waters every planted slot whose world location lies within the given radius around a world point.
|
||||||
|
* Returns the number of slots that were watered and caches the new slot data into the game state. */
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
||||||
|
int32 WaterSlotsInRadius(const FVector& WorldLocation, float Radius);
|
||||||
|
|
||||||
|
/** Collects the coordinates of every planted slot whose world location lies within the given radius.
|
||||||
|
* Returns the number of collected slots, OutSlotCoordinates is emptied first. */
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
||||||
|
int32 GatherSlotsInRadius(const FVector& WorldLocation, float Radius, TArray<FIntVector2>& OutSlotCoordinates) const;
|
||||||
|
|
||||||
/** Finds the free slot that is closest to the given world location */
|
/** Finds the free slot that is closest to the given world location */
|
||||||
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
||||||
bool FindClosestFreeSlot(const FVector& WorldLocation, FIntVector2& OutSlotCoordinate) const;
|
bool FindClosestFreeSlot(const FVector& WorldLocation, FIntVector2& OutSlotCoordinate) const;
|
||||||
|
|
||||||
|
/** Same as FindClosestFreeSlot, but also reports how far away the slot is, as a squared distance in XY */
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
||||||
|
bool FindClosestFreeSlotWithDistance(const FVector& WorldLocation, FIntVector2& OutSlotCoordinate, float& OutDistanceSquared) const;
|
||||||
|
|
||||||
/** World location a plant of the given slot is placed at */
|
/** World location a plant of the given slot is placed at */
|
||||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Seed Bed")
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Seed Bed")
|
||||||
bool GetSlotWorldLocation(FIntVector2 SlotCoordinate, FVector& OutWorldLocation) const;
|
bool GetSlotWorldLocation(FIntVector2 SlotCoordinate, FVector& OutWorldLocation) const;
|
||||||
|
|||||||
@@ -23,7 +23,12 @@
|
|||||||
#include "Subsystem/InteractionSubsystem.h"
|
#include "Subsystem/InteractionSubsystem.h"
|
||||||
#include "Interface/InteractableActorInterface.h"
|
#include "Interface/InteractableActorInterface.h"
|
||||||
#include "EngineUtils.h"
|
#include "EngineUtils.h"
|
||||||
|
#include "Components/StatForgeComponent.h"
|
||||||
|
#include "Helpers/StatForgeFunctionLibrary.h"
|
||||||
|
#include "ProjectEleri/Data/StatDefinitions.h"
|
||||||
#include "ProjectEleri/Items/SeedBedActor.h"
|
#include "ProjectEleri/Items/SeedBedActor.h"
|
||||||
|
#include "ProjectEleri/Settings/EleriGameSettings.h"
|
||||||
|
#include "ProjectEleri/System/EleriGameplayTags.h"
|
||||||
|
|
||||||
AEleriPlayerController::AEleriPlayerController(const FObjectInitializer &ObjectInitializer)
|
AEleriPlayerController::AEleriPlayerController(const FObjectInitializer &ObjectInitializer)
|
||||||
: Super(ObjectInitializer)
|
: Super(ObjectInitializer)
|
||||||
@@ -53,6 +58,30 @@ void AEleriPlayerController::BeginPlay()
|
|||||||
AlchemyManager = Cast<AAlchemyManager>(UGameplayStatics::GetActorOfClass(GetWorld(), AAlchemyManager::StaticClass()));
|
AlchemyManager = Cast<AAlchemyManager>(UGameplayStatics::GetActorOfClass(GetWorld(), AAlchemyManager::StaticClass()));
|
||||||
|
|
||||||
SelectionManagerInventorySlots = NewObject<USelectionManager>();
|
SelectionManagerInventorySlots = NewObject<USelectionManager>();
|
||||||
|
ToggleMovement(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AEleriPlayerController::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||||
|
{
|
||||||
|
ToggleMovement(true);
|
||||||
|
|
||||||
|
Super::EndPlay(EndPlayReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AEleriPlayerController::ToggleMovement(bool bActive)
|
||||||
|
{
|
||||||
|
UStatForgeComponent* StatForgeComponent = UMainBlueprintFunctionLibrary::GetStatForgeComponentFromPlayer(this);
|
||||||
|
if (!StatForgeComponent) return;
|
||||||
|
|
||||||
|
if (bActive)
|
||||||
|
{
|
||||||
|
StatForgeComponent->RemoveGameplayStatEffect(MovementDisabledEffect);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const UEleriGameSettings* GameSettings = UEleriGameSettings::GetEleriGameSettings();
|
||||||
|
ensure(GameSettings);
|
||||||
|
MovementDisabledEffect = StatForgeComponent->ApplyGameplayStatEffect(GameSettings->MovementDisableEffectClass, TMap<FName, float>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AEleriPlayerController::Tick(float DeltaTime)
|
void AEleriPlayerController::Tick(float DeltaTime)
|
||||||
@@ -332,19 +361,20 @@ void AEleriPlayerController::OnMove(const FInputActionValue &Value)
|
|||||||
if (IsInMenu())
|
if (IsInMenu())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FVector2D AnalogueValue = Value.Get<FInputActionValue::Axis2D>();
|
const FVector2D AnalogueValue = Value.Get<FInputActionValue::Axis2D>();
|
||||||
MovementDirection = AnalogueValue;
|
MovementDirection = AnalogueValue;
|
||||||
|
|
||||||
if (PlayerCharacter)
|
if (PlayerCharacter)
|
||||||
{
|
{
|
||||||
FRotator CtrlRotation = GetControlRotation();
|
if (UStatForgeFunctionLibrary::HasTag(CharacterState::MovementDisabled, PlayerCharacter))
|
||||||
FRotator YawRotation(0, CtrlRotation.Yaw, 0);
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float AppliedMovementVelocity = UStatForgeFunctionLibrary::GetStatValue(FStat::MovementSpeedMultiplier, PlayerCharacter);
|
||||||
|
|
||||||
// FVector ForwardFacing = UKismetMathLibrary::GetForwardVector(bFlying? PlayerCameraManager->GetCameraRotation() : CharRotForward);
|
const FVector ForwardVec = PlayerCharacter->GetPlayerCamera()->GetForwardVector();
|
||||||
float AppliedMovementVelocity = 1.f; // MovementVelocity * (bFlying? 0.5f : 1.f);
|
const FVector RightVec = PlayerCharacter->GetPlayerCamera()->GetRightVector();
|
||||||
|
|
||||||
FVector ForwardVec = PlayerCharacter->GetPlayerCamera()->GetForwardVector();
|
|
||||||
FVector RightVec = PlayerCharacter->GetPlayerCamera()->GetRightVector();
|
|
||||||
|
|
||||||
PlayerCharacter->AddMovementInput(ForwardVec, MovementDirection.Y * AppliedMovementVelocity);
|
PlayerCharacter->AddMovementInput(ForwardVec, MovementDirection.Y * AppliedMovementVelocity);
|
||||||
PlayerCharacter->AddMovementInput(RightVec, MovementDirection.X * AppliedMovementVelocity);
|
PlayerCharacter->AddMovementInput(RightVec, MovementDirection.X * AppliedMovementVelocity);
|
||||||
@@ -446,10 +476,13 @@ void AEleriPlayerController::OnWateringActionStart(const FInputActionValue &Valu
|
|||||||
MainGameUI->IsAlchemyOpen() ||
|
MainGameUI->IsAlchemyOpen() ||
|
||||||
IsInMenu())
|
IsInMenu())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Watering = true;
|
Watering = true;
|
||||||
PlayerCharacter->BeginWatering();
|
PlayerCharacter->BeginWatering();
|
||||||
OnWatering.Broadcast(Watering);
|
OnWatering.Broadcast(Watering);
|
||||||
OnChangeInputContext.Broadcast(2);
|
OnChangeInputContext.Broadcast(2);
|
||||||
|
|
||||||
|
ToggleMovement(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AEleriPlayerController::OnWateringActionEnd(const FInputActionValue &Value)
|
void AEleriPlayerController::OnWateringActionEnd(const FInputActionValue &Value)
|
||||||
@@ -463,6 +496,8 @@ void AEleriPlayerController::OnWateringActionEnd(const FInputActionValue &Value)
|
|||||||
PlayerCharacter->EndWatering();
|
PlayerCharacter->EndWatering();
|
||||||
OnWatering.Broadcast(Watering);
|
OnWatering.Broadcast(Watering);
|
||||||
OnChangeInputContext.Broadcast(1);
|
OnChangeInputContext.Broadcast(1);
|
||||||
|
|
||||||
|
ToggleMovement(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AEleriPlayerController::OnWateringThrowAction(const FInputActionValue &Value)
|
void AEleriPlayerController::OnWateringThrowAction(const FInputActionValue &Value)
|
||||||
|
|||||||
@@ -128,35 +128,50 @@ void AMyCharacter::Tick(float DeltaTime)
|
|||||||
|
|
||||||
if (bIsPlanting)
|
if (bIsPlanting)
|
||||||
{
|
{
|
||||||
|
// The reach is measured from the closest free slot and not from the center of the bed: a bed is as big as
|
||||||
|
// its grid, so its outer slots sit up to 1273 units away from that center and would never be in reach
|
||||||
|
const float SlotReachSquared = FMath::Square(200.f);
|
||||||
|
|
||||||
ASeedBedActor* ClosestActor = nullptr;
|
ASeedBedActor* ClosestActor = nullptr;
|
||||||
float ClosestDistance = 9999999999.f;
|
FIntVector2 ClosestSlotCoordinate = FIntVector2::NoneValue;
|
||||||
|
float ClosestSlotDistance = SlotReachSquared;
|
||||||
const FVector PointToCheck = GetActorLocation() + (GetActorForwardVector() * 100.f);
|
const FVector PointToCheck = GetActorLocation() + (GetActorForwardVector() * 100.f);
|
||||||
const float ThresholdDist = FMath::Pow(1000.f, 2.f);
|
|
||||||
|
|
||||||
for (ASeedBedActor* SeedBeds : SeedBedActors)
|
for (ASeedBedActor* SeedBeds : SeedBedActors)
|
||||||
{
|
{
|
||||||
const double Dist = FVector::DistSquaredXY(PointToCheck, SeedBeds->GetActorLocation());
|
if (!IsValid(SeedBeds))
|
||||||
if (Dist <= ClosestDistance && Dist <= ThresholdDist)
|
|
||||||
{
|
{
|
||||||
ClosestDistance = Dist;
|
continue;
|
||||||
ClosestActor = SeedBeds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FIntVector2 OutSlotCoordinate;
|
||||||
|
float OutSlotDistance = 0.f;
|
||||||
|
if (!SeedBeds->FindClosestFreeSlotWithDistance(PointToCheck, OutSlotCoordinate, OutSlotDistance))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A bed is only a candidate while its closest free slot is in reach, the closest slot wins
|
||||||
|
if (OutSlotDistance > ClosestSlotDistance)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClosestSlotDistance = OutSlotDistance;
|
||||||
|
ClosestSlotCoordinate = OutSlotCoordinate;
|
||||||
|
ClosestActor = SeedBeds;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LastClosestSeedBedActor)
|
if (LastClosestSeedBedActor)
|
||||||
{
|
{
|
||||||
LastClosestSeedBedActor->StopHighlightingSlot();
|
LastClosestSeedBedActor->StopHighlightingSlot();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ClosestActor)
|
if (ClosestActor)
|
||||||
{
|
{
|
||||||
FIntVector2 OutSlotCoordinate;
|
ClosestActor->HighlightSlot(ClosestSlotCoordinate);
|
||||||
if (ClosestActor->FindClosestFreeSlot(PointToCheck, OutSlotCoordinate))
|
|
||||||
{
|
|
||||||
ClosestActor->HighlightSlot(OutSlotCoordinate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LastClosestSeedBedActor = ClosestActor;
|
LastClosestSeedBedActor = ClosestActor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,9 @@ private:
|
|||||||
|
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
USelectionManager* SelectionManagerInventorySlots;
|
USelectionManager* SelectionManagerInventorySlots;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
FGuid MovementDisabledEffect;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
@@ -108,8 +111,14 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
|
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// Enable or disable movement with a character tag
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
void ToggleMovement(bool bActive);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, BlueprintPure)
|
UFUNCTION(BlueprintCallable, BlueprintPure)
|
||||||
FORCEINLINE USelectionManager* GetSelectionManagerInventorySlot() { return SelectionManagerInventorySlots; }
|
FORCEINLINE USelectionManager* GetSelectionManagerInventorySlot() { return SelectionManagerInventorySlots; }
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public:
|
|||||||
|
|
||||||
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "Ability System|Effects")
|
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "Ability System|Effects")
|
||||||
TSubclassOf<UGameplayStatEffect> ExpIncreaseEffectClass;
|
TSubclassOf<UGameplayStatEffect> ExpIncreaseEffectClass;
|
||||||
|
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "Ability System|Effects")
|
||||||
|
TSubclassOf<UGameplayStatEffect> MovementDisableEffectClass;
|
||||||
|
|
||||||
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "Ability System|Professions")
|
UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "Ability System|Professions")
|
||||||
TArray<float> ProfessionExpArray;
|
TArray<float> ProfessionExpArray;
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
|
|
||||||
#include "EleriGameplayTags.h"
|
#include "EleriGameplayTags.h"
|
||||||
|
|
||||||
namespace TimeOfDay {
|
namespace CharacterState
|
||||||
|
{
|
||||||
|
UE_DEFINE_GAMEPLAY_TAG(MovementDisabled, TEXT("CharacterState.MovementDisabled"))
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace TimeOfDay
|
||||||
|
{
|
||||||
UE_DEFINE_GAMEPLAY_TAG(TimePassed, TEXT("TimeOfDay.TimePassed"))
|
UE_DEFINE_GAMEPLAY_TAG(TimePassed, TEXT("TimeOfDay.TimePassed"))
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Stats {
|
namespace Stats
|
||||||
|
{
|
||||||
UE_DEFINE_GAMEPLAY_TAG(Energy, TEXT("Stats.Energy"))
|
UE_DEFINE_GAMEPLAY_TAG(Energy, TEXT("Stats.Energy"))
|
||||||
UE_DEFINE_GAMEPLAY_TAG(TimesEatenToday, TEXT("Stats.TimesEatenToday"))
|
UE_DEFINE_GAMEPLAY_TAG(TimesEatenToday, TEXT("Stats.TimesEatenToday"))
|
||||||
UE_DEFINE_GAMEPLAY_TAG(FriendPointsObtainAmount, TEXT("Stats.FriendPointsObtainAmount"))
|
UE_DEFINE_GAMEPLAY_TAG(FriendPointsObtainAmount, TEXT("Stats.FriendPointsObtainAmount"))
|
||||||
|
|||||||
@@ -2,14 +2,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "NativeGameplayTags.h"
|
#include "NativeGameplayTags.h"
|
||||||
|
|
||||||
namespace TimeOfDay {
|
namespace CharacterState
|
||||||
|
{
|
||||||
|
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(MovementDisabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace TimeOfDay
|
||||||
|
{
|
||||||
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(TimePassed)
|
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(TimePassed)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Stats {
|
namespace Stats
|
||||||
|
{
|
||||||
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Energy)
|
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Energy)
|
||||||
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(TimesEatenToday)
|
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(TimesEatenToday)
|
||||||
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(FriendPointsObtainAmount)
|
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(FriendPointsObtainAmount)
|
||||||
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(GatheringDoubleDropChance)
|
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(GatheringDoubleDropChance)
|
||||||
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(GatheringHqDropChance)
|
PROJECTELERI_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(GatheringHqDropChance)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user