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"
|
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"
|
2022-11-29 00:33:34 +00:00
|
|
|
|
#include "GameFramework/Character.h"
|
2022-11-17 03:02:58 +00:00
|
|
|
|
#include "Kismet/GameplayStatics.h"
|
|
|
|
|
|
|
|
|
|
// Sets default values
|
|
|
|
|
ATurnBaseCombatV2::ATurnBaseCombatV2()
|
|
|
|
|
{
|
|
|
|
|
if (HUDWidget == nullptr)
|
|
|
|
|
{
|
|
|
|
|
// Load the HUD widget from the specified path
|
|
|
|
|
static ConstructorHelpers::FClassFinder<UUserWidget> HUDWidgetClass(TEXT("/Game/Blueprints/Combat_UI/Combat_UI"));
|
|
|
|
|
HUDWidget = HUDWidgetClass.Class;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::StartCombat(AActor* Enemy)
|
|
|
|
|
{
|
2023-01-31 00:04:24 +00:00
|
|
|
|
if (Enemy == nullptr) return;
|
2023-01-31 00:29:53 +00:00
|
|
|
|
UBlackboardComponent* EnemyBlackboard = Cast<AAIController>(Enemy->GetInstigatorController())->GetBlackboardComponent();
|
|
|
|
|
|
2023-01-31 00:04:24 +00:00
|
|
|
|
if (EnemyBlackboard->GetValueAsBool("IsInCombat")) return;
|
2023-01-31 00:29:53 +00:00
|
|
|
|
EnemyBlackboard->SetValueAsBool("IsInCombat", true);
|
2023-01-31 00:04:24 +00:00
|
|
|
|
FProperty* HealthProperty = Enemy->GetClass()->FindPropertyByName(FName("Health"));
|
|
|
|
|
int32* EnemyHealthPtr = HealthProperty->ContainerPtrToValuePtr<int32>(Enemy);
|
|
|
|
|
|
|
|
|
|
EnemyHealth = EnemyHealthPtr;
|
|
|
|
|
|
2022-11-17 03:02:58 +00:00
|
|
|
|
if (HUD->IsInViewport()) return;
|
|
|
|
|
HUD->AddToViewport();
|
|
|
|
|
EnemyActor = Enemy;
|
|
|
|
|
|
|
|
|
|
if (APlayerController* PC = Cast<APlayerController>(GetWorld()->GetFirstPlayerController()))
|
|
|
|
|
{
|
|
|
|
|
PC->bShowMouseCursor = true;
|
|
|
|
|
PC->bEnableClickEvents = true;
|
|
|
|
|
PC->bEnableMouseOverEvents = true;
|
|
|
|
|
}
|
2022-11-29 00:33:34 +00:00
|
|
|
|
//Disable Character Movement
|
|
|
|
|
if (ACharacter* PlayerCharacter = Cast<ACharacter>(GetWorld()->GetFirstPlayerController()->GetPawn()))
|
|
|
|
|
{
|
|
|
|
|
PlayerCharacter->DisableInput(GetWorld()->GetFirstPlayerController());
|
|
|
|
|
}
|
|
|
|
|
CurrentComboString = "";
|
|
|
|
|
UpdateComboString(CurrentComboString);
|
|
|
|
|
RevertActionPoints();
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
UpdateResourceBars();
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::EndCombat()
|
|
|
|
|
{
|
|
|
|
|
//Remove the HUD from the viewport
|
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
|
|
|
|
|
if (ACharacter* PlayerCharacter = Cast<ACharacter>(GetWorld()->GetFirstPlayerController()->GetPawn()))
|
|
|
|
|
{
|
|
|
|
|
PlayerCharacter->EnableInput(GetWorld()->GetFirstPlayerController());
|
|
|
|
|
}
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-24 02:49:37 +00:00
|
|
|
|
void ATurnBaseCombatV2::FKeyPressed()
|
|
|
|
|
{
|
|
|
|
|
FButtonOnClick();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::WKeyPressed()
|
|
|
|
|
{
|
|
|
|
|
WButtonOnClick();
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
2022-11-17 03:02:58 +00:00
|
|
|
|
|
|
|
|
|
HUD = CreateWidget<UUserWidget>(GetWorld(), HUDWidget);
|
|
|
|
|
|
|
|
|
|
TurnIndicatorTextBlock = Cast<UTextBlock>(HUD->GetWidgetFromName("TurnIndicator"));
|
|
|
|
|
CurrentComboTextBlock = Cast<UTextBlock>(HUD->GetWidgetFromName("CurrentCombo"));
|
|
|
|
|
ActionPointsTextBlock = Cast<UTextBlock>(HUD->GetWidgetFromName("ActionPoints"));
|
|
|
|
|
BattleLogTextBlock = Cast<UTextBlock>(HUD->GetWidgetFromName("BattleLog"));
|
|
|
|
|
PlayerHealthBar = Cast<UProgressBar>(HUD->GetWidgetFromName("PlayerHealthBar"));
|
|
|
|
|
EnemyHealthBar = Cast<UProgressBar>(HUD->GetWidgetFromName("EnemyHealthBar"));
|
|
|
|
|
IronResourceBar = Cast<UProgressBar>(HUD->GetWidgetFromName("IronResourceBar"));
|
|
|
|
|
SulfurResourceBar = Cast<UProgressBar>(HUD->GetWidgetFromName("SulfurResourceBar"));
|
|
|
|
|
CastButton = Cast<UButton>(HUD->GetWidgetFromName("CastButton"));
|
|
|
|
|
FButton = Cast<UButton>(HUD->GetWidgetFromName("FButton"));
|
|
|
|
|
WButton = Cast<UButton>(HUD->GetWidgetFromName("WButton"));
|
|
|
|
|
BackspaceButton = Cast<UButton>(HUD->GetWidgetFromName("BackspaceButton"));
|
|
|
|
|
CastButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::CastButtonOnClick);
|
|
|
|
|
FButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::FButtonOnClick);
|
|
|
|
|
WButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::WButtonOnClick);
|
|
|
|
|
BackspaceButton->OnClicked.AddDynamic(this, &ATurnBaseCombatV2::BackspaceButtonOnClick);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::ExecuteCast(FString Combo)
|
|
|
|
|
{
|
|
|
|
|
if (!IsValidCombo(Combo))
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Invalid Combo"));
|
|
|
|
|
//For each character in the current combo add back the resource
|
|
|
|
|
for (int i = 0; i < Combo.Len(); i++)
|
|
|
|
|
{
|
|
|
|
|
if (Combo[i] == 'F')
|
|
|
|
|
{
|
|
|
|
|
IronResource += 1;
|
|
|
|
|
}
|
|
|
|
|
else if (Combo[i] == 'W')
|
|
|
|
|
{
|
|
|
|
|
SulfurResource += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
CurrentComboString = "";
|
|
|
|
|
UpdateComboString(CurrentComboString);
|
|
|
|
|
RevertActionPoints();
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
UpdateResourceBars();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-29 01:54:45 +00:00
|
|
|
|
if (GunEffect)
|
|
|
|
|
{
|
|
|
|
|
//Get Static Mesh Location on the player actor
|
|
|
|
|
const UStaticMeshComponent* GunComponent = Cast<UStaticMeshComponent>(PlayerActor->GetComponentsByTag(UPrimitiveComponent::StaticClass(), FName("Gun"))[0]);
|
|
|
|
|
const FVector GunLocationOffset = GunComponent->GetSocketTransform("Muzzle").TransformPosition(FVector(-100, 0, 0));
|
|
|
|
|
UNiagaraFunctionLibrary::SpawnSystemAtLocation(GetWorld(), GunEffect, GunLocationOffset, PlayerActor->GetActorRotation());
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-17 03:02:58 +00:00
|
|
|
|
CurrentComboString = "";
|
|
|
|
|
UpdateComboString(CurrentComboString);
|
|
|
|
|
RevertActionPoints();
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
|
|
|
|
|
switch (bIsPlayerTurn)
|
|
|
|
|
{
|
|
|
|
|
case true:
|
|
|
|
|
// Player Turn
|
|
|
|
|
DamageEnemy(*ValidCombos.Find(Combo));
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("Enemy Damaged %d"), *ValidCombos.Find(Combo)));
|
|
|
|
|
break;
|
|
|
|
|
case false:
|
|
|
|
|
// Enemy Turn
|
|
|
|
|
DamagePlayer(*ValidCombos.Find(Combo));
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::Printf(TEXT("Player Damaged %d"), *ValidCombos.Find(Combo)));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
//End Combat if either the player or enemy is dead
|
2023-01-31 00:04:24 +00:00
|
|
|
|
if (*EnemyHealth <= 0)
|
2022-11-17 03:02:58 +00:00
|
|
|
|
{
|
|
|
|
|
EndCombat();
|
|
|
|
|
EnemyActor->Destroy();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (PlayerHealth <= 0)
|
|
|
|
|
{
|
|
|
|
|
EndCombat();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SwitchTurn();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::UseActionPoint()
|
|
|
|
|
{
|
|
|
|
|
ActiveActionPoints += 1;
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::ReuseActionPoint()
|
|
|
|
|
{
|
|
|
|
|
ActiveActionPoints -= 1;
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::RevertActionPoints()
|
|
|
|
|
{
|
|
|
|
|
ActiveActionPoints = 0;
|
|
|
|
|
UpdateActionPoints();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::DamagePlayer(int Damage)
|
|
|
|
|
{
|
|
|
|
|
PlayerHealth -= FMath::Clamp(Damage, 0, 100);
|
|
|
|
|
UpdateProgressBars();
|
|
|
|
|
AddBattleLogMessage("Player was damaged for " + FString::FromInt(Damage) + " damage.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::DamageEnemy(int Damage)
|
|
|
|
|
{
|
2023-01-31 00:04:24 +00:00
|
|
|
|
*EnemyHealth -= FMath::Clamp(Damage, 0, 100);
|
2022-11-17 03:02:58 +00:00
|
|
|
|
UpdateProgressBars();
|
|
|
|
|
AddBattleLogMessage("Enemy was damaged for " + FString::FromInt(Damage) + " damage.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::UpdateProgressBars() const
|
|
|
|
|
{
|
|
|
|
|
PlayerHealthBar->SetPercent(PlayerHealth / 100.0f);
|
2023-01-31 00:04:24 +00:00
|
|
|
|
EnemyHealthBar->SetPercent(*EnemyHealth / 100.0f);
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ATurnBaseCombatV2::IsValidCombo(FString Combo) const
|
|
|
|
|
{
|
|
|
|
|
return ValidCombos.Contains(Combo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::SwitchTurn()
|
|
|
|
|
{
|
|
|
|
|
//TurnIndicatorTextBlock->SetText(FText::FromString(bIsPlayerTurn ? "Enemy Turn" : "Player Turn"));
|
|
|
|
|
//bIsPlayerTurn = !bIsPlayerTurn;
|
|
|
|
|
TurnIndicatorTextBlock->SetText(FText::FromString("Enemy Turn"));
|
|
|
|
|
ToggleButtons();
|
|
|
|
|
//wait for 2 seconds
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::FButtonOnClick()
|
|
|
|
|
{
|
|
|
|
|
if (ActiveActionPoints >= DefaultActionPoints)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Action Points"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (IronResource <= 0)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Iron"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
UseActionPoint();
|
|
|
|
|
CurrentComboString.AppendChar('F');
|
|
|
|
|
UpdateComboString(CurrentComboString);
|
|
|
|
|
IronResource -= 1;
|
|
|
|
|
UpdateResourceBars();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::WButtonOnClick()
|
|
|
|
|
{
|
|
|
|
|
if (ActiveActionPoints >= DefaultActionPoints)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Action Points"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (SulfurResource <= 0)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("No More Sulfur"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
UseActionPoint();
|
|
|
|
|
CurrentComboString.AppendChar('W');
|
|
|
|
|
UpdateComboString(CurrentComboString);
|
|
|
|
|
SulfurResource -= 1;
|
|
|
|
|
UpdateResourceBars();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::BackspaceButtonOnClick()
|
|
|
|
|
{
|
|
|
|
|
if (CurrentComboString.Len() <= 0)
|
|
|
|
|
{
|
|
|
|
|
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Blank Combo"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ReuseActionPoint();
|
|
|
|
|
if (CurrentComboString.Right(1) == "F")
|
|
|
|
|
{
|
|
|
|
|
IronResource += 1;
|
|
|
|
|
}
|
|
|
|
|
else if (CurrentComboString.Right(1) == "W")
|
|
|
|
|
{
|
|
|
|
|
SulfurResource += 1;
|
|
|
|
|
}
|
|
|
|
|
CurrentComboString.RemoveAt(CurrentComboString.Len() - 1);
|
|
|
|
|
UpdateComboString(CurrentComboString);
|
|
|
|
|
UpdateResourceBars();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::UpdateComboString(FString NewCombo) const
|
|
|
|
|
{
|
|
|
|
|
CurrentComboTextBlock->SetText(FText::FromString(NewCombo));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::UpdateActionPoints() const
|
|
|
|
|
{
|
|
|
|
|
ActionPointsTextBlock->SetText(FText::FromString(FString::FromInt(ActiveActionPoints)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::AddBattleLogMessage(FString Message)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
IronResourceBar->SetPercent(IronResource / 10.0f);
|
|
|
|
|
SulfurResourceBar->SetPercent(SulfurResource / 10.0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::ToggleButtons() const
|
|
|
|
|
{
|
2023-01-15 19:50:39 +00:00
|
|
|
|
FButton->SetIsEnabled(!FButton->GetIsEnabled());
|
|
|
|
|
WButton->SetIsEnabled(!WButton->GetIsEnabled());
|
|
|
|
|
BackspaceButton->SetIsEnabled(!BackspaceButton->GetIsEnabled());
|
|
|
|
|
CastButton->SetIsEnabled(!CastButton->GetIsEnabled());
|
2022-11-17 03:02:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ATurnBaseCombatV2::EnemyTurn()
|
|
|
|
|
{
|
|
|
|
|
DamagePlayer(10);
|
|
|
|
|
TurnIndicatorTextBlock->SetText(FText::FromString("Player Turn"));
|
|
|
|
|
ToggleButtons();
|
2023-01-31 00:04:24 +00:00
|
|
|
|
}
|