From 1d964b289c1f38bf0dd99a58df5002e1367aba0e Mon Sep 17 00:00:00 2001 From: charnet3d Date: Mon, 29 Jan 2024 03:46:47 +0100 Subject: [PATCH] Some basic boilerplate for win/lose states --- .../0/W3/BH9RA5CXGG4V6NBO45LIOY.uasset | 2 +- .../2/YS/0MUVLSZG6FOQLXF4C5BDRV.uasset | 4 +- .../3/YJ/OD1NN2YHEXD84Z0IQ2F2Z8.uasset | 3 -- .../7/UM/P713255HQHP0RVRQ5S9OSS.uasset | 3 ++ FunnyPrince.uproject | 4 +- Source/FunnyPrince/FighterAIController.cpp | 36 ++++++++++++++++ Source/FunnyPrince/FighterAIController.h | 28 +++++++++++++ Source/FunnyPrince/FunnyPrince.Build.cs | 2 +- Source/FunnyPrince/FunnyPrinceCharacter.cpp | 9 +++- Source/FunnyPrince/FunnyPrinceCharacter.h | 6 +-- Source/FunnyPrince/FunnyPrinceController.cpp | 41 ++++++++++++++++++ Source/FunnyPrince/FunnyPrinceController.h | 42 +++++++++++++++++++ Source/FunnyPrince/FunnyPrinceGameMode.cpp | 37 ++++++++++++++++ Source/FunnyPrince/FunnyPrinceGameMode.h | 3 ++ 14 files changed, 207 insertions(+), 13 deletions(-) delete mode 100644 Content/__ExternalActors__/SideScroller/Maps/ExampleMap/3/YJ/OD1NN2YHEXD84Z0IQ2F2Z8.uasset create mode 100644 Content/__ExternalActors__/SideScroller/Maps/ExampleMap/7/UM/P713255HQHP0RVRQ5S9OSS.uasset create mode 100644 Source/FunnyPrince/FighterAIController.cpp create mode 100644 Source/FunnyPrince/FighterAIController.h create mode 100644 Source/FunnyPrince/FunnyPrinceController.cpp create mode 100644 Source/FunnyPrince/FunnyPrinceController.h diff --git a/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/0/W3/BH9RA5CXGG4V6NBO45LIOY.uasset b/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/0/W3/BH9RA5CXGG4V6NBO45LIOY.uasset index f31026e..a9290bf 100644 --- a/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/0/W3/BH9RA5CXGG4V6NBO45LIOY.uasset +++ b/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/0/W3/BH9RA5CXGG4V6NBO45LIOY.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8699b8e9f3b3df26e1d91a9d389beeff586a609b8b588520319dde7fe55012d8 +oid sha256:771cd89a7d5192d4c517d2a0ee70c1a875141c12d781e3797cd942c37968616c size 4498 diff --git a/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/2/YS/0MUVLSZG6FOQLXF4C5BDRV.uasset b/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/2/YS/0MUVLSZG6FOQLXF4C5BDRV.uasset index fd3ba2c..95eb033 100644 --- a/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/2/YS/0MUVLSZG6FOQLXF4C5BDRV.uasset +++ b/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/2/YS/0MUVLSZG6FOQLXF4C5BDRV.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37752814a22df1e5d469618d6679444a4b0eee5f572113ba63fcbd4b4372c445 -size 7761 +oid sha256:a9c02836f05f9dd707881070f9f2f1da9133fb8bba701baaf1d3a56669a1252b +size 8316 diff --git a/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/3/YJ/OD1NN2YHEXD84Z0IQ2F2Z8.uasset b/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/3/YJ/OD1NN2YHEXD84Z0IQ2F2Z8.uasset deleted file mode 100644 index 7a1b669..0000000 --- a/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/3/YJ/OD1NN2YHEXD84Z0IQ2F2Z8.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a361b255a619894179cb24bd608269b7916ff78d76db39bb9d11ad12208267ea -size 3991 diff --git a/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/7/UM/P713255HQHP0RVRQ5S9OSS.uasset b/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/7/UM/P713255HQHP0RVRQ5S9OSS.uasset new file mode 100644 index 0000000..00ea084 --- /dev/null +++ b/Content/__ExternalActors__/SideScroller/Maps/ExampleMap/7/UM/P713255HQHP0RVRQ5S9OSS.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b197688de87c31b268fdcf038e439b3f2843919aeaeeec4d553b214c91e60e6c +size 8404 diff --git a/FunnyPrince.uproject b/FunnyPrince.uproject index a271194..142686c 100644 --- a/FunnyPrince.uproject +++ b/FunnyPrince.uproject @@ -9,7 +9,9 @@ "Type": "Runtime", "LoadingPhase": "Default", "AdditionalDependencies": [ - "SST" + "SST", + "AIModule", + "Engine" ] } ], diff --git a/Source/FunnyPrince/FighterAIController.cpp b/Source/FunnyPrince/FighterAIController.cpp new file mode 100644 index 0000000..dc33249 --- /dev/null +++ b/Source/FunnyPrince/FighterAIController.cpp @@ -0,0 +1,36 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "FighterAIController.h" + +#include "FunnyPrinceCharacter.h" +#include "BehaviorTree/BlackboardComponent.h" +#include "Kismet/GameplayStatics.h" + +void AFighterAIController::BeginPlay() +{ + Super::BeginPlay(); + + if (AIBehavior) + { + RunBehaviorTree(AIBehavior); + + GetBlackboardComponent()->SetValueAsVector(TEXT("StartLocation"), GetPawn()->GetActorLocation()); + } +} + +void AFighterAIController::Tick(float DeltaSeconds) +{ + Super::Tick(DeltaSeconds); +} + +bool AFighterAIController::IsDead() const +{ + AFunnyPrinceCharacter* ControlledCharacter = Cast(GetPawn()); + if (ControlledCharacter) + { + return ControlledCharacter->IsDead(); + } + + return true; +} diff --git a/Source/FunnyPrince/FighterAIController.h b/Source/FunnyPrince/FighterAIController.h new file mode 100644 index 0000000..ab8a718 --- /dev/null +++ b/Source/FunnyPrince/FighterAIController.h @@ -0,0 +1,28 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "AIController.h" +#include "FighterAIController.generated.h" + +/** + * + */ +UCLASS() +class FUNNYPRINCE_API AFighterAIController : public AAIController +{ + GENERATED_BODY() + +public: + virtual void Tick(float DeltaSeconds) override; + + bool IsDead() const; + +protected: + virtual void BeginPlay() override; + +private: + UPROPERTY(EditAnywhere) + class UBehaviorTree* AIBehavior; +}; diff --git a/Source/FunnyPrince/FunnyPrince.Build.cs b/Source/FunnyPrince/FunnyPrince.Build.cs index b9bef3c..938b09f 100644 --- a/Source/FunnyPrince/FunnyPrince.Build.cs +++ b/Source/FunnyPrince/FunnyPrince.Build.cs @@ -8,6 +8,6 @@ public class FunnyPrince : ModuleRules { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; - PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput" }); + PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "UMG" }); } } diff --git a/Source/FunnyPrince/FunnyPrinceCharacter.cpp b/Source/FunnyPrince/FunnyPrinceCharacter.cpp index b06683c..8e1e25d 100644 --- a/Source/FunnyPrince/FunnyPrinceCharacter.cpp +++ b/Source/FunnyPrince/FunnyPrinceCharacter.cpp @@ -8,6 +8,8 @@ #include "EnhancedInputComponent.h" #include "Engine/DamageEvents.h" #include "EnemyCharacter.h" +#include "FunnyPrinceGameMode.h" +#include "Components/CapsuleComponent.h" DEFINE_LOG_CATEGORY(LogTemplateFunnyPrinceCharacter); @@ -46,6 +48,8 @@ void AFunnyPrinceCharacter::BeginPlay() { // Call the base class Super::BeginPlay(); + + Health = MaxHealth; } @@ -84,14 +88,15 @@ float AFunnyPrinceCharacter::TakeDamage(float DamageAmount, FDamageEvent const& { Health = 0; - /*ASimpleShooterGameModeBase* GameMode = GetWorld()->GetAuthGameMode(); + AFunnyPrinceGameMode* GameMode = GetWorld()->GetAuthGameMode(); if (GameMode) { GameMode->PawnKilled(this); } DetachFromControllerPendingDestroy(); - GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);*/ + GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision); + SetLifeSpan(0.f); } UE_LOG(LogTemp, Warning, TEXT("Actor hit for %f damage. Current HP: %f"), DamageToApply, Health); diff --git a/Source/FunnyPrince/FunnyPrinceCharacter.h b/Source/FunnyPrince/FunnyPrinceCharacter.h index aa26bec..dc439e3 100644 --- a/Source/FunnyPrince/FunnyPrinceCharacter.h +++ b/Source/FunnyPrince/FunnyPrinceCharacter.h @@ -29,6 +29,9 @@ public: // To add mapping context virtual void Tick(float DeltaTime) override; + UFUNCTION(BlueprintPure) + bool IsDead() const; + protected: // To add mapping context @@ -36,9 +39,6 @@ protected: virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser) override; - UFUNCTION(BlueprintPure) - bool IsDead() const; - UFUNCTION(BlueprintPure) float GetHealthPercent() const; diff --git a/Source/FunnyPrince/FunnyPrinceController.cpp b/Source/FunnyPrince/FunnyPrinceController.cpp new file mode 100644 index 0000000..bdae8df --- /dev/null +++ b/Source/FunnyPrince/FunnyPrinceController.cpp @@ -0,0 +1,41 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "FunnyPrinceController.h" +#include "Blueprint/UserWidget.h" + +void AFunnyPrinceController::BeginPlay() +{ + Super::BeginPlay(); + + HUD = CreateWidget(this, HUDClass); + if (HUD != nullptr) + { + HUD->AddToViewport(); + } +} + +void AFunnyPrinceController::GameHasEnded(AActor* EndGameFocus, bool bIsWinner) +{ + Super::GameHasEnded(EndGameFocus, bIsWinner); + HUD->RemoveFromParent(); + + if (bIsWinner) + { + UUserWidget* WinScreen = CreateWidget(this, WinScreenClass); + if (WinScreen != nullptr) + { + WinScreen->AddToViewport(); + } + } + else + { + UUserWidget* LoseScreen = CreateWidget(this, LoseScreenClass); + if (LoseScreen != nullptr) + { + LoseScreen->AddToViewport(); + } + } + + GetWorldTimerManager().SetTimer(RestartTimer, this, &APlayerController::RestartLevel, RestartDelay); +} diff --git a/Source/FunnyPrince/FunnyPrinceController.h b/Source/FunnyPrince/FunnyPrinceController.h new file mode 100644 index 0000000..22cac84 --- /dev/null +++ b/Source/FunnyPrince/FunnyPrinceController.h @@ -0,0 +1,42 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/PlayerController.h" +#include "Blueprint/UserWidget.h" + +#include "FunnyPrinceController.generated.h" + +class UUserWidget; +/** + * + */ +UCLASS() +class FUNNYPRINCE_API AFunnyPrinceController : public APlayerController +{ + GENERATED_BODY() + +public: + virtual void BeginPlay() override; + virtual void GameHasEnded(class AActor* EndGameFocus = nullptr, bool bIsWinner = false) override; + +private: + + UPROPERTY(EditAnywhere) + TSubclassOf HUDClass; + + UPROPERTY(EditAnywhere) + TSubclassOf WinScreenClass; + + UPROPERTY(EditAnywhere) + TSubclassOf LoseScreenClass; + + UPROPERTY(EditAnywhere) + float RestartDelay = 5; + + FTimerHandle RestartTimer; + + UPROPERTY() + UUserWidget* HUD; +}; diff --git a/Source/FunnyPrince/FunnyPrinceGameMode.cpp b/Source/FunnyPrince/FunnyPrinceGameMode.cpp index 7a23b84..f71e72f 100644 --- a/Source/FunnyPrince/FunnyPrinceGameMode.cpp +++ b/Source/FunnyPrince/FunnyPrinceGameMode.cpp @@ -2,8 +2,45 @@ #include "FunnyPrinceGameMode.h" #include "UObject/ConstructorHelpers.h" +#include "EngineUtils.h" +#include "FighterAIController.h" AFunnyPrinceGameMode::AFunnyPrinceGameMode() { } + +void AFunnyPrinceGameMode::PawnKilled(APawn* PawnKilled) +{ + if (!PawnKilled) + { + return; + } + + APlayerController* PlayerController = Cast(PawnKilled->GetController()); + if (PlayerController) + { + PlayerController->GameHasEnded(nullptr, false); + } + + // Check for win condition + for (AFighterAIController* Controller : TActorRange(GetWorld())) + { + if (!Controller->IsDead()) + { + return; + } + } + + // All AI is dead, game is won + EndGame(true); +} + +void AFunnyPrinceGameMode::EndGame(bool bIsPlayerWinner) +{ + for (AController* Controller : TActorRange(GetWorld())) + { + bool bWon = (bIsPlayerWinner == Controller->IsPlayerController()); + Controller->GameHasEnded(Controller->GetPawn(), bWon); + } +} diff --git a/Source/FunnyPrince/FunnyPrinceGameMode.h b/Source/FunnyPrince/FunnyPrinceGameMode.h index 2660a7e..87b43bc 100644 --- a/Source/FunnyPrince/FunnyPrinceGameMode.h +++ b/Source/FunnyPrince/FunnyPrinceGameMode.h @@ -13,6 +13,9 @@ class AFunnyPrinceGameMode : public AGameModeBase public: AFunnyPrinceGameMode(); + + virtual void PawnKilled(APawn* PawnKilled); + void EndGame(bool bIsPlayerWinner); };