Merge branch 'Turn-Based-Combat' into Hub-level-blockout

This commit is contained in:
Philip W 2023-03-05 18:47:08 +00:00
commit 704ba824e6
13 changed files with 148 additions and 29 deletions

View File

@ -1,10 +1,15 @@
{ {
"version": "1.0", "version": "1.0",
"components": [ "components": [
"Microsoft.Net.Component.4.6.2.TargetingPack",
"Microsoft.VisualStudio.Component.VC.14.33.17.3.ARM64",
"Microsoft.VisualStudio.Component.VC.14.33.17.3.x86.x64",
"Microsoft.VisualStudio.Component.VC.Tools.ARM64", "Microsoft.VisualStudio.Component.VC.Tools.ARM64",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows10SDK", "Microsoft.VisualStudio.Component.Windows10SDK",
"Microsoft.VisualStudio.Workload.CoreEditor", "Microsoft.VisualStudio.Workload.CoreEditor",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NativeCrossPlat",
"Microsoft.VisualStudio.Workload.NativeDesktop", "Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.NativeGame", "Microsoft.VisualStudio.Workload.NativeGame",
"Microsoft.VisualStudio.Workload.Universal" "Microsoft.VisualStudio.Workload.Universal"

BIN
Content/Blueprints/StatusEffects/BP_DamageOverTime.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

View File

@ -5,6 +5,7 @@
#include "StatusSystem.h" #include "StatusSystem.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "TurnBaseCombatV2.h"
#include "Components/TextBlock.h" #include "Components/TextBlock.h"
void UStatusEffect::Invoke(AActor* Character, float TimeOfInit) void UStatusEffect::Invoke(AActor* Character, float TimeOfInit)
@ -19,16 +20,33 @@ void UStatusEffect::OnExpiry(AActor* Character)
if (StatusSystem->GetActiveStatusEffect(this).StatusIcon == nullptr) return; if (StatusSystem->GetActiveStatusEffect(this).StatusIcon == nullptr) return;
StatusSystem->GetActiveStatusEffect(this).StatusIcon->RemoveFromParent(); StatusSystem->GetActiveStatusEffect(this).StatusIcon->RemoveFromParent();
StatusSystem->RemoveStatusEffect(this); StatusSystem->RemoveStatusEffect(this);
ATurnBaseCombatV2* CombatSystem = Cast<ATurnBaseCombatV2>(GetWorld()->GetGameState());
CombatSystem->OnPlayerTurn.Remove(OnPlayerTurnDelegateHandle);
CombatSystem->OnEnemyTurn.Remove(OnEnemyTurnDelegateHandle);
} }
void UStatusEffect::OnPlayerTurn(AActor* Character) void UStatusEffect::OnPlayerTurn(AActor* Character, AActor* Enemy)
{ {
return; return;
} }
void UStatusEffect::OnEnemyTurn(AActor* Character) void UStatusEffect::OnEnemyTurn(AActor* Enemy, AActor* Character)
{ {
return; TickDown(Character);
}
void UStatusEffect::OnStatusEffectAdd(AActor* Character)
{
ATurnBaseCombatV2* CombatSystem = Cast<ATurnBaseCombatV2>(GetWorld()->GetGameState());
OnPlayerTurnDelegateHandle = CombatSystem->OnPlayerTurn.AddUObject(this, &UStatusEffect::OnPlayerTurn);
OnEnemyTurnDelegateHandle = CombatSystem->OnEnemyTurn.AddUObject(this, &UStatusEffect::OnEnemyTurn);
}
void UStatusEffect::TickDown(AActor* Character)
{
UStatusSystem* StatusSystem = Cast<UStatusSystem>(Character->GetComponentByClass(UStatusSystem::StaticClass()));
UTextBlock* StatusText = Cast<UTextBlock>(StatusSystem->GetActiveStatusEffect(this).StatusIcon->GetWidgetFromName(TEXT("DurationText")));
StatusText->SetText(FText::FromString(FString::FromInt(BaseDuration)));
} }
void UStatusEffect::CheckForExpiry(const float TimeOfExpiry, AActor* Character) void UStatusEffect::CheckForExpiry(const float TimeOfExpiry, AActor* Character)

View File

@ -20,25 +20,34 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite) UPROPERTY(EditAnywhere, BlueprintReadWrite)
FString Description; FString Description;
UPROPERTY(EditAnywhere, BlueprintReadWrite) UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool IsForCombatOnly = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float BaseDuration; float BaseDuration;
UPROPERTY(EditAnywhere, BlueprintReadWrite) UPROPERTY(EditAnywhere, BlueprintReadWrite)
UTexture2D* Icon; UTexture2D* Icon;
UFUNCTION() UFUNCTION()
virtual void Invoke(AActor* Character, float TimeOfExpiry); virtual void Invoke(AActor* Character, float TimeOfExpiry);
UFUNCTION() UFUNCTION()
virtual void OnExpiry(AActor* Character); virtual void OnExpiry(AActor* Character);
UFUNCTION() UFUNCTION()
virtual void OnPlayerTurn(AActor* Character); virtual void OnPlayerTurn(AActor* Character, AActor* Enemy);
UFUNCTION()
virtual void OnEnemyTurn(AActor* Enemy, AActor* Character);
UFUNCTION() UFUNCTION()
virtual void OnEnemyTurn(AActor* Character); virtual void OnStatusEffectAdd(AActor* Character);
UFUNCTION()
virtual void TickDown(AActor* Character);
protected: protected:
UPROPERTY() UPROPERTY()
FTimerHandle ExpiryTimerHandle; FTimerHandle ExpiryTimerHandle;
UFUNCTION() UFUNCTION()
void CheckForExpiry(float TimeOfExpiry, AActor* Character); void CheckForExpiry(float TimeOfExpiry, AActor* Character);
FDelegateHandle OnPlayerTurnDelegateHandle;
FDelegateHandle OnEnemyTurnDelegateHandle;
}; };

View File

@ -0,0 +1,17 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "DamageOverTime.h"
#include <the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.h>
void UDamageOverTime::OnEnemyTurn(AActor* Enemy, AActor* Character)
{
ATurnBaseCombatV2* CombatSystem = Cast<ATurnBaseCombatV2>(GetWorld()->GetGameState());
CombatSystem->DamageEnemy(DamagePerTurn, "DOT");
BaseDuration -= 1.0f;
Super::OnEnemyTurn(Enemy, Character);
if (BaseDuration <= 0.0f)
{
OnExpiry(Character);
}
}

View File

@ -0,0 +1,23 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "../StatusEffect.h"
#include "DamageOverTime.generated.h"
/**
*
*/
UCLASS()
class THE_TWILIGHT_ABYSS_API UDamageOverTime : public UStatusEffect
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float DamagePerTurn = 6.0f;
//virtual void Invoke(AActor* Character, float TimeOfExpiry) override;
//virtual void OnExpiry(AActor* Character) override;
virtual void OnEnemyTurn(AActor* Enemy, AActor* Character) override;
};

View File

@ -3,6 +3,8 @@
#include "Thorns.h" #include "Thorns.h"
#include "the_twilight_abyss/TurnBasedCombatV2/TurnBaseCombatV2.h"
void UThorns::Invoke(AActor* Character, float TimeOfExpiry) void UThorns::Invoke(AActor* Character, float TimeOfExpiry)
{ {
Super::Invoke(Character, TimeOfExpiry); Super::Invoke(Character, TimeOfExpiry);
@ -12,3 +14,15 @@ void UThorns::OnExpiry(AActor* Character)
{ {
Super::OnExpiry(Character); Super::OnExpiry(Character);
} }
void UThorns::OnEnemyTurn(AActor* Enemy, AActor* Character)
{
ATurnBaseCombatV2* CombatSystem = Cast<ATurnBaseCombatV2>(GetWorld()->GetGameState());
CombatSystem->DamageEnemy(DamagePerTurn, "thorns");
BaseDuration -= 1.0f;
Super::OnEnemyTurn(Enemy, Character);
if (BaseDuration <= 0.0f)
{
OnExpiry(Character);
}
}

View File

@ -15,6 +15,10 @@ class THE_TWILIGHT_ABYSS_API UThorns : public UStatusEffect
GENERATED_BODY() GENERATED_BODY()
public: public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float DamagePerTurn = 3.0f;
virtual void Invoke(AActor* Character, float TimeOfExpiry) override; virtual void Invoke(AActor* Character, float TimeOfExpiry) override;
virtual void OnExpiry(AActor* Character) override; virtual void OnExpiry(AActor* Character) override;
virtual void OnEnemyTurn(AActor* Enemy, AActor* Character) override;
}; };

View File

@ -43,11 +43,21 @@ void UStatusSystem::AddStatusEffect(UStatusEffect* StatusEffect, const float Dur
FActiveStatusEffect NewStatusEffect; FActiveStatusEffect NewStatusEffect;
NewStatusEffect.StatusEffect = StatusEffect; NewStatusEffect.StatusEffect = StatusEffect;
NewStatusEffect.TimeInitiated = UGameplayStatics::GetRealTimeSeconds(GetWorld()); NewStatusEffect.TimeInitiated = UGameplayStatics::GetRealTimeSeconds(GetWorld());
if (StatusEffect->IsForCombatOnly)
{
NewStatusEffect.TimeTillExpiry = StatusEffect->BaseDuration * DurationMultiplier;
}
else
{
NewStatusEffect.TimeTillExpiry = UGameplayStatics::GetRealTimeSeconds(GetWorld()) + StatusEffect->BaseDuration * DurationMultiplier; NewStatusEffect.TimeTillExpiry = UGameplayStatics::GetRealTimeSeconds(GetWorld()) + StatusEffect->BaseDuration * DurationMultiplier;
}
NewStatusEffect.StatusIcon = CreateWidget<UUserWidget>(GetWorld(), HUDStatusIconWidget); NewStatusEffect.StatusIcon = CreateWidget<UUserWidget>(GetWorld(), HUDStatusIconWidget);
UImage* StatusIconImage = Cast<UImage>(NewStatusEffect.StatusIcon->GetWidgetFromName(TEXT("StatusIconImage"))); UImage* StatusIconImage = Cast<UImage>(NewStatusEffect.StatusIcon->GetWidgetFromName(TEXT("StatusIconImage")));
StatusIconImage->SetBrushFromTexture(StatusEffect->Icon); StatusIconImage->SetBrushFromTexture(StatusEffect->Icon);
StatusIconsBox->AddChild(NewStatusEffect.StatusIcon); StatusIconsBox->AddChild(NewStatusEffect.StatusIcon);
NewStatusEffect.StatusEffect->OnStatusEffectAdd(GetOwner());
UTextBlock* StatusText = Cast<UTextBlock>(NewStatusEffect.StatusIcon->GetWidgetFromName(TEXT("DurationText")));
StatusText->SetText(FText::FromString(FString::FromInt(NewStatusEffect.TimeTillExpiry)));
if (Invoke) NewStatusEffect.StatusEffect->Invoke(GetOwner(), NewStatusEffect.TimeTillExpiry); if (Invoke) NewStatusEffect.StatusEffect->Invoke(GetOwner(), NewStatusEffect.TimeTillExpiry);
ActiveStatusEffects.Add(NewStatusEffect); ActiveStatusEffects.Add(NewStatusEffect);

View File

@ -22,6 +22,8 @@ ATurnBaseCombatV2::ATurnBaseCombatV2()
HUDWidget = HUDWidgetClass.Class; HUDWidget = HUDWidgetClass.Class;
static ConstructorHelpers::FClassFinder<UStatusEffect> StatusEffectThornsClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_Thorns")); static ConstructorHelpers::FClassFinder<UStatusEffect> StatusEffectThornsClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_Thorns"));
ThornsStatusEffect = StatusEffectThornsClassFinder.Class; ThornsStatusEffect = StatusEffectThornsClassFinder.Class;
static ConstructorHelpers::FClassFinder<UStatusEffect> StatusEffectDOTClassFinder(TEXT("/Game/Blueprints/StatusEffects/BP_DamageOverTime"));
DOTStatusEffect = StatusEffectDOTClassFinder.Class;
} }
} }
@ -86,15 +88,15 @@ void ATurnBaseCombatV2::EndCombat()
PlayerController->bShowMouseCursor = false; PlayerController->bShowMouseCursor = false;
} }
void ATurnBaseCombatV2::FKeyPressed() // void ATurnBaseCombatV2::FKeyPressed()
{ // {
PButtonOnClick(); // PButtonOnClick();
} // }
//
void ATurnBaseCombatV2::WKeyPressed() // void ATurnBaseCombatV2::WKeyPressed()
{ // {
EButtonOnClick(); // EButtonOnClick();
} // }
void ATurnBaseCombatV2::BeginPlay() void ATurnBaseCombatV2::BeginPlay()
{ {
@ -176,6 +178,14 @@ void ATurnBaseCombatV2::ExecuteCast(FString Combo)
UStatusEffect* TempThornsStatusEffect = NewObject<UStatusEffect>(PlayerActor, ThornsStatusEffect); UStatusEffect* TempThornsStatusEffect = NewObject<UStatusEffect>(PlayerActor, ThornsStatusEffect);
StatusSystem->AddStatusEffect(TempThornsStatusEffect, 1, false); StatusSystem->AddStatusEffect(TempThornsStatusEffect, 1, false);
StatusEffects.Add(TempThornsStatusEffect); StatusEffects.Add(TempThornsStatusEffect);
AddBattleLogMessage("Player Casted Thorns");
}
else if (Combo == "PPI")
{
UStatusEffect* TempDOTStatusEffect = NewObject<UStatusEffect>(PlayerActor, DOTStatusEffect);
StatusSystem->AddStatusEffect(TempDOTStatusEffect, 1, false);
StatusEffects.Add(TempDOTStatusEffect);
AddBattleLogMessage("Player Casted DOT");
} }
} }
@ -191,6 +201,7 @@ void ATurnBaseCombatV2::ExecuteCast(FString Combo)
RevertActionPoints(); RevertActionPoints();
UpdateActionPoints(); UpdateActionPoints();
//Damage Calculation
switch (bIsPlayerTurn) switch (bIsPlayerTurn)
{ {
case true: case true:
@ -241,18 +252,18 @@ void ATurnBaseCombatV2::RevertActionPoints()
UpdateActionPoints(); UpdateActionPoints();
} }
void ATurnBaseCombatV2::DamagePlayer(int Damage) void ATurnBaseCombatV2::DamagePlayer(int Damage, FString DamageType)
{ {
*PlayerHealth -= FMath::Clamp(Damage, 0, 100); *PlayerHealth -= FMath::Clamp(Damage, 0, 100);
UpdateProgressBars(); UpdateProgressBars();
AddBattleLogMessage("Player was damaged for " + FString::FromInt(Damage) + " damage."); AddBattleLogMessage("Player was damaged for " + FString::FromInt(Damage) + " HP by " + DamageType + ".");
} }
void ATurnBaseCombatV2::DamageEnemy(int Damage) void ATurnBaseCombatV2::DamageEnemy(int Damage, FString DamageType)
{ {
*EnemyHealth -= FMath::Clamp(Damage, 0, 100); *EnemyHealth -= FMath::Clamp(Damage, 0, 100);
UpdateProgressBars(); UpdateProgressBars();
AddBattleLogMessage("Enemy was damaged for " + FString::FromInt(Damage) + " damage."); AddBattleLogMessage("Enemy was damaged for " + FString::FromInt(Damage) + " HP by " + DamageType + ".");
} }
void ATurnBaseCombatV2::UpdateProgressBars() const void ATurnBaseCombatV2::UpdateProgressBars() const
@ -455,6 +466,7 @@ void ATurnBaseCombatV2::ToggleButtons() const
void ATurnBaseCombatV2::EnemyTurn() void ATurnBaseCombatV2::EnemyTurn()
{ {
DamagePlayer(10); DamagePlayer(10);
OnEnemyTurn.Broadcast(EnemyActor, PlayerActor);
TurnIndicatorTextBlock->SetText(FText::FromString("Player Turn")); TurnIndicatorTextBlock->SetText(FText::FromString("Player Turn"));
ToggleButtons(); ToggleButtons();
} }

View File

@ -94,24 +94,25 @@ public:
void StartCombat(AActor* Enemy); void StartCombat(AActor* Enemy);
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
void EndCombat(); void EndCombat();
UFUNCTION(BlueprintCallable) // UFUNCTION(BlueprintCallable)
void FKeyPressed(); // void FKeyPressed();
UFUNCTION(BlueprintCallable) // UFUNCTION(BlueprintCallable)
void WKeyPressed(); // void WKeyPressed();
DECLARE_EVENT_TwoParams(ATurnBaseCombatV2, FOnPlayerTurn, AActor*, AActor*); DECLARE_EVENT_TwoParams(ATurnBaseCombatV2, FOnPlayerTurn, AActor*, AActor*);
DECLARE_EVENT_TwoParams(ATurnBaseCombatV2, FOnEnemyTurn, AActor*, AActor*); DECLARE_EVENT_TwoParams(ATurnBaseCombatV2, FOnEnemyTurn, AActor*, AActor*);
FOnPlayerTurn OnPlayerTurn; FOnPlayerTurn OnPlayerTurn;
FOnEnemyTurn OnEnemyTurn; FOnEnemyTurn OnEnemyTurn;
void DamagePlayer(int Damage, FString DamageType = "unknown");
void DamageEnemy(int Damage, FString DamageType = "unknown");
protected: protected:
virtual void BeginPlay() override; virtual void BeginPlay() override;
void ExecuteCast(FString Combo); void ExecuteCast(FString Combo);
void UseActionPoint(); void UseActionPoint();
void ReuseActionPoint(); void ReuseActionPoint();
void RevertActionPoints(); void RevertActionPoints();
void DamagePlayer(int Damage);
void DamageEnemy(int Damage);
void UpdateProgressBars() const; void UpdateProgressBars() const;
private: private:
@ -120,6 +121,8 @@ private:
UPROPERTY() UPROPERTY()
TSubclassOf<UStatusEffect> ThornsStatusEffect; TSubclassOf<UStatusEffect> ThornsStatusEffect;
UPROPERTY()
TSubclassOf<UStatusEffect> DOTStatusEffect;
UPROPERTY() UPROPERTY()
TArray<UStatusEffect*> StatusEffects; TArray<UStatusEffect*> StatusEffects;

View File

@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Azos/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Azos/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Iroquoid/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Iroquoid/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Probertium/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> <s:Boolean x:Key="/Default/UserDictionary/Words/=Probertium/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=UFUNCTION/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>