diff --git a/Content/Animations/Boss/AB_Boss.uasset b/Content/Animations/Boss/AB_Boss.uasset index 12de586..990d267 100644 --- a/Content/Animations/Boss/AB_Boss.uasset +++ b/Content/Animations/Boss/AB_Boss.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62ec006f5b165f6752c5cbf4cecb1e13bd4a39bbb07f2de3e6b2d117e625e514 -size 302681 +oid sha256:de84708d9012a547f8d2bae72250b642e2057f2586628d1f13c0c360c4c84de0 +size 302922 diff --git a/Content/BlueprintAI/AI/AIBruh_Boss.uasset b/Content/BlueprintAI/AI/AIBruh_Boss.uasset index 524ec5a..cf8b6f3 100644 --- a/Content/BlueprintAI/AI/AIBruh_Boss.uasset +++ b/Content/BlueprintAI/AI/AIBruh_Boss.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bfa566cea4453caf6bd27c616f7ece25fadb0557a37c68a347734c79097d62e6 -size 143344 +oid sha256:5602edbffa51f656dde7f0766e36de7a692812a1d1487c3b2eaf2eadc9c0c41a +size 143109 diff --git a/Content/Blueprints/Combat_UI/BP_TurnBaseCombatV2.uasset b/Content/Blueprints/Combat_UI/BP_TurnBaseCombatV2.uasset index eede7e3..2515764 100644 --- a/Content/Blueprints/Combat_UI/BP_TurnBaseCombatV2.uasset +++ b/Content/Blueprints/Combat_UI/BP_TurnBaseCombatV2.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4dd88316fe4a1f9e2208b3db3d94ae401765d151786c67a0f5ef9e88a80ac8b2 -size 31304 +oid sha256:344276ef0b680eda3a858cd5bdec13ae1d4faf51700109739314ae3e964b4272 +size 31315 diff --git a/Content/Blueprints/StatusEffects/BP_DamageDown.uasset b/Content/Blueprints/StatusEffects/BP_DamageDown.uasset new file mode 100644 index 0000000..b05d92b --- /dev/null +++ b/Content/Blueprints/StatusEffects/BP_DamageDown.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:725465e42f03b432e3ac51705eac6998e369b933262565349694748dfd8cbfd5 +size 6090 diff --git a/Content/Blueprints/StatusEffects/BP_DamageDownPlayer.uasset b/Content/Blueprints/StatusEffects/BP_DamageDownPlayer.uasset new file mode 100644 index 0000000..6682e95 --- /dev/null +++ b/Content/Blueprints/StatusEffects/BP_DamageDownPlayer.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a4c63e8e94e70e90a3ebb6c5118ce7c14e473790d1f47b58b74a62767212916 +size 6667 diff --git a/Source/the_twilight_abyss/Quest/Quest.cpp b/Source/the_twilight_abyss/Quest/Quest.cpp index 451a80c..ade9822 100644 --- a/Source/the_twilight_abyss/Quest/Quest.cpp +++ b/Source/the_twilight_abyss/Quest/Quest.cpp @@ -33,6 +33,11 @@ bool UQuest::WorldStateMatch(UWorldState* A, UWorldState* B) if (A->Items.IsEmpty() && !B->Items.IsEmpty()) return false; for (UBaseItem* Item : B->Items) { + if (A->Items.IndexOfByPredicate([Item](const UBaseItem* AItem) { return AItem->ItemID == Item->ItemID; }) == -1) + { + UE_LOG(LogTemp, Warning, TEXT("WorldState Predicate Failed")); + return false; + } if (!A->Items.Contains(Item) && Item->StackCount > A->Items[A->Items.IndexOfByPredicate([Item](const UBaseItem* AItem) { return AItem->ItemID == Item->ItemID; })]->StackCount) { return false; diff --git a/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDown.cpp b/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDown.cpp new file mode 100644 index 0000000..80b0442 --- /dev/null +++ b/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDown.cpp @@ -0,0 +1,26 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "DamageDown.h" + +void UDamageDown::Invoke(AActor* Character, float TimeOfExpiry) +{ + CombatSystem = Cast(GetWorld()->GetGameState()); + CombatSystem->EnemyBaseDamageMultiplier -= EnemyDamageMultiplierDecreaseAmount; +} + +void UDamageDown::OnExpiry(AActor* Character) +{ + CombatSystem->EnemyBaseDamageMultiplier += EnemyDamageMultiplierDecreaseAmount; + Super::OnExpiry(Character); +} + +void UDamageDown::OnEnemyTurn(AActor* Enemy, AActor* Character) +{ + BaseDuration -= 1.0f; + Super::OnEnemyTurn(Enemy, Character); + if (BaseDuration <= 0.0f) + { + OnExpiry(Character); + } +} diff --git a/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDown.h b/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDown.h new file mode 100644 index 0000000..23a43d0 --- /dev/null +++ b/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDown.h @@ -0,0 +1,27 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "../StatusEffect.h" +#include "the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.h" +#include "DamageDown.generated.h" + +/** + * + */ +UCLASS() +class THE_TWILIGHT_ABYSS_API UDamageDown : public UStatusEffect +{ + GENERATED_BODY() + +public: + UPROPERTY(EditDefaultsOnly) + float EnemyDamageMultiplierDecreaseAmount = 0.2f; + virtual void Invoke(AActor* Character, float TimeOfExpiry) override; + virtual void OnExpiry(AActor* Character) override; + virtual void OnEnemyTurn(AActor* Enemy, AActor* Character) override; + +protected: + ATurnBaseCombatV2* CombatSystem; +}; diff --git a/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDownPlayer.cpp b/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDownPlayer.cpp new file mode 100644 index 0000000..a0ba615 --- /dev/null +++ b/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDownPlayer.cpp @@ -0,0 +1,26 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "DamageDownPlayer.h" + +void UDamageDownPlayer::Invoke(AActor* Character, float TimeOfExpiry) +{ + CombatSystem = Cast(GetWorld()->GetGameState()); + CombatSystem->BaseDamageMultiplier -= PlayerDamageMultiplierDecreaseAmount; +} + +void UDamageDownPlayer::OnExpiry(AActor* Character) +{ + Super::OnExpiry(Character); + CombatSystem->BaseDamageMultiplier += PlayerDamageMultiplierDecreaseAmount; +} + +void UDamageDownPlayer::OnEnemyTurn(AActor* Enemy, AActor* Character) +{ + BaseDuration -= 1.0f; + Super::OnEnemyTurn(Enemy, Character); + if (BaseDuration <= 0.0f) + { + OnExpiry(Character); + } +} diff --git a/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDownPlayer.h b/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDownPlayer.h new file mode 100644 index 0000000..8170034 --- /dev/null +++ b/Source/the_twilight_abyss/TurnBasedCombatV2/StatusEffects/DamageDownPlayer.h @@ -0,0 +1,27 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "../StatusEffect.h" +#include "the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.h" +#include "DamageDownPlayer.generated.h" + +/** + * + */ +UCLASS() +class THE_TWILIGHT_ABYSS_API UDamageDownPlayer : public UStatusEffect +{ + GENERATED_BODY() + +public: + UPROPERTY(EditDefaultsOnly) + float PlayerDamageMultiplierDecreaseAmount = 0.2f; + virtual void Invoke(AActor* Character, float TimeOfExpiry) override; + virtual void OnExpiry(AActor* Character) override; + virtual void OnEnemyTurn(AActor* Enemy, AActor* Character) override; + +protected: + ATurnBaseCombatV2* CombatSystem; +}; diff --git a/Source/the_twilight_abyss/TurnBasedCombatV2/StatusSystem.h b/Source/the_twilight_abyss/TurnBasedCombatV2/StatusSystem.h index 1076de3..f751ceb 100644 --- a/Source/the_twilight_abyss/TurnBasedCombatV2/StatusSystem.h +++ b/Source/the_twilight_abyss/TurnBasedCombatV2/StatusSystem.h @@ -48,7 +48,7 @@ public: UPROPERTY() UWrapBox* StatusIconsBox; - UPROPERTY() + UPROPERTY(VisibleAnywhere) TArray ActiveStatusEffects; protected: diff --git a/Source/the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.cpp b/Source/the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.cpp index c6816ca..e0c006b 100644 --- a/Source/the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.cpp +++ b/Source/the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.cpp @@ -23,10 +23,15 @@ ATurnBaseCombatV2::ATurnBaseCombatV2() { static ConstructorHelpers::FClassFinder HUDWidgetClass(TEXT("/Game/Blueprints/Combat_UI/Combat_UI")); HUDWidget = HUDWidgetClass.Class; + static ConstructorHelpers::FClassFinder StatusEffectThornsClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_Thorns")); ThornsStatusEffect = StatusEffectThornsClassFinder.Class; static ConstructorHelpers::FClassFinder StatusEffectDotClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_DamageOverTime")); DOTStatusEffect = StatusEffectDotClassFinder.Class; + static ConstructorHelpers::FClassFinder StatusEffectDamageDownClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_DamageDown")); + DamageDownStatusEffect = StatusEffectDamageDownClassFinder.Class; + static ConstructorHelpers::FClassFinder StatusEffectDamageDownPlayerClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_DamageDownPlayer")); + DamageDownPlayerStatusEffect = StatusEffectDamageDownPlayerClassFinder.Class; static ConstructorHelpers::FClassFinder DeathScreenWidgetClass(TEXT("/Game/Blueprints/Death_UI/Death_UI")); DeathScreenWidgetSubclass = DeathScreenWidgetClass.Class; @@ -58,19 +63,27 @@ void ATurnBaseCombatV2::StartCombat(AActor* Enemy, const bool bWasShot) PlayerController->SetInputMode(FInputModeGameAndUI()); PlayerController->bShowMouseCursor = true; - // FVector Direction = Enemy->GetActorLocation() - PlayerActor->GetActorLocation(); - // Direction.Normalize(); - // FRotator LookAtRotation = FRotationMatrix::MakeFromX(Direction).Rotator(); - // const FRotator NewRotation = UKismetMathLibrary::FindLookAtRotation(Cast(PlayerActor->FindComponentByClass())->GetComponentLocation(), EnemyActor->GetActorLocation()); - // LookAtRotation.Pitch = NewRotation.Pitch - PlayerActor->GetActorRotation().Pitch; - // PlayerController->SetControlRotation(LookAtRotation); - if (EnemyBlackboard->GetValueAsBool("IsInCombat")) return; EnemyBlackboard->SetValueAsBool("IsInCombat", true); const FProperty* HealthProperty = Enemy->GetClass()->FindPropertyByName(FName("Health")); int32* EnemyHealthPtr = HealthProperty->ContainerPtrToValuePtr(Enemy); EnemyHealth = EnemyHealthPtr; + FProperty* IsBossProperty = FindFieldChecked(EnemyActor->GetClass(), "IsBoss"); + if (const FBoolProperty* IsBossBoolProperty = CastFieldChecked(IsBossProperty); IsBossBoolProperty->GetPropertyValue_InContainer(EnemyActor)) + { + FOutputDeviceNull AR; + const FString Command = FString::Printf(TEXT("TriggerCombatAnimation true")); + EnemyActor->CallFunctionByNameWithArguments(*Command, AR, nullptr, true); + FVector Direction = EnemyActor->GetActorLocation() - PlayerActor->GetActorLocation(); + Direction.Normalize(); + FRotator LookAtRotation = FRotationMatrix::MakeFromX(Direction).Rotator(); + const FRotator NewRotation = UKismetMathLibrary::FindLookAtRotation(Cast(PlayerActor->FindComponentByClass())->GetComponentLocation(), EnemyActor->GetActorLocation()); + LookAtRotation.Pitch = NewRotation.Pitch - PlayerActor->GetActorRotation().Pitch; + LookAtRotation.Pitch += 10; //Offset + PlayerController->SetControlRotation(LookAtRotation); + } + if (IsValid(CombatTutorialWidgetInstance) && CombatTutorialWidgetInstance->IsInViewport()) return; if (!HasSeenTutorial) { @@ -93,6 +106,7 @@ void ATurnBaseCombatV2::CombatCheck(const bool bWasShot) ChainDamageMultiplier = 0; BaseDamageMultiplier = DefaultBaseDamageMultiplier; + EnemyBaseDamageMultiplier = DefaultEnemyBaseDamageMultiplier; if (bIsBuffed) BaseDamageMultiplier += 1.0f; DamageMultiplierTextBlock->SetText(FText::FromString("")); @@ -249,28 +263,14 @@ void ATurnBaseCombatV2::Tick(const float DeltaTime) { APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); FProperty* IsBossProperty = FindFieldChecked(EnemyActor->GetClass(), "IsBoss"); - const FBoolProperty* IsBossBoolProperty = CastFieldChecked(IsBossProperty); - if (IsBossBoolProperty->GetPropertyValue_InContainer(EnemyActor)) - { - FOutputDeviceNull AR; - const FString Command = FString::Printf(TEXT("TriggerCombatAnimation true")); - EnemyActor->CallFunctionByNameWithArguments(*Command, AR, nullptr, true); - - FVector Direction = EnemyActor->GetActorLocation() - PlayerActor->GetActorLocation(); - Direction.Normalize(); - FRotator LookAtRotation = FRotationMatrix::MakeFromX(Direction).Rotator(); - const FRotator NewRotation = UKismetMathLibrary::FindLookAtRotation(Cast(PlayerActor->FindComponentByClass())->GetComponentLocation(), EnemyActor->GetActorLocation()); - LookAtRotation.Pitch = NewRotation.Pitch - PlayerActor->GetActorRotation().Pitch; - PlayerController->SetControlRotation(LookAtRotation); - } - else + if (const FBoolProperty* IsBossBoolProperty = CastFieldChecked(IsBossProperty); !IsBossBoolProperty->GetPropertyValue_InContainer(EnemyActor)) { FVector Direction = EnemyActor->GetActorLocation() - PlayerActor->GetActorLocation(); Direction.Normalize(); FRotator LookAtRotation = FRotationMatrix::MakeFromX(Direction).Rotator(); const FRotator NewRotation = UKismetMathLibrary::FindLookAtRotation(Cast(PlayerActor->FindComponentByClass())->GetComponentLocation(), Cast(EnemyActor->FindComponentByClass())->GetComponentLocation()); LookAtRotation.Pitch = NewRotation.Pitch - PlayerActor->GetActorRotation().Pitch; - Cast(PlayerActor->FindComponentByClass())->SetWorldRotation(LookAtRotation); + PlayerController->SetControlRotation(LookAtRotation); } } } @@ -308,6 +308,7 @@ void ATurnBaseCombatV2::ExecuteCast(FString Combo) } if (IsSpecialCombo(Combo)) { + FOutputDeviceNull AR; UStatusSystem* StatusSystem = Cast(PlayerActor->GetComponentByClass(UStatusSystem::StaticClass())); if (Combo == "PA") { @@ -315,6 +316,10 @@ void ATurnBaseCombatV2::ExecuteCast(FString Combo) StatusSystem->AddStatusEffect(TempThornsStatusEffect, 1, false); StatusEffects.Add(TempThornsStatusEffect); AddBattleLogMessage("Player Casted Thorns"); + StatusTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 1.0f, 1.0f, 1.0f))); + StatusTextBlock->SetText(FText::FromString("Casted Thorns")); + const FString Command3 = FString::Printf(TEXT("PlayStatusAnimation")); + HUD->CallFunctionByNameWithArguments(*Command3, AR, nullptr, true); } else if (Combo == "PI") { @@ -322,6 +327,21 @@ void ATurnBaseCombatV2::ExecuteCast(FString Combo) StatusSystem->AddStatusEffect(TempDOTStatusEffect, 1, false); StatusEffects.Add(TempDOTStatusEffect); AddBattleLogMessage("Player Casted DOT"); + StatusTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 1.0f, 1.0f, 1.0f))); + StatusTextBlock->SetText(FText::FromString("Casted DOT")); + const FString Command3 = FString::Printf(TEXT("PlayStatusAnimation")); + HUD->CallFunctionByNameWithArguments(*Command3, AR, nullptr, true); + } + else if (Combo == "AI") + { + UStatusEffect* TempDamageDownStatusEffect = NewObject(PlayerActor, DamageDownStatusEffect); + StatusSystem->AddStatusEffect(TempDamageDownStatusEffect, 1); + StatusEffects.Add(TempDamageDownStatusEffect); + AddBattleLogMessage("Player Casted DamageDown"); + StatusTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 1.0f, 1.0f, 1.0f))); + StatusTextBlock->SetText(FText::FromString("Enemy Damage Down")); + const FString Command3 = FString::Printf(TEXT("PlayStatusAnimation")); + HUD->CallFunctionByNameWithArguments(*Command3, AR, nullptr, true); } } @@ -402,12 +422,12 @@ void ATurnBaseCombatV2::RevertActionPoints() void ATurnBaseCombatV2::DamagePlayer(int Damage, const FString& DamageType) { FOutputDeviceNull AR; - *PlayerHealth -= FMath::Clamp(Damage * BaseDefenseMultiplier, 0, 100); - DamageAmountPlayerTextBlock->SetText(FText::FromString("-" + FString::FromInt(Damage * BaseDefenseMultiplier))); + *PlayerHealth -= FMath::Clamp(Damage * EnemyBaseDamageMultiplier, 0, 100); + DamageAmountPlayerTextBlock->SetText(FText::FromString("-" + FString::FromInt(Damage * EnemyBaseDamageMultiplier))); const FString Command3 = FString::Printf(TEXT("PlayDamagePlayerTextAnimation")); BookHUD->CallFunctionByNameWithArguments(*Command3, AR, nullptr, true); UpdateProgressBars(); - AddBattleLogMessage("Player was damaged for " + FString::FromInt(Damage * BaseDefenseMultiplier) + " HP by " + DamageType + "."); + AddBattleLogMessage("Player was damaged for " + FString::FromInt(Damage * EnemyBaseDamageMultiplier) + " HP by " + DamageType + "."); if (*EnemyHealth <= 0) { EndCombat(); @@ -636,7 +656,7 @@ void ATurnBaseCombatV2::RunButtonOnClick() { if (FMath::RandRange(0.0f, 1.0f) >= EscapePercentage) { - GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Escape Failed")); + StatusTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 0.0f, 0.0f, 1.0f))); StatusTextBlock->SetText(FText::FromString("Escape Failed")); FOutputDeviceNull AR; const FString Command3 = FString::Printf(TEXT("PlayStatusAnimation")); @@ -722,10 +742,10 @@ void ATurnBaseCombatV2::UpdateBattleLog() void ATurnBaseCombatV2::UpdateResourceBars() const { - ProbertiumResourceBar->SetPercent(ProbertiumResource / 10.0f); - EisResourceBar->SetPercent(EisResource / 10.0f); - AzosResourceBar->SetPercent(AzosResource / 10.0f); - IroquoidResourceBar->SetPercent(IroquoidResource / 10.0f); + ProbertiumResourceBar->SetPercent(ProbertiumResource / 20.0f); + EisResourceBar->SetPercent(EisResource / 20.0f); + AzosResourceBar->SetPercent(AzosResource / 20.0f); + IroquoidResourceBar->SetPercent(IroquoidResource / 20.0f); ToggleButtonIfResourceAvailable(); } @@ -764,6 +784,7 @@ void ATurnBaseCombatV2::EnemyTurn() } else { + StatusTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 1.0f, 1.0f, 1.0f))); StatusTextBlock->SetText(FText::FromString("Missed")); FOutputDeviceNull AR; const FString Command3 = FString::Printf(TEXT("PlayStatusAnimation")); @@ -787,6 +808,6 @@ void ATurnBaseCombatV2::ToggleButtonIfResourceAvailable() const else AButton->SetIsEnabled(false); if (IroquoidResource >= 1) IButton->SetIsEnabled(true); else IButton->SetIsEnabled(false); - if (Cast(PlayerActor)->Inventory->GetItemAmount(0) >= 1) HealButton->SetIsEnabled(true); + if (Cast(PlayerActor)->Inventory->GetItemAmount(0) >= 1 && *PlayerHealth < 100.0f) HealButton->SetIsEnabled(true); else HealButton->SetIsEnabled(false); } diff --git a/Source/the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.h b/Source/the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.h index 17b588a..cd71c0e 100644 --- a/Source/the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.h +++ b/Source/the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.h @@ -28,7 +28,7 @@ public: UPROPERTY(BlueprintReadOnly) bool bIsInCombat = false; - UPROPERTY(EditDefaultsOnly) + UPROPERTY() float BaseDamageMultiplier = 1.0f; UPROPERTY(EditDefaultsOnly) float BaseDefenseMultiplier = 1.0f; @@ -40,6 +40,11 @@ public: float ChainDamageMultiplier = 0; UPROPERTY(EditAnywhere) float ChainDamageMultiplierIncrease = 0.2f; + + UPROPERTY(EditDefaultsOnly) + float EnemyBaseDamageMultiplier = 1.0f; + UPROPERTY(EditDefaultsOnly) + float DefaultEnemyBaseDamageMultiplier = 1.0f; UPROPERTY(EditDefaultsOnly) int DefaultActionPoints = 2; @@ -99,7 +104,8 @@ public: TMap SpecialCombos = { {"PA", "Thorns"}, - {"PI", "DamageOverTime"} + {"PI", "DamageOverTime"}, + {"AI", "DamageDown"} }; FString BattleLog; @@ -145,6 +151,10 @@ private: TSubclassOf ThornsStatusEffect; UPROPERTY() TSubclassOf DOTStatusEffect; + UPROPERTY() + TSubclassOf DamageDownStatusEffect; + UPROPERTY() + TSubclassOf DamageDownPlayerStatusEffect; UPROPERTY() TArray StatusEffects;