2022-11-17 03:02:58 +00:00
|
|
|
|
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "TurnBaseCombatV2.h"
|
|
|
|
|
#include "CoreMinimal.h"
|
2023-01-31 00:29:53 +00:00
|
|
|
|
#include "AIController.h"
|
2023-02-27 04:55:55 +00:00
|
|
|
|
#include "StatusSystem.h"
|
2022-11-17 03:02:58 +00:00
|
|
|
|
#include "Blueprint/UserWidget.h"
|
2023-01-31 00:29:53 +00:00
|
|
|
|
#include "BehaviorTree/BlackboardComponent.h"
|
2022-11-17 03:02:58 +00:00
|
|
|
|
#include "Components/TextBlock.h"
|
|
|
|
|
#include "Components/ProgressBar.h"
|
|
|
|
|
#include "Kismet/GameplayStatics.h"
|
2023-04-28 02:59:03 +00:00
|
|
|
|
#include "Kismet/KismetMathLibrary.h"
|
2023-04-27 04:13:41 +00:00
|
|
|
|
#include "Misc/OutputDeviceNull.h"
|
2023-01-31 01:21:49 +00:00
|
|
|
|
#include "the_twilight_abyss/PlayerTemp/TempCharacter.h"
|
2023-05-08 23:42:03 +00:00
|
|
|
|
#include "the_twilight_abyss/Quest/QuestSystem.h"
|
2022-11-17 03:02:58 +00:00
|
|
|
|
|
|
|
|
|
// Sets default values
|
|
|
|
|
ATurnBaseCombatV2::ATurnBaseCombatV2()
|
|
|
|
|
{
|
2023-05-12 13:38:58 +00:00
|
|
|
|
PrimaryActorTick.bCanEverTick = true;
|
2022-11-17 03:02:58 +00:00
|
|
|
|
if (HUDWidget == nullptr)
|
|
|
|
|
{
|
|
|
|
|
static ConstructorHelpers::FClassFinder<UUserWidget> HUDWidgetClass(TEXT("/Game/Blueprints/Combat_UI/Combat_UI"));
|
|
|
|
|
HUDWidget = HUDWidgetClass.Class;
|
2023-05-12 19:44:46 +00:00
|
|
|
|
|
2023-02-27 04:55:55 +00:00
|
|
|
|
static ConstructorHelpers::FClassFinder<UStatusEffect> StatusEffectThornsClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_Thorns"));
|
|
|
|
|
ThornsStatusEffect = StatusEffectThornsClassFinder.Class;
|
2023-05-09 03:29:19 +00:00
|
|
|
|
static ConstructorHelpers::FClassFinder<UStatusEffect> StatusEffectDotClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_DamageOverTime"));
|
|
|
|
|
DOTStatusEffect = StatusEffectDotClassFinder.Class;
|
2023-05-12 19:44:46 +00:00
|
|
|
|
static ConstructorHelpers::FClassFinder<UStatusEffect> StatusEffectDamageDownClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_DamageDown"));
|
|
|
|
|
DamageDownStatusEffect = StatusEffectDamageDownClassFinder.Class;
|
|
|
|
|
static ConstructorHelpers::FClassFinder<UStatusEffect> StatusEffectDamageDownPlayerClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_DamageDownPlayer"));
|
|
|
|
|
DamageDownPlayerStatusEffect = StatusEffectDamageDownPlayerClassFinder.Class;
|
2023-04-21 03:16:46 +00:00
|
|
|
|
|
2023-03-14 04:17:29 +00:00
|
|
|
|
static ConstructorHelpers::FClassFinder<UUserWidget> DeathScreenWidgetClass(TEXT("/Game/Blueprints/Death_UI/Death_UI"));
|
|
|
|
|
DeathScreenWidgetSubclass = DeathScreenWidgetClass.Class;
|
2023-04-24 10:54:28 +00:00
|
|
|
|
|
|
|
|
|
static ConstructorHelpers::FClassFinder<UUserWidget> CombatTutorialWidgetClass(TEXT("/Game/Blueprints/Combat_UI/CombatTutorial"));
|
|
|
|
|
CombatTutorialWidget = CombatTutorialWidgetClass.Class;
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 03:29:19 +00:00
|
|
|
|
void ATurnBaseCombatV2::StartCombat(AActor* Enemy, const bool bWasShot)
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
2023-01-31 00:04:24 +00:00
|
|
|
|
if (Enemy == nullptr) return;
|
2023-04-26 04:28:02 +00:00
|
|
|
|
EnemyActor = Enemy;
|
2023-04-25 02:46:52 +00:00
|
|
|
|
if (bIsInCombat) return;
|
2023-04-26 02:52:22 +00:00
|
|
|
|
BookHUD->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
|
2023-04-27 03:24:54 +00:00
|
|
|
|
HUD->AddToViewport(-1);
|
2023-04-27 06:19:19 +00:00
|
|
|
|
BookStaticMeshComponent->SetVisibility(true);
|
2023-04-25 03:23:51 +00:00
|
|
|
|
EscapePercentage = CalculateEscapePercentage();
|
|
|
|
|
EscapePercentageTextBlock->SetText(FText::Join(FText::FromString(""), FText::FromString(FString::FromInt(EscapePercentage * 100)), FText::FromString("%")));
|
2023-04-24 17:01:51 +00:00
|
|
|
|
bIsInCombat = true;
|
2023-01-31 00:29:53 +00:00
|
|
|
|
UBlackboardComponent* EnemyBlackboard = Cast<AAIController>(Enemy->GetInstigatorController())->GetBlackboardComponent();
|
2023-05-08 23:42:03 +00:00
|
|
|
|
Cast<UQuestSystem>(PlayerActor->GetComponentByClass(UQuestSystem::StaticClass()))->QuestWidgetInstance->SetVisibility(ESlateVisibility::Hidden);
|
2023-05-09 04:40:31 +00:00
|
|
|
|
HealingJellyAmountTextBlock->SetText(FText::FromString(FString::FromInt(FMath::Clamp(Cast<ATempCharacter>(PlayerActor)->Inventory->GetItemAmount(0), 0, 99))));
|
|
|
|
|
|
2022-11-29 00:33:34 +00:00
|
|
|
|
//Disable Character Movement
|
2023-02-02 02:06:55 +00:00
|
|
|
|
APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
|
2023-04-25 02:46:52 +00:00
|
|
|
|
PlayerController->SetIgnoreMoveInput(true);
|
|
|
|
|
PlayerController->SetIgnoreLookInput(true);
|
|
|
|
|
PlayerController->SetInputMode(FInputModeGameAndUI());
|
2023-02-02 02:06:55 +00:00
|
|
|
|
PlayerController->bShowMouseCursor = true;
|
2023-02-27 04:07:19 +00:00
|
|
|
|
|
2023-04-26 04:28:02 +00:00
|
|
|
|
if (EnemyBlackboard->GetValueAsBool("IsInCombat")) return;
|
|
|
|
|
EnemyBlackboard->SetValueAsBool("IsInCombat", true);
|
2023-05-09 03:29:19 +00:00
|
|
|
|
const FProperty* HealthProperty = Enemy->GetClass()->FindPropertyByName(FName("Health"));
|
2023-04-26 04:28:02 +00:00
|
|
|
|
int32* EnemyHealthPtr = HealthProperty->ContainerPtrToValuePtr<int32>(Enemy);
|
|
|
|
|
EnemyHealth = EnemyHealthPtr;
|
2023-04-26 05:21:08 +00:00
|
|
|
|
|
2023-05-12 15:48:14 +00:00
|
|
|
|
FProperty* IsBossProperty = FindFieldChecked<FProperty>(EnemyActor->GetClass(), "IsBoss");
|
|
|
|
|
if (const FBoolProperty* IsBossBoolProperty = CastFieldChecked<FBoolProperty>(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<UCameraComponent>(PlayerActor->FindComponentByClass<UCameraComponent>())->GetComponentLocation(), EnemyActor->GetActorLocation());
|
|
|
|
|
LookAtRotation.Pitch = NewRotation.Pitch - PlayerActor->GetActorRotation().Pitch;
|
|
|
|
|
LookAtRotation.Pitch += 10; //Offset
|
|
|
|
|
PlayerController->SetControlRotation(LookAtRotation);
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-26 04:28:02 +00:00
|
|
|
|
if (IsValid(CombatTutorialWidgetInstance) && CombatTutorialWidgetInstance->IsInViewport()) return;
|
|
|
|
|
if (!HasSeenTutorial)
|
|
|
|
|
{
|
|
|
|
|
DisableButtons();
|
|
|
|
|
CombatTutorialWidgetInstance->AddToViewport();
|
2023-04-28 04:33:08 +00:00
|
|
|
|
FProperty* Property = FindFieldChecked<FProperty>(CombatTutorialWidgetInstance->GetClass(), "WasShot");
|
|
|
|
|
const FBoolProperty* WasShotProperty = CastFieldChecked<FBoolProperty>(Property);
|
|
|
|
|
WasShotProperty->SetPropertyValue_InContainer(CombatTutorialWidgetInstance, bWasShot);
|
2023-04-26 04:28:02 +00:00
|
|
|
|
HasSeenTutorial = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-26 05:21:08 +00:00
|
|
|
|
CombatCheck(bWasShot);
|
2023-03-06 04:28:13 +00:00
|
|
|
|
//DrawDebugPoint(GetWorld(), Enemy->GetActorLocation(), 10, FColor::Red, false, 10);
|
2023-04-26 04:28:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 03:29:19 +00:00
|
|
|
|
void ATurnBaseCombatV2::CombatCheck(const bool bWasShot)
|
2023-04-26 04:28:02 +00:00
|
|
|
|
{
|
|
|
|
|
const UBlackboardComponent* EnemyBlackboard = Cast<AAIController>(EnemyActor->GetInstigatorController())->GetBlackboardComponent();
|
2023-03-06 04:28:13 +00:00
|
|
|
|
|
2023-05-11 04:59:49 +00:00
|
|
|
|
ChainDamageMultiplier = 0;
|
2023-05-12 12:51:08 +00:00
|
|
|
|
BaseDamageMultiplier = DefaultBaseDamageMultiplier;
|
2023-05-12 19:44:46 +00:00
|
|
|
|
EnemyBaseDamageMultiplier = DefaultEnemyBaseDamageMultiplier;
|
2023-05-12 12:51:08 +00:00
|
|
|
|
if (bIsBuffed) BaseDamageMultiplier += 1.0f;
|
2023-04-27 06:22:40 +00:00
|
|
|
|
DamageMultiplierTextBlock->SetText(FText::FromString(""));
|
2023-04-26 05:21:08 +00:00
|
|
|
|
|
2023-05-09 03:29:19 +00:00
|
|
|
|
const FProperty* ReactionSpeedProperty = EnemyActor->GetClass()->FindPropertyByName(FName("ReactionSpeed"));
|
|
|
|
|
const float* EnemyReactionSpeedPtr = ReactionSpeedProperty->ContainerPtrToValuePtr<float>(EnemyActor);
|
2023-04-28 02:59:03 +00:00
|
|
|
|
|
2022-11-29 00:33:34 +00:00
|
|
|
|
CurrentComboString = "";
|
|
|
|
|
UpdateComboString(CurrentComboString);
|
|
|
|
|
RevertActionPoints();
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
UpdateResourceBars();
|
2023-04-27 06:22:40 +00:00
|
|
|
|
UpdateProgressBars();
|
2023-01-31 02:19:11 +00:00
|
|
|
|
ClearBattleLog();
|
2023-04-26 04:28:02 +00:00
|
|
|
|
EnableButtons();
|
2023-04-28 02:59:03 +00:00
|
|
|
|
|
2023-04-26 05:21:08 +00:00
|
|
|
|
if (EnemyBlackboard->GetValueAsBool("Sight") && !bWasShot)
|
2023-04-26 04:28:02 +00:00
|
|
|
|
{
|
|
|
|
|
//bEnemyHasExtraTurn = true;
|
|
|
|
|
SwitchTurn();
|
2023-05-09 12:29:52 +00:00
|
|
|
|
return;
|
2023-04-26 04:28:02 +00:00
|
|
|
|
}
|
2023-04-26 05:21:08 +00:00
|
|
|
|
else if (Cast<ATempCharacter>(PlayerActor)->ReactionSpeed > *EnemyReactionSpeedPtr && bWasShot)
|
2023-04-26 04:28:02 +00:00
|
|
|
|
{
|
2023-05-09 12:29:52 +00:00
|
|
|
|
TurnIndicatorTextBlock->SetText(FText::FromString("Player Turn\nExtra"));
|
2023-04-26 04:28:02 +00:00
|
|
|
|
bPlayerHasExtraTurn = true;
|
2023-05-09 12:29:52 +00:00
|
|
|
|
return;
|
2023-04-26 04:28:02 +00:00
|
|
|
|
}
|
2023-04-26 05:21:08 +00:00
|
|
|
|
TurnIndicatorTextBlock->SetText(FText::FromString("Player Turn"));
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::EndCombat()
|
|
|
|
|
{
|
2023-04-26 02:52:22 +00:00
|
|
|
|
BookHUD->SetVisibility(ESlateVisibility::Hidden);
|
2023-04-27 03:24:54 +00:00
|
|
|
|
HUD->RemoveFromParent();
|
2023-04-27 06:19:19 +00:00
|
|
|
|
BookStaticMeshComponent->SetVisibility(false);
|
2023-05-08 23:42:03 +00:00
|
|
|
|
Cast<UQuestSystem>(PlayerActor->GetComponentByClass(UQuestSystem::StaticClass()))->QuestWidgetInstance->SetVisibility(ESlateVisibility::HitTestInvisible);
|
2023-04-26 02:52:22 +00:00
|
|
|
|
Cast<ATempCharacter>(PlayerActor)->ResetWidgetPointer();
|
2023-04-25 03:23:51 +00:00
|
|
|
|
TurnIndicatorTextBlock->SetText(FText::FromString(""));
|
2023-03-06 04:56:05 +00:00
|
|
|
|
bEnemyHasExtraTurn = false;
|
|
|
|
|
bPlayerHasExtraTurn = false;
|
2023-04-24 17:01:51 +00:00
|
|
|
|
bIsInCombat = false;
|
2023-05-11 04:59:49 +00:00
|
|
|
|
BaseDamageMultiplier -= ChainDamageMultiplier;
|
|
|
|
|
PreviousComboString = "";
|
2023-02-27 04:55:55 +00:00
|
|
|
|
for (UStatusEffect* StatusEffect : StatusEffects)
|
|
|
|
|
{
|
|
|
|
|
StatusEffect->OnExpiry(PlayerActor);
|
|
|
|
|
}
|
2023-03-06 04:28:13 +00:00
|
|
|
|
|
2023-01-31 00:04:24 +00:00
|
|
|
|
HUD->RemoveFromParent();
|
2022-11-21 22:34:33 +00:00
|
|
|
|
APawn* PlayerPawn = Cast<APawn>(GetWorld()->GetFirstPlayerController()->GetPawn());
|
|
|
|
|
PlayerPawn->bUseControllerRotationYaw = true;
|
|
|
|
|
PlayerPawn->bUseControllerRotationPitch = true;
|
2022-11-29 00:33:34 +00:00
|
|
|
|
//Enable Character Movement
|
2023-02-02 02:06:55 +00:00
|
|
|
|
//Set to Game Mode Only
|
|
|
|
|
APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
|
2023-04-25 02:46:52 +00:00
|
|
|
|
PlayerController->SetIgnoreMoveInput(false);
|
|
|
|
|
PlayerController->SetIgnoreLookInput(false);
|
2023-02-02 02:06:55 +00:00
|
|
|
|
PlayerController->SetInputMode(FInputModeGameOnly());
|
|
|
|
|
PlayerController->bShowMouseCursor = false;
|
2023-05-09 03:29:19 +00:00
|
|
|
|
|
|
|
|
|
if (IsValid(EnemyActor))
|
|
|
|
|
{
|
|
|
|
|
FProperty* IsBossProperty = FindFieldChecked<FProperty>(EnemyActor->GetClass(), "IsBoss");
|
|
|
|
|
const FBoolProperty* IsBossBoolProperty = CastFieldChecked<FBoolProperty>(IsBossProperty);
|
|
|
|
|
if (IsBossBoolProperty->GetPropertyValue_InContainer(EnemyActor))
|
|
|
|
|
{
|
|
|
|
|
FOutputDeviceNull AR;
|
|
|
|
|
const FString Command = FString::Printf(TEXT("TriggerCombatAnimation false"));
|
|
|
|
|
EnemyActor->CallFunctionByNameWithArguments(*Command, AR, nullptr, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::BeginPlay()
|
|
|
|
|
{
|
|
|
|
|
Super::BeginPlay();
|
|
|
|
|
|
|
|
|
|
TArray<AActor*> AllCharacterActorsInScene;
|
2022-11-21 22:34:33 +00:00
|
|
|
|
|
|
|
|
|
UGameplayStatics::GetAllActorsOfClassWithTag(GetWorld(), AActor::StaticClass(), FName("Player"), AllCharacterActorsInScene);
|
|
|
|
|
for (AActor* Actor : AllCharacterActorsInScene)
|
|
|
|
|
{
|
|
|
|
|
PlayerActor = Cast<AActor>(Actor);
|
|
|
|
|
}
|
2023-01-31 01:21:49 +00:00
|
|
|
|
PlayerHealth = &Cast<ATempCharacter>(PlayerActor)->Health;
|
2022-11-17 03:02:58 +00:00
|
|
|
|
|
2023-04-27 05:59:52 +00:00
|
|
|
|
TArray<AActor*> AllActorsInScene;
|
|
|
|
|
UGameplayStatics::GetAllActorsOfClass(GetWorld(), APostProcessVolume::StaticClass(), AllActorsInScene);
|
|
|
|
|
if (ensureMsgf(AllActorsInScene.Num() > 0, TEXT("No Post Processing Volume in scene")))
|
|
|
|
|
{
|
|
|
|
|
PostProcessVolume = Cast<APostProcessVolume>(AllActorsInScene[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsValid(RedVignetteMaterialInstance))
|
|
|
|
|
{
|
|
|
|
|
FWeightedBlendable WeightedBlendable;
|
|
|
|
|
WeightedBlendable.Object = RedVignetteMaterialInstance;
|
|
|
|
|
WeightedBlendable.Weight = 1.0f;
|
2023-04-27 16:40:34 +00:00
|
|
|
|
if (IsValid(PostProcessVolume)) PostProcessVolume->Settings.WeightedBlendables.Array.Add(WeightedBlendable);
|
2023-04-27 05:59:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-27 06:19:19 +00:00
|
|
|
|
TArray<UStaticMeshComponent*> StaticMeshComponents;
|
|
|
|
|
PlayerActor->GetComponents<UStaticMeshComponent>(StaticMeshComponents);
|
|
|
|
|
BookStaticMeshComponent = StaticMeshComponents[1];
|
|
|
|
|
BookStaticMeshComponent->SetVisibility(false);
|
|
|
|
|
|
2023-04-26 04:28:02 +00:00
|
|
|
|
CombatTutorialWidgetInstance = CreateWidget<UUserWidget>(GetWorld(), CombatTutorialWidget);
|
2022-11-17 03:02:58 +00:00
|
|
|
|
HUD = CreateWidget<UUserWidget>(GetWorld(), HUDWidget);
|
2023-04-21 02:44:01 +00:00
|
|
|
|
TArray<AActor*> PlayerChildActors;
|
|
|
|
|
PlayerActor->GetAllChildActors(PlayerChildActors, false);
|
|
|
|
|
PlayerWidget = Cast<UWidgetComponent>(PlayerChildActors[0]->GetComponentByClass(UWidgetComponent::StaticClass()));
|
|
|
|
|
PlayerWidget->InitWidget();
|
|
|
|
|
BookHUD = PlayerWidget->GetWidget();
|
2022-11-17 03:02:58 +00:00
|
|
|
|
|
2023-04-25 03:23:51 +00:00
|
|
|
|
TurnIndicatorTextBlock = Cast<UTextBlock>(BookHUD->GetWidgetFromName("TurnIndicator"));
|
2023-04-21 03:16:46 +00:00
|
|
|
|
CurrentComboTextBlock = Cast<UTextBlock>(BookHUD->GetWidgetFromName("CurrentCombo"));
|
|
|
|
|
CurrentComboTextBlock1 = Cast<UTextBlock>(BookHUD->GetWidgetFromName("CurrentCombo_1"));
|
|
|
|
|
CurrentComboTextBlock2 = Cast<UTextBlock>(BookHUD->GetWidgetFromName("CurrentCombo_2"));
|
2022-11-17 03:02:58 +00:00
|
|
|
|
BattleLogTextBlock = Cast<UTextBlock>(HUD->GetWidgetFromName("BattleLog"));
|
2023-04-25 03:23:51 +00:00
|
|
|
|
EscapePercentageTextBlock = Cast<UTextBlock>(BookHUD->GetWidgetFromName("EscapePercentage_Text"));
|
2023-04-26 02:52:22 +00:00
|
|
|
|
DamageMultiplierTextBlock = Cast<UTextBlock>(BookHUD->GetWidgetFromName("DamageMultiplier_Text"));
|
2023-05-09 04:40:31 +00:00
|
|
|
|
HealingJellyAmountTextBlock = Cast<UTextBlock>(BookHUD->GetWidgetFromName("HealingAmount_Text"));
|
2023-05-11 03:00:03 +00:00
|
|
|
|
DamageAmountEnemyTextBlock = Cast<UTextBlock>(HUD->GetWidgetFromName("DamageAmountEnemy_Text"));
|
|
|
|
|
DamageAmountPlayerTextBlock = Cast<UTextBlock>(BookHUD->GetWidgetFromName("DamageAmountPlayer_Text"));
|
|
|
|
|
StatusTextBlock = Cast<UTextBlock>(HUD->GetWidgetFromName("Status_Text"));
|
2023-04-21 02:44:01 +00:00
|
|
|
|
PlayerHealthBar = Cast<UProgressBar>(BookHUD->GetWidgetFromName("PlayerHealthBar"));
|
2022-11-17 03:02:58 +00:00
|
|
|
|
EnemyHealthBar = Cast<UProgressBar>(HUD->GetWidgetFromName("EnemyHealthBar"));
|
2023-04-21 02:44:01 +00:00
|
|
|
|
ProbertiumResourceBar = Cast<UProgressBar>(BookHUD->GetWidgetFromName("ProbertiumResourceBar"));
|
|
|
|
|
EisResourceBar = Cast<UProgressBar>(BookHUD->GetWidgetFromName("EisResourceBar"));
|
|
|
|
|
AzosResourceBar = Cast<UProgressBar>(BookHUD->GetWidgetFromName("AzosResourceBar"));
|
|
|
|
|
IroquoidResourceBar = Cast<UProgressBar>(BookHUD->GetWidgetFromName("IroquoidResourceBar"));
|
2023-04-25 02:46:52 +00:00
|
|
|
|
CastButton = Cast<UButton>(BookHUD->GetWidgetFromName("Cast_Button"));
|
|
|
|
|
PButton = Cast<UButton>(BookHUD->GetWidgetFromName("Probertium_Button"));
|
|
|
|
|
EButton = Cast<UButton>(BookHUD->GetWidgetFromName("Eis_Button"));
|
|
|
|
|
AButton = Cast<UButton>(BookHUD->GetWidgetFromName("Azos_Button"));
|
|
|
|
|
IButton = Cast<UButton>(BookHUD->GetWidgetFromName("Iroquoid_Button"));
|
|
|
|
|
BackspaceButton = Cast<UButton>(BookHUD->GetWidgetFromName("Clear_Button"));
|
|
|
|
|
RunButton = Cast<UButton>(BookHUD->GetWidgetFromName("Escape_Button"));
|
2023-05-09 04:40:31 +00:00
|
|
|
|
HealButton = Cast<UButton>(BookHUD->GetWidgetFromName("Heal_Button"));
|
2022-11-17 03:02:58 +00:00
|
|
|
|
CastButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::CastButtonOnClick);
|
2023-02-27 04:07:19 +00:00
|
|
|
|
PButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::PButtonOnClick);
|
|
|
|
|
EButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::EButtonOnClick);
|
|
|
|
|
AButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::AButtonOnClick);
|
|
|
|
|
IButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::IButtonOnClick);
|
2022-11-17 03:02:58 +00:00
|
|
|
|
BackspaceButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::BackspaceButtonOnClick);
|
2023-01-31 01:39:42 +00:00
|
|
|
|
RunButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::RunButtonOnClick);
|
2023-05-09 04:40:31 +00:00
|
|
|
|
HealButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::HealButtonOnClick);
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-12 13:38:58 +00:00
|
|
|
|
void ATurnBaseCombatV2::Tick(const float DeltaTime)
|
|
|
|
|
{
|
|
|
|
|
Super::Tick(DeltaTime);
|
|
|
|
|
if (bIsInCombat)
|
|
|
|
|
{
|
|
|
|
|
APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
|
|
|
|
|
FProperty* IsBossProperty = FindFieldChecked<FProperty>(EnemyActor->GetClass(), "IsBoss");
|
2023-05-12 15:48:14 +00:00
|
|
|
|
if (const FBoolProperty* IsBossBoolProperty = CastFieldChecked<FBoolProperty>(IsBossProperty); !IsBossBoolProperty->GetPropertyValue_InContainer(EnemyActor))
|
2023-05-12 13:38:58 +00:00
|
|
|
|
{
|
|
|
|
|
FVector Direction = EnemyActor->GetActorLocation() - PlayerActor->GetActorLocation();
|
|
|
|
|
Direction.Normalize();
|
|
|
|
|
FRotator LookAtRotation = FRotationMatrix::MakeFromX(Direction).Rotator();
|
|
|
|
|
const FRotator NewRotation = UKismetMathLibrary::FindLookAtRotation(Cast<UCameraComponent>(PlayerActor->FindComponentByClass<UCameraComponent>())->GetComponentLocation(), Cast<USkeletalMeshComponent>(EnemyActor->FindComponentByClass<USkeletalMeshComponent>())->GetComponentLocation());
|
|
|
|
|
LookAtRotation.Pitch = NewRotation.Pitch - PlayerActor->GetActorRotation().Pitch;
|
2023-05-12 15:32:02 +00:00
|
|
|
|
PlayerController->SetControlRotation(LookAtRotation);
|
2023-05-12 13:38:58 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-17 03:02:58 +00:00
|
|
|
|
void ATurnBaseCombatV2::ExecuteCast(FString Combo)
|
|
|
|
|
{
|
|
|
|
|
if (!IsValidCombo(Combo))
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Invalid Combo"));
|
|
|
|
|
for (int i = 0; i < Combo.Len(); i++)
|
|
|
|
|
{
|
2023-02-27 04:07:19 +00:00
|
|
|
|
if (Combo[i] == 'P')
|
|
|
|
|
{
|
|
|
|
|
ProbertiumResource += 1;
|
|
|
|
|
}
|
|
|
|
|
else if (Combo[i] == 'E')
|
|
|
|
|
{
|
|
|
|
|
EisResource += 1;
|
|
|
|
|
}
|
|
|
|
|
else if (Combo[i] == 'A')
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
2023-02-27 04:07:19 +00:00
|
|
|
|
AzosResource += 1;
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
2023-02-27 04:07:19 +00:00
|
|
|
|
else if (Combo[i] == 'I')
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
2023-02-27 04:07:19 +00:00
|
|
|
|
IroquoidResource += 1;
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
CurrentComboString = "";
|
|
|
|
|
UpdateComboString(CurrentComboString);
|
|
|
|
|
RevertActionPoints();
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
UpdateResourceBars();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-02-27 04:55:55 +00:00
|
|
|
|
if (IsSpecialCombo(Combo))
|
|
|
|
|
{
|
2023-05-12 19:44:46 +00:00
|
|
|
|
FOutputDeviceNull AR;
|
2023-02-27 04:55:55 +00:00
|
|
|
|
UStatusSystem* StatusSystem = Cast<UStatusSystem>(PlayerActor->GetComponentByClass(UStatusSystem::StaticClass()));
|
2023-04-25 03:38:06 +00:00
|
|
|
|
if (Combo == "PA")
|
2023-02-27 04:55:55 +00:00
|
|
|
|
{
|
|
|
|
|
UStatusEffect* TempThornsStatusEffect = NewObject<UStatusEffect>(PlayerActor, ThornsStatusEffect);
|
|
|
|
|
StatusSystem->AddStatusEffect(TempThornsStatusEffect, 1, false);
|
|
|
|
|
StatusEffects.Add(TempThornsStatusEffect);
|
2023-03-02 03:25:00 +00:00
|
|
|
|
AddBattleLogMessage("Player Casted Thorns");
|
2023-05-12 20:45:51 +00:00
|
|
|
|
StatusTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 1.0f, 1.0f, 1.0f)));
|
2023-05-12 19:44:46 +00:00
|
|
|
|
StatusTextBlock->SetText(FText::FromString("Casted Thorns"));
|
|
|
|
|
const FString Command3 = FString::Printf(TEXT("PlayStatusAnimation"));
|
|
|
|
|
HUD->CallFunctionByNameWithArguments(*Command3, AR, nullptr, true);
|
2023-02-27 04:55:55 +00:00
|
|
|
|
}
|
2023-04-25 03:38:06 +00:00
|
|
|
|
else if (Combo == "PI")
|
2023-03-02 15:06:31 +00:00
|
|
|
|
{
|
|
|
|
|
UStatusEffect* TempDOTStatusEffect = NewObject<UStatusEffect>(PlayerActor, DOTStatusEffect);
|
|
|
|
|
StatusSystem->AddStatusEffect(TempDOTStatusEffect, 1, false);
|
|
|
|
|
StatusEffects.Add(TempDOTStatusEffect);
|
|
|
|
|
AddBattleLogMessage("Player Casted DOT");
|
2023-05-12 20:45:51 +00:00
|
|
|
|
StatusTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 1.0f, 1.0f, 1.0f)));
|
2023-05-12 19:44:46 +00:00
|
|
|
|
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<UStatusEffect>(PlayerActor, DamageDownStatusEffect);
|
|
|
|
|
StatusSystem->AddStatusEffect(TempDamageDownStatusEffect, 1);
|
|
|
|
|
StatusEffects.Add(TempDamageDownStatusEffect);
|
|
|
|
|
AddBattleLogMessage("Player Casted DamageDown");
|
2023-05-12 20:45:51 +00:00
|
|
|
|
StatusTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 1.0f, 1.0f, 1.0f)));
|
2023-05-12 19:44:46 +00:00
|
|
|
|
StatusTextBlock->SetText(FText::FromString("Enemy Damage Down"));
|
|
|
|
|
const FString Command3 = FString::Printf(TEXT("PlayStatusAnimation"));
|
|
|
|
|
HUD->CallFunctionByNameWithArguments(*Command3, AR, nullptr, true);
|
2023-03-02 15:06:31 +00:00
|
|
|
|
}
|
2023-02-27 04:55:55 +00:00
|
|
|
|
}
|
2022-11-17 03:02:58 +00:00
|
|
|
|
|
2023-04-26 01:10:01 +00:00
|
|
|
|
if (GunEffect)
|
2022-11-29 01:54:45 +00:00
|
|
|
|
{
|
|
|
|
|
const UStaticMeshComponent* GunComponent = Cast<UStaticMeshComponent>(PlayerActor->GetComponentsByTag(UPrimitiveComponent::StaticClass(), FName("Gun"))[0]);
|
2023-05-08 22:40:44 +00:00
|
|
|
|
const FVector GunLocationOffset = GunComponent->GetSocketTransform("Muzzle").GetLocation();
|
2022-11-29 01:54:45 +00:00
|
|
|
|
UNiagaraFunctionLibrary::SpawnSystemAtLocation(GetWorld(), GunEffect, GunLocationOffset, PlayerActor->GetActorRotation());
|
2023-04-27 04:13:41 +00:00
|
|
|
|
FOutputDeviceNull AR;
|
|
|
|
|
const FString Command = FString::Printf(TEXT("PlayCameraShakeShoot"));
|
|
|
|
|
PlayerActor->CallFunctionByNameWithArguments(*Command, AR, nullptr, true);
|
2022-11-29 01:54:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-26 02:52:22 +00:00
|
|
|
|
if (ChainDamageMultiplier == 1) BaseDamageMultiplier = 1;
|
|
|
|
|
if ((CurrentComboString == "II" || CurrentComboString == "PP" || CurrentComboString == "EE" || CurrentComboString == "AA") &&
|
|
|
|
|
(PreviousComboString == "II" || PreviousComboString == "PP" || PreviousComboString == "EE" || PreviousComboString == "AA"))
|
|
|
|
|
{
|
2023-04-27 05:59:52 +00:00
|
|
|
|
ChainDamageMultiplier += ChainDamageMultiplierIncrease;
|
2023-05-11 04:59:49 +00:00
|
|
|
|
DamageMultiplierTextBlock->SetText(FText::Join(FText::FromString(""), FText::FromString("x"), FText::FromString(FString::SanitizeFloat(ChainDamageMultiplier + BaseDamageMultiplier))));
|
2023-04-26 02:52:22 +00:00
|
|
|
|
}
|
|
|
|
|
else if (CurrentComboString == "EI")
|
|
|
|
|
{
|
2023-05-11 04:59:49 +00:00
|
|
|
|
BaseDamageMultiplier += ChainDamageMultiplier;
|
2023-04-26 02:52:22 +00:00
|
|
|
|
DamageMultiplierTextBlock->SetText(FText::FromString(""));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PreviousComboString = CurrentComboString;
|
|
|
|
|
|
2022-11-17 03:02:58 +00:00
|
|
|
|
CurrentComboString = "";
|
|
|
|
|
UpdateComboString(CurrentComboString);
|
|
|
|
|
RevertActionPoints();
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
|
2023-04-26 02:52:22 +00:00
|
|
|
|
//Damage Calculation
|
|
|
|
|
switch (bIsPlayerTurn)
|
|
|
|
|
{
|
|
|
|
|
case true:
|
|
|
|
|
// Player Turn
|
|
|
|
|
DamageEnemy(*ValidCombos.Find(Combo));
|
|
|
|
|
OnPlayerTurn.Broadcast(PlayerActor, EnemyActor);
|
|
|
|
|
break;
|
|
|
|
|
case false:
|
|
|
|
|
// Enemy Turn
|
|
|
|
|
DamagePlayer(*ValidCombos.Find(Combo));
|
|
|
|
|
OnEnemyTurn.Broadcast(EnemyActor, PlayerActor);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-06 04:56:05 +00:00
|
|
|
|
if (!bPlayerHasExtraTurn)
|
|
|
|
|
{
|
|
|
|
|
SwitchTurn();
|
|
|
|
|
}
|
2023-05-09 12:29:52 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TurnIndicatorTextBlock->SetText(FText::FromString("Player Turn"));
|
|
|
|
|
bPlayerHasExtraTurn = false;
|
|
|
|
|
}
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::UseActionPoint()
|
|
|
|
|
{
|
|
|
|
|
ActiveActionPoints += 1;
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::ReuseActionPoint()
|
|
|
|
|
{
|
|
|
|
|
ActiveActionPoints -= 1;
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::RevertActionPoints()
|
|
|
|
|
{
|
|
|
|
|
ActiveActionPoints = 0;
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 03:29:19 +00:00
|
|
|
|
void ATurnBaseCombatV2::DamagePlayer(int Damage, const FString& DamageType)
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
2023-05-11 03:00:03 +00:00
|
|
|
|
FOutputDeviceNull AR;
|
2023-05-12 19:44:46 +00:00
|
|
|
|
*PlayerHealth -= FMath::Clamp(Damage * EnemyBaseDamageMultiplier, 0, 100);
|
|
|
|
|
DamageAmountPlayerTextBlock->SetText(FText::FromString("-" + FString::FromInt(Damage * EnemyBaseDamageMultiplier)));
|
2023-05-11 03:00:03 +00:00
|
|
|
|
const FString Command3 = FString::Printf(TEXT("PlayDamagePlayerTextAnimation"));
|
|
|
|
|
BookHUD->CallFunctionByNameWithArguments(*Command3, AR, nullptr, true);
|
2022-11-17 03:02:58 +00:00
|
|
|
|
UpdateProgressBars();
|
2023-05-12 19:44:46 +00:00
|
|
|
|
AddBattleLogMessage("Player was damaged for " + FString::FromInt(Damage * EnemyBaseDamageMultiplier) + " HP by " + DamageType + ".");
|
2023-04-26 04:28:02 +00:00
|
|
|
|
if (*EnemyHealth <= 0)
|
|
|
|
|
{
|
|
|
|
|
EndCombat();
|
2023-05-09 03:29:19 +00:00
|
|
|
|
FProperty* IsBossProperty = FindFieldChecked<FProperty>(EnemyActor->GetClass(), "IsBoss");
|
|
|
|
|
const FBoolProperty* IsBossBoolProperty = CastFieldChecked<FBoolProperty>(IsBossProperty);
|
|
|
|
|
if (IsBossBoolProperty->GetPropertyValue_InContainer(EnemyActor))
|
|
|
|
|
{
|
|
|
|
|
const FString Command = FString::Printf(TEXT("TriggerDeathAnimation"));
|
|
|
|
|
EnemyActor->CallFunctionByNameWithArguments(*Command, AR, nullptr, true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-05-13 00:17:59 +00:00
|
|
|
|
Cast<ATempCharacter>(PlayerActor)->GoldBalance += 100;
|
2023-04-26 04:28:02 +00:00
|
|
|
|
EnemyActor->Destroy();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (*PlayerHealth <= 0)
|
|
|
|
|
{
|
|
|
|
|
//EndCombat();
|
|
|
|
|
DeathScreenWidget = CreateWidget<UUserWidget>(GetWorld(), DeathScreenWidgetSubclass);
|
|
|
|
|
DeathScreenWidget->AddToViewport();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-04-27 05:59:52 +00:00
|
|
|
|
const FString Command = FString::Printf(TEXT("PlayCameraShakeShoot"));
|
|
|
|
|
PlayerActor->CallFunctionByNameWithArguments(*Command, AR, nullptr, true);
|
|
|
|
|
RedVignetteMaterialInstance->SetScalarParameterValue(FName("BlendWeight"), 1.0f);
|
2023-04-28 02:40:41 +00:00
|
|
|
|
|
|
|
|
|
const FString Command2 = FString::Printf(TEXT("TriggerAttackAnimation"));
|
|
|
|
|
EnemyActor->CallFunctionByNameWithArguments(*Command2, AR, nullptr, true);
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 03:29:19 +00:00
|
|
|
|
void ATurnBaseCombatV2::DamageEnemy(int Damage, const FString& DamageType)
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
2023-04-26 02:52:22 +00:00
|
|
|
|
*EnemyHealth -= FMath::Clamp(Damage * BaseDamageMultiplier, 0, 100);
|
2022-11-17 03:02:58 +00:00
|
|
|
|
UpdateProgressBars();
|
2023-05-11 03:00:03 +00:00
|
|
|
|
DamageAmountEnemyTextBlock->SetText(FText::FromString("-" + FString::FromInt(Damage * BaseDamageMultiplier)));
|
|
|
|
|
FOutputDeviceNull AR;
|
|
|
|
|
const FString Command = FString::Printf(TEXT("PlayDamageEnemyTextAnimation"));
|
|
|
|
|
HUD->CallFunctionByNameWithArguments(*Command, AR, nullptr, true);
|
2023-04-26 02:52:22 +00:00
|
|
|
|
AddBattleLogMessage("Enemy was damaged for " + FString::FromInt(Damage * BaseDamageMultiplier) + " HP by " + DamageType + ".");
|
2023-05-11 04:59:49 +00:00
|
|
|
|
if (DamageMultiplierTextBlock->GetText().ToString() == "")
|
|
|
|
|
{
|
2023-05-12 12:51:08 +00:00
|
|
|
|
BaseDamageMultiplier = DefaultBaseDamageMultiplier;
|
|
|
|
|
if (bIsBuffed) BaseDamageMultiplier += 1.0f;
|
2023-05-11 04:59:49 +00:00
|
|
|
|
ChainDamageMultiplier = 0;
|
|
|
|
|
}
|
2023-05-09 03:29:19 +00:00
|
|
|
|
|
|
|
|
|
FProperty* IsBossProperty = FindFieldChecked<FProperty>(EnemyActor->GetClass(), "IsBoss");
|
|
|
|
|
const FBoolProperty* IsBossBoolProperty = CastFieldChecked<FBoolProperty>(IsBossProperty);
|
|
|
|
|
if (IsBossBoolProperty->GetPropertyValue_InContainer(EnemyActor))
|
|
|
|
|
{
|
2023-05-11 03:00:03 +00:00
|
|
|
|
const FString Command2 = FString::Printf(TEXT("TriggerDamageAnimation"));
|
|
|
|
|
EnemyActor->CallFunctionByNameWithArguments(*Command2, AR, nullptr, true);
|
2023-05-09 03:29:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-26 04:28:02 +00:00
|
|
|
|
//Ends Combat if either the player or enemy is dead
|
|
|
|
|
if (*EnemyHealth <= 0)
|
|
|
|
|
{
|
|
|
|
|
EndCombat();
|
2023-05-09 03:29:19 +00:00
|
|
|
|
if (IsBossBoolProperty->GetPropertyValue_InContainer(EnemyActor))
|
|
|
|
|
{
|
2023-05-11 03:00:03 +00:00
|
|
|
|
const FString Command2 = FString::Printf(TEXT("TriggerDeathAnimation"));
|
|
|
|
|
EnemyActor->CallFunctionByNameWithArguments(*Command2, AR, nullptr, true);
|
2023-05-09 03:29:19 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2023-05-13 00:17:59 +00:00
|
|
|
|
Cast<ATempCharacter>(PlayerActor)->GoldBalance += 100;
|
2023-04-26 04:28:02 +00:00
|
|
|
|
EnemyActor->Destroy();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (*PlayerHealth <= 0)
|
|
|
|
|
{
|
|
|
|
|
//EndCombat();
|
|
|
|
|
DeathScreenWidget = CreateWidget<UUserWidget>(GetWorld(), DeathScreenWidgetSubclass);
|
|
|
|
|
DeathScreenWidget->AddToViewport();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::UpdateProgressBars() const
|
|
|
|
|
{
|
2023-05-09 03:29:19 +00:00
|
|
|
|
const FProperty* MaxHealthProperty = EnemyActor->GetClass()->FindPropertyByName(FName("MaxHealth"));
|
|
|
|
|
const int32* EnemyMaxHealthPtr = MaxHealthProperty->ContainerPtrToValuePtr<int32>(EnemyActor);
|
2023-04-28 03:47:24 +00:00
|
|
|
|
EnemyHealthBar->SetPercent(static_cast<float>(*EnemyHealth) / static_cast<float>(*EnemyMaxHealthPtr));
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-25 03:23:51 +00:00
|
|
|
|
float ATurnBaseCombatV2::CalculateEscapePercentage() const
|
|
|
|
|
{
|
|
|
|
|
return FMath::RandRange(0.1f, 0.9f);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 03:29:19 +00:00
|
|
|
|
bool ATurnBaseCombatV2::IsValidCombo(const FString& Combo) const
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
|
|
|
|
return ValidCombos.Contains(Combo);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 03:29:19 +00:00
|
|
|
|
bool ATurnBaseCombatV2::IsSpecialCombo(const FString& Combo) const
|
2023-02-27 04:55:55 +00:00
|
|
|
|
{
|
|
|
|
|
return SpecialCombos.Contains(Combo);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-17 03:02:58 +00:00
|
|
|
|
void ATurnBaseCombatV2::SwitchTurn()
|
|
|
|
|
{
|
|
|
|
|
//TurnIndicatorTextBlock->SetText(FText::FromString(bIsPlayerTurn ? "Enemy Turn" : "Player Turn"));
|
|
|
|
|
//bIsPlayerTurn = !bIsPlayerTurn;
|
|
|
|
|
TurnIndicatorTextBlock->SetText(FText::FromString("Enemy Turn"));
|
2023-05-09 01:55:31 +00:00
|
|
|
|
DisableButtons();
|
2023-03-06 04:28:13 +00:00
|
|
|
|
|
2022-11-17 03:02:58 +00:00
|
|
|
|
FTimerHandle UnusedHandle;
|
|
|
|
|
GetWorldTimerManager().SetTimer(UnusedHandle, this, &ATurnBaseCombatV2::EnemyTurn, 2.0f, false);
|
2023-01-31 00:04:24 +00:00
|
|
|
|
|
2022-11-17 03:02:58 +00:00
|
|
|
|
//activeActor = bIsPlayerTurn ? enemyActor : playerActor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::CastButtonOnClick()
|
|
|
|
|
{
|
|
|
|
|
ExecuteCast(CurrentComboString);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-27 04:07:19 +00:00
|
|
|
|
void ATurnBaseCombatV2::PButtonOnClick()
|
|
|
|
|
{
|
|
|
|
|
if (ActiveActionPoints >= DefaultActionPoints)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Action Points"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (ProbertiumResource <= 0)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Probertium"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
UseActionPoint();
|
|
|
|
|
CurrentComboString.AppendChar('P');
|
|
|
|
|
UpdateComboString(CurrentComboString);
|
|
|
|
|
ProbertiumResource -= 1;
|
|
|
|
|
UpdateResourceBars();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::EButtonOnClick()
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
|
|
|
|
if (ActiveActionPoints >= DefaultActionPoints)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Action Points"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-02-27 04:07:19 +00:00
|
|
|
|
if (EisResource <= 0)
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
2023-02-27 04:07:19 +00:00
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Eis"));
|
2022-11-17 03:02:58 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
UseActionPoint();
|
2023-02-27 04:07:19 +00:00
|
|
|
|
CurrentComboString.AppendChar('E');
|
2022-11-17 03:02:58 +00:00
|
|
|
|
UpdateComboString(CurrentComboString);
|
2023-02-27 04:07:19 +00:00
|
|
|
|
EisResource -= 1;
|
2022-11-17 03:02:58 +00:00
|
|
|
|
UpdateResourceBars();
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-27 04:07:19 +00:00
|
|
|
|
void ATurnBaseCombatV2::AButtonOnClick()
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
|
|
|
|
if (ActiveActionPoints >= DefaultActionPoints)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Action Points"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-02-27 04:07:19 +00:00
|
|
|
|
if (AzosResource <= 0)
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
2023-02-27 04:07:19 +00:00
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Azos"));
|
2022-11-17 03:02:58 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
UseActionPoint();
|
2023-02-27 04:07:19 +00:00
|
|
|
|
CurrentComboString.AppendChar('A');
|
2022-11-17 03:02:58 +00:00
|
|
|
|
UpdateComboString(CurrentComboString);
|
2023-02-27 04:07:19 +00:00
|
|
|
|
AzosResource -= 1;
|
|
|
|
|
UpdateResourceBars();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::IButtonOnClick()
|
|
|
|
|
{
|
|
|
|
|
if (ActiveActionPoints >= DefaultActionPoints)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Action Points"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (IroquoidResource <= 0)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Iroquoid"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
UseActionPoint();
|
|
|
|
|
CurrentComboString.AppendChar('I');
|
|
|
|
|
UpdateComboString(CurrentComboString);
|
|
|
|
|
IroquoidResource -= 1;
|
2022-11-17 03:02:58 +00:00
|
|
|
|
UpdateResourceBars();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::BackspaceButtonOnClick()
|
|
|
|
|
{
|
|
|
|
|
if (CurrentComboString.Len() <= 0)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Blank Combo"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-04-25 02:46:52 +00:00
|
|
|
|
for (int i = 0; i < CurrentComboString.Len(); i++)
|
2023-02-27 04:07:19 +00:00
|
|
|
|
{
|
2023-04-25 02:46:52 +00:00
|
|
|
|
if (CurrentComboString[i] == 'P')
|
|
|
|
|
{
|
|
|
|
|
ProbertiumResource += 1;
|
|
|
|
|
}
|
|
|
|
|
else if (CurrentComboString[i] == 'E')
|
|
|
|
|
{
|
|
|
|
|
EisResource += 1;
|
|
|
|
|
}
|
|
|
|
|
else if (CurrentComboString[i] == 'A')
|
|
|
|
|
{
|
|
|
|
|
AzosResource += 1;
|
|
|
|
|
}
|
|
|
|
|
else if (CurrentComboString[i] == 'I')
|
|
|
|
|
{
|
|
|
|
|
IroquoidResource += 1;
|
|
|
|
|
}
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
2023-04-25 02:46:52 +00:00
|
|
|
|
CurrentComboString = "";
|
2022-11-17 03:02:58 +00:00
|
|
|
|
UpdateComboString(CurrentComboString);
|
2023-04-25 02:46:52 +00:00
|
|
|
|
RevertActionPoints();
|
|
|
|
|
UpdateActionPoints();
|
2022-11-17 03:02:58 +00:00
|
|
|
|
UpdateResourceBars();
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-31 01:39:42 +00:00
|
|
|
|
void ATurnBaseCombatV2::RunButtonOnClick()
|
|
|
|
|
{
|
2023-04-25 03:23:51 +00:00
|
|
|
|
if (FMath::RandRange(0.0f, 1.0f) >= EscapePercentage)
|
|
|
|
|
{
|
2023-05-12 20:45:51 +00:00
|
|
|
|
StatusTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 0.0f, 0.0f, 1.0f)));
|
2023-05-11 03:00:03 +00:00
|
|
|
|
StatusTextBlock->SetText(FText::FromString("Escape Failed"));
|
|
|
|
|
FOutputDeviceNull AR;
|
|
|
|
|
const FString Command3 = FString::Printf(TEXT("PlayStatusAnimation"));
|
|
|
|
|
HUD->CallFunctionByNameWithArguments(*Command3, AR, nullptr, true);
|
2023-04-25 03:23:51 +00:00
|
|
|
|
EscapePercentage = CalculateEscapePercentage();
|
|
|
|
|
EscapePercentageTextBlock->SetText(FText::Join(FText::FromString(""), FText::FromString(FString::FromInt(EscapePercentage * 100)), FText::FromString("%")));
|
|
|
|
|
SwitchTurn();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-04-26 04:28:02 +00:00
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Escape Successful"));
|
2023-01-31 01:39:42 +00:00
|
|
|
|
UBlackboardComponent* EnemyBlackboard = Cast<AAIController>(EnemyActor->GetInstigatorController())->GetBlackboardComponent();
|
2023-04-25 03:23:51 +00:00
|
|
|
|
EscapePercentageTextBlock->SetText(FText::Join(FText::FromString(""), FText::FromString("--"), FText::FromString("%")));
|
2023-01-31 01:39:42 +00:00
|
|
|
|
EnemyBlackboard->SetValueAsBool("IsInCombat", false);
|
2023-04-21 14:32:41 +00:00
|
|
|
|
EnemyBlackboard->SetValueAsBool("WasInCombat", true);
|
2023-01-31 01:39:42 +00:00
|
|
|
|
EndCombat();
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 04:40:31 +00:00
|
|
|
|
void ATurnBaseCombatV2::HealButtonOnClick()
|
|
|
|
|
{
|
|
|
|
|
if (Cast<ATempCharacter>(PlayerActor)->Inventory->GetItemAmount(0) >= 1)
|
|
|
|
|
{
|
|
|
|
|
Cast<ATempCharacter>(PlayerActor)->Inventory->GetItemByID(0)->Use(Cast<ATempCharacter>(PlayerActor));
|
|
|
|
|
HealingJellyAmountTextBlock->SetText(FText::FromString(FString::FromInt(FMath::Clamp(Cast<ATempCharacter>(PlayerActor)->Inventory->GetItemAmount(0), 0, 99))));
|
|
|
|
|
UpdateResourceBars();
|
|
|
|
|
SwitchTurn();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 03:29:19 +00:00
|
|
|
|
void ATurnBaseCombatV2::UpdateComboString(const FString& NewCombo) const
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
2023-04-21 03:26:09 +00:00
|
|
|
|
CurrentComboTextBlock->SetText(FText::FromString("?"));
|
|
|
|
|
CurrentComboTextBlock1->SetText(FText::FromString("?"));
|
|
|
|
|
CurrentComboTextBlock2->SetText(FText::FromString("?"));
|
2023-04-21 03:16:46 +00:00
|
|
|
|
|
2023-05-09 01:55:31 +00:00
|
|
|
|
if (NewCombo.Len() > 0) BackspaceButton->SetVisibility(ESlateVisibility::Visible);
|
|
|
|
|
else BackspaceButton->SetVisibility(ESlateVisibility::Hidden);
|
|
|
|
|
|
|
|
|
|
if (IsValidCombo(NewCombo))
|
|
|
|
|
{
|
|
|
|
|
CurrentComboTextBlock->SetText(FText::FromString(NewCombo));
|
|
|
|
|
CastButton->SetVisibility(ESlateVisibility::Visible);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CastButton->SetVisibility(ESlateVisibility::Hidden);
|
|
|
|
|
}
|
2023-04-21 03:16:46 +00:00
|
|
|
|
if (NewCombo.Len() == 1)
|
|
|
|
|
{
|
|
|
|
|
CurrentComboTextBlock1->SetText(FText::FromString(NewCombo));
|
|
|
|
|
}
|
|
|
|
|
else if (NewCombo.Len() == 2)
|
|
|
|
|
{
|
|
|
|
|
CurrentComboTextBlock1->SetText(FText::FromString(NewCombo.LeftChop(1)));
|
|
|
|
|
CurrentComboTextBlock2->SetText(FText::FromString(NewCombo.RightChop(1)));
|
|
|
|
|
}
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 03:29:19 +00:00
|
|
|
|
void ATurnBaseCombatV2::UpdateActionPoints()
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
2023-04-21 13:35:36 +00:00
|
|
|
|
return;
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 03:29:19 +00:00
|
|
|
|
void ATurnBaseCombatV2::AddBattleLogMessage(const FString& Message)
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
|
|
|
|
BattleLog.Append(Message + "\n");
|
|
|
|
|
UpdateBattleLog();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::ClearBattleLog()
|
|
|
|
|
{
|
|
|
|
|
BattleLog = "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::UpdateBattleLog()
|
|
|
|
|
{
|
|
|
|
|
TArray<FString> TempArray;
|
|
|
|
|
if (const int32 LineCount = BattleLog.ParseIntoArray(TempArray, TEXT("\n"), true); LineCount > 10)
|
|
|
|
|
{
|
|
|
|
|
ClearBattleLog();
|
|
|
|
|
}
|
|
|
|
|
BattleLogTextBlock->SetText(FText::FromString(BattleLog));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::UpdateResourceBars() const
|
|
|
|
|
{
|
2023-05-12 15:51:06 +00:00
|
|
|
|
ProbertiumResourceBar->SetPercent(ProbertiumResource / 20.0f);
|
|
|
|
|
EisResourceBar->SetPercent(EisResource / 20.0f);
|
|
|
|
|
AzosResourceBar->SetPercent(AzosResource / 20.0f);
|
|
|
|
|
IroquoidResourceBar->SetPercent(IroquoidResource / 20.0f);
|
2023-05-09 01:55:31 +00:00
|
|
|
|
ToggleButtonIfResourceAvailable();
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-26 04:28:02 +00:00
|
|
|
|
void ATurnBaseCombatV2::DisableButtons() const
|
|
|
|
|
{
|
|
|
|
|
PButton->SetIsEnabled(false);
|
|
|
|
|
EButton->SetIsEnabled(false);
|
|
|
|
|
AButton->SetIsEnabled(false);
|
|
|
|
|
IButton->SetIsEnabled(false);
|
|
|
|
|
BackspaceButton->SetIsEnabled(false);
|
|
|
|
|
CastButton->SetIsEnabled(false);
|
|
|
|
|
RunButton->SetIsEnabled(false);
|
2023-05-09 04:40:31 +00:00
|
|
|
|
HealButton->SetIsEnabled(false);
|
2023-04-26 04:28:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::EnableButtons() const
|
|
|
|
|
{
|
2023-05-09 01:55:31 +00:00
|
|
|
|
ToggleButtonIfResourceAvailable();
|
2023-04-26 04:28:02 +00:00
|
|
|
|
BackspaceButton->SetIsEnabled(true);
|
|
|
|
|
CastButton->SetIsEnabled(true);
|
|
|
|
|
RunButton->SetIsEnabled(true);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-17 03:02:58 +00:00
|
|
|
|
void ATurnBaseCombatV2::EnemyTurn()
|
|
|
|
|
{
|
2023-05-11 03:55:41 +00:00
|
|
|
|
int ChanceToMiss;
|
|
|
|
|
FProperty* IsBossProperty = FindFieldChecked<FProperty>(EnemyActor->GetClass(), "IsBoss");
|
|
|
|
|
const FBoolProperty* IsBossBoolProperty = CastFieldChecked<FBoolProperty>(IsBossProperty);
|
|
|
|
|
if (IsBossBoolProperty->GetPropertyValue_InContainer(EnemyActor)) ChanceToMiss = 5;
|
|
|
|
|
else ChanceToMiss = 30;
|
|
|
|
|
if (FMath::RandRange(1, 100) > ChanceToMiss)
|
2023-05-11 03:12:00 +00:00
|
|
|
|
{
|
2023-05-12 23:42:38 +00:00
|
|
|
|
if (IsBossBoolProperty->GetPropertyValue_InContainer(EnemyActor) && FMath::RandRange(1, 100) > 10)
|
|
|
|
|
{
|
|
|
|
|
FOutputDeviceNull AR;
|
|
|
|
|
UStatusSystem* StatusSystem = Cast<UStatusSystem>(PlayerActor->GetComponentByClass(UStatusSystem::StaticClass()));
|
|
|
|
|
UStatusEffect* TempPlayerDamageDownStatusEffect = NewObject<UStatusEffect>(PlayerActor, DamageDownPlayerStatusEffect);
|
|
|
|
|
StatusSystem->AddStatusEffect(TempPlayerDamageDownStatusEffect, 1, true);
|
|
|
|
|
StatusEffects.Add(TempPlayerDamageDownStatusEffect);
|
|
|
|
|
AddBattleLogMessage("Player Damage Down");
|
|
|
|
|
StatusTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 0.0f, 0.0f, 1.0f)));
|
|
|
|
|
StatusTextBlock->SetText(FText::FromString("Player Damage Down"));
|
|
|
|
|
const FString Command3 = FString::Printf(TEXT("PlayStatusAnimation"));
|
|
|
|
|
HUD->CallFunctionByNameWithArguments(*Command3, AR, nullptr, true);
|
|
|
|
|
const FString Command4 = FString::Printf(TEXT("TriggerScreamAnimation"));
|
|
|
|
|
EnemyActor->CallFunctionByNameWithArguments(*Command4, AR, nullptr, true);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const FProperty* EnemyBaseDamageProperty = EnemyActor->GetClass()->FindPropertyByName(FName("BaseDamage"));
|
|
|
|
|
const int* EnemyBaseDamagePtr = EnemyBaseDamageProperty->ContainerPtrToValuePtr<int>(EnemyActor);
|
|
|
|
|
DamagePlayer(*EnemyBaseDamagePtr);
|
|
|
|
|
}
|
2023-05-11 03:12:00 +00:00
|
|
|
|
}
|
2023-05-11 03:00:03 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2023-05-12 20:45:51 +00:00
|
|
|
|
StatusTextBlock->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 1.0f, 1.0f, 1.0f)));
|
2023-05-11 03:00:03 +00:00
|
|
|
|
StatusTextBlock->SetText(FText::FromString("Missed"));
|
|
|
|
|
FOutputDeviceNull AR;
|
|
|
|
|
const FString Command3 = FString::Printf(TEXT("PlayStatusAnimation"));
|
|
|
|
|
HUD->CallFunctionByNameWithArguments(*Command3, AR, nullptr, true);
|
|
|
|
|
const FString Command2 = FString::Printf(TEXT("TriggerAttackAnimation"));
|
|
|
|
|
EnemyActor->CallFunctionByNameWithArguments(*Command2, AR, nullptr, true);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-02 03:25:00 +00:00
|
|
|
|
OnEnemyTurn.Broadcast(EnemyActor, PlayerActor);
|
2022-11-17 03:02:58 +00:00
|
|
|
|
TurnIndicatorTextBlock->SetText(FText::FromString("Player Turn"));
|
2023-05-09 01:55:31 +00:00
|
|
|
|
EnableButtons();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::ToggleButtonIfResourceAvailable() const
|
|
|
|
|
{
|
|
|
|
|
if (ProbertiumResource >= 1) PButton->SetIsEnabled(true);
|
|
|
|
|
else PButton->SetIsEnabled(false);
|
|
|
|
|
if (EisResource >= 1) EButton->SetIsEnabled(true);
|
|
|
|
|
else EButton->SetIsEnabled(false);
|
|
|
|
|
if (AzosResource >= 1) AButton->SetIsEnabled(true);
|
|
|
|
|
else AButton->SetIsEnabled(false);
|
|
|
|
|
if (IroquoidResource >= 1) IButton->SetIsEnabled(true);
|
|
|
|
|
else IButton->SetIsEnabled(false);
|
2023-05-12 20:45:51 +00:00
|
|
|
|
if (Cast<ATempCharacter>(PlayerActor)->Inventory->GetItemAmount(0) >= 1 && *PlayerHealth < 100.0f) HealButton->SetIsEnabled(true);
|
2023-05-09 04:40:31 +00:00
|
|
|
|
else HealButton->SetIsEnabled(false);
|
2023-01-31 00:04:24 +00:00
|
|
|
|
}
|