Merge some UI improvements #8

Merged
eyakm1 merged 7 commits from feature-ui-improvements into dev 2 years ago

@ -1,7 +1,10 @@
[/Script/EngineSettings.GeneralProjectSettings] [/Script/EngineSettings.GeneralProjectSettings]
ProjectID=D68B8A08410D0195272328B9EAD1AE41 ProjectID=D68B8A08410D0195272328B9EAD1AE41
bShouldWindowPreserveAspectRatio=False
bUseBorderlessWindow=False
[StartupActions] [StartupActions]
bAddPacks=True bAddPacks=True
InsertPack=(PackSource="StarterContent.upack",PackName="StarterContent") InsertPack=(PackSource="StarterContent.upack",PackName="StarterContent")

@ -19,6 +19,7 @@ ABattleGameMode::ABattleGameMode()
void ABattleGameMode::BeginPlay() { void ABattleGameMode::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
// UGameplayStatics::PlaySound2D(GetWorld(), BackgroundSound);
} }
auto ABattleGameMode::GetMyGameState() const { auto ABattleGameMode::GetMyGameState() const {
@ -34,10 +35,10 @@ void ABattleGameMode::InitializeBattleField_Implementation() {
uint8 TrooperCount = 0; uint8 TrooperCount = 0;
TArray<const TCHAR *> bpPaths{ TArray<const TCHAR *> bpPaths{
TEXT("Blueprint'/Game/Troopers/TrooperWizard.TrooperWizard_C'"),
TEXT( TEXT(
"Blueprint'/Game/Troopers/TrooperSkeletonMelee.TrooperSkeletonMelee_C'" "Blueprint'/Game/Troopers/TrooperSkeletonMelee.TrooperSkeletonMelee_C'"
), )
TEXT("Blueprint'/Game/Troopers/TrooperWizard.TrooperWizard_C'")
}; };
// TArray<UClass *> LoadedBpAssets; // TArray<UClass *> LoadedBpAssets;
for (int i = 0; i < bpPaths.Num(); ++i) { for (int i = 0; i < bpPaths.Num(); ++i) {
@ -51,7 +52,7 @@ void ABattleGameMode::InitializeBattleField_Implementation() {
FTransform SpawnLocationAndRotation(Rotation); FTransform SpawnLocationAndRotation(Rotation);
SpawnLocationAndRotation.SetLocation(Location); SpawnLocationAndRotation.SetLocation(Location);
AActor *Spawned = GetWorld()->SpawnActorDeferred<ATrooper>( AActor *Spawned = GetWorld()->SpawnActorDeferred<ATrooper>(
LoadedBpAssets[i % 2], SpawnLocationAndRotation); LoadedBpAssets[FirstPlayerTrooperKinds[i]], SpawnLocationAndRotation);
// AActor *Spawned = GetWorld()->SpawnActorDeferred<ATrooper>( // AActor *Spawned = GetWorld()->SpawnActorDeferred<ATrooper>(
// ATrooper::StaticClass(), SpawnLocationAndRotation); // ATrooper::StaticClass(), SpawnLocationAndRotation);
Cast<ATrooper>(Spawned)->Initialize( Cast<ATrooper>(Spawned)->Initialize(
@ -68,7 +69,7 @@ void ABattleGameMode::InitializeBattleField_Implementation() {
FTransform SpawnLocationAndRotation(Rotation); FTransform SpawnLocationAndRotation(Rotation);
SpawnLocationAndRotation.SetLocation(Location); SpawnLocationAndRotation.SetLocation(Location);
AActor *Spawned = GetWorld()->SpawnActorDeferred<ATrooper>( AActor *Spawned = GetWorld()->SpawnActorDeferred<ATrooper>(
LoadedBpAssets[i % 2], SpawnLocationAndRotation); LoadedBpAssets[SecondPlayerTrooperKinds[i]], SpawnLocationAndRotation);
// AActor *Spawned = GetWorld()->SpawnActorDeferred<ATrooper>( // AActor *Spawned = GetWorld()->SpawnActorDeferred<ATrooper>(
// ATrooper::StaticClass(), SpawnLocationAndRotation); // ATrooper::StaticClass(), SpawnLocationAndRotation);
Cast<ATrooper>(Spawned)->Initialize( Cast<ATrooper>(Spawned)->Initialize(
@ -78,11 +79,6 @@ void ABattleGameMode::InitializeBattleField_Implementation() {
GetMyGameState()->AddTrooper(Cast<ATrooper>(Spawned)); GetMyGameState()->AddTrooper(Cast<ATrooper>(Spawned));
Location += {0.f, 500.f, 0.0f}; Location += {0.f, 500.f, 0.0f};
} }
} else {
// Cast<ASinglePlayerGS>(GetMyGameState())->GetEnemyAIController()->
// SetTrooperAssetsAndSpawn(
// LoadedBpAssets,
// TrooperCount);
} }
} }
@ -137,8 +133,19 @@ void ABattleGameMode::PostLogin(APlayerController *NewPlayer) {
// 0-indexation // 0-indexation
Cast<ABattlePlayerController>(NewPlayer)->SetPlayerIndex( Cast<ABattlePlayerController>(NewPlayer)->SetPlayerIndex(
CurrentNumberOfPlayers - 1); CurrentNumberOfPlayers - 1);
Cast<ABattlePlayerController>(NewPlayer)->
StartPlayingMusic(BackgroundSound);
if (CurrentNumberOfPlayers == 1)
{
FirstPlayerTrooperKinds = Cast<ABattlePlayerController>(NewPlayer)->TrooperKinds;
} else if (CurrentNumberOfPlayers == 2)
{
SecondPlayerTrooperKinds = Cast<ABattlePlayerController>(NewPlayer)->TrooperKinds;
}
UE_LOG(LogTemp, Warning, TEXT("%d"), CurrentNumberOfPlayers); UE_LOG(LogTemp, Warning, TEXT("%d"), CurrentNumberOfPlayers);
if (CurrentNumberOfPlayers == 2) { if (!bIsMultiplayer || CurrentNumberOfPlayers == 2) {
UE_LOG(LogTemp, Warning, TEXT("Game Start")); UE_LOG(LogTemp, Warning, TEXT("Game Start"));
// start the game // start the game
// dynamic_cast<AMyGameState *>( // dynamic_cast<AMyGameState *>(

@ -27,12 +27,21 @@ public:
// void CycleTurns(); // void CycleTurns();
protected: protected:
UPROPERTY(BlueprintReadWrite, EditAnywhere)
USoundBase *BackgroundSound;
UPROPERTY() UPROPERTY()
TArray<UClass *> LoadedBpAssets; TArray<UClass *> LoadedBpAssets;
UPROPERTY() UPROPERTY()
bool bIsMultiplayer = true; bool bIsMultiplayer = true;
UPROPERTY()
TArray<uint8> FirstPlayerTrooperKinds;
UPROPERTY()
TArray<uint8> SecondPlayerTrooperKinds;
void InitializeSpawnPointsIfNeeded(AController *Player); void InitializeSpawnPointsIfNeeded(AController *Player);
UFUNCTION(Server, Reliable) UFUNCTION(Server, Reliable)

@ -7,19 +7,27 @@
#include "BattlePlayerState.h" #include "BattlePlayerState.h"
#include "Blueprint/UserWidget.h" #include "Blueprint/UserWidget.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#include "TurnBasedTutorial/ManageSquad/SelectedTrooperSaveGame.h"
ABattlePlayerController::ABattlePlayerController() ABattlePlayerController::ABattlePlayerController()
: Super()/*, bIsMyTurn(false), SelectedTrooper(nullptr)*/ { : Super()/*, bIsMyTurn(false), SelectedTrooper(nullptr)*/ {
UE_LOG(LogTemp, Warning, TEXT("Player controller created")); UE_LOG(LogTemp, Warning, TEXT("Player controller created"));
SetShowMouseCursor(true); SetShowMouseCursor(true);
PlayerIndex = 0; PlayerIndex = 0;
if (UGameplayStatics::DoesSaveGameExist("Selected troopers", 0)) {
const USelectedTrooperSaveGame *SaveGameInstance = Cast<
USelectedTrooperSaveGame>(
UGameplayStatics::LoadGameFromSlot(TEXT("Selected troopers"), 0));
TrooperKinds = SaveGameInstance->SelectedTroopers;
} else {
TrooperKinds = {0, 0, 0, 0, 0};
}
} }
void ABattlePlayerController::BeginPlay() { void ABattlePlayerController::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
UUserWidget *CreatedWidget = CreateWidget<UUserWidget>( CreateBattleWidget();
GetWorld(), WidgetClass);
CreatedWidget->AddToViewport();
} }
void ABattlePlayerController::SetupInputComponent() { void ABattlePlayerController::SetupInputComponent() {
@ -64,8 +72,9 @@ void ABattlePlayerController::EndTurn_Implementation() {
// GetMyGameState()->CycleTurns(); // GetMyGameState()->CycleTurns();
// } // }
// GetMyPlayerState()->CycleTurns(); // GetMyPlayerState()->CycleTurns();
if (GetMyGameState()->IsInTurn(PlayerIndex)) if (GetMyGameState()->IsInTurn(PlayerIndex)) {
GetMyGameState()->CycleTurns(); GetMyGameState()->CycleTurns();
}
} }
// void AMyPlayerController::EndTurn_Implementation() { // void AMyPlayerController::EndTurn_Implementation() {
@ -147,6 +156,25 @@ uint8 ABattlePlayerController::GetPlayerIndex() const {
return PlayerIndex; return PlayerIndex;
} }
void ABattlePlayerController::CreateBattleWidget_Implementation() {
BattleWidget = CreateWidget<UBattleUI>(
GetWorld(), WidgetClass);
BattleWidget->AddToViewport();
// GetPlayerState<ABattlePlayerState>()->SetBattleWidget(BattleWidget);
}
void ABattlePlayerController::SetWidgetTurn_Implementation(bool bIsMyTurn) {
if (BattleWidget) {
BattleWidget->SetWhoseTurnText(bIsMyTurn);
}
}
void ABattlePlayerController::StartPlayingMusic_Implementation(
USoundBase *BackgroundSound) const {
UGameplayStatics::PlaySound2D(GetWorld(), BackgroundSound, 0.25f);
}
// float AMyPlayerController::SetCurrentActionAndReturnRadius(int action) { // float AMyPlayerController::SetCurrentActionAndReturnRadius(int action) {
// return GetMyPlayerState()->SetCurrentActionAndReturnRadius(action); // return GetMyPlayerState()->SetCurrentActionAndReturnRadius(action);
// //

@ -2,6 +2,7 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "BattleUI.h"
#include "GameFramework/PlayerController.h" #include "GameFramework/PlayerController.h"
#include "BattlePlayerController.generated.h" #include "BattlePlayerController.generated.h"
@ -50,7 +51,22 @@ public:
// UFUNCTION(Client, Reliable) // UFUNCTION(Client, Reliable)
// void SetEnemySelection(const TArray<ATrooper *> &Troopers) const; // void SetEnemySelection(const TArray<ATrooper *> &Troopers) const;
UFUNCTION(Client, Reliable)
void StartPlayingMusic(USoundBase *BackgroundSound) const;
UFUNCTION(Client, Reliable)
void SetWidgetTurn(bool bIsMyTurn);
UPROPERTY()
TArray<uint8> TrooperKinds;
private: private:
UFUNCTION(Client, Reliable)
void CreateBattleWidget();
UPROPERTY()
UBattleUI *BattleWidget;
UPROPERTY(EditAnywhere) UPROPERTY(EditAnywhere)
TSubclassOf<UUserWidget> WidgetClass; TSubclassOf<UUserWidget> WidgetClass;

@ -39,6 +39,11 @@ void ABattlePlayerState::SetPlayerIndex(uint8 NewPlayerIndex) {
PlayerIndex = NewPlayerIndex; PlayerIndex = NewPlayerIndex;
} }
// void ABattlePlayerState::
// SetBattleWidget_Implementation(UBattleUI *BattleWidget) {
// BattleUI = BattleWidget;
// }
void ABattlePlayerState::GameOver_Implementation(int PlayerLoseIndex) { void ABattlePlayerState::GameOver_Implementation(int PlayerLoseIndex) {
UGameOverWidget *CreatedWidget = CreateWidget<UGameOverWidget>( UGameOverWidget *CreatedWidget = CreateWidget<UGameOverWidget>(
GetWorld(), GameOverWidgetClass); GetWorld(), GameOverWidgetClass);
@ -61,7 +66,7 @@ void ABattlePlayerState::SetEnemySelection_Implementation(
} }
void ABattlePlayerState::MoveTrooper_Implementation(ATrooper *Trooper, void ABattlePlayerState::MoveTrooper_Implementation(ATrooper *Trooper,
FVector Location) { FVector Location) {
Location.Z = 0.0f; Location.Z = 0.0f;
if (Trooper->CheckMoveCorrectness(Location)) { if (Trooper->CheckMoveCorrectness(Location)) {
Trooper->MoveTrooper(Location); Trooper->MoveTrooper(Location);
@ -87,8 +92,8 @@ void ABattlePlayerState::MoveTrooper_Implementation(ATrooper *Trooper,
// } // }
void ABattlePlayerState::Attack_Implementation(ATrooper *Attacker, void ABattlePlayerState::Attack_Implementation(ATrooper *Attacker,
FVector Location, FVector Location,
int ActionIndex) { int ActionIndex) {
if (Attacker->CheckAttackCorrectness(Location, ActionIndex)) { if (Attacker->CheckAttackCorrectness(Location, ActionIndex)) {
Attacker->Attack(ActionIndex, Location); Attacker->Attack(ActionIndex, Location);
// for (const auto Trooper : Troopers) { // for (const auto Trooper : Troopers) {
@ -116,12 +121,14 @@ bool ABattlePlayerState::IsMyTurn() const {
void ABattlePlayerState::SetMyTurn(bool bMyTurn) { void ABattlePlayerState::SetMyTurn(bool bMyTurn) {
bIsMyTurn = bMyTurn; bIsMyTurn = bMyTurn;
if (bIsMyTurn) { Cast<ABattlePlayerController>(GetWorld()->GetFirstPlayerController())->
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, SetWidgetTurn(bIsMyTurn);
FString::Printf( // if (bIsMyTurn) {
TEXT("CURRENT TURN: %d"), // GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green,
PlayerIndex)); // FString::Printf(
} // TEXT("CURRENT TURN: %d"),
// PlayerIndex));
// }
} }
void ABattlePlayerState::StartTurn_Implementation() { void ABattlePlayerState::StartTurn_Implementation() {
@ -139,6 +146,7 @@ void ABattlePlayerState::EndTurn_Implementation() {
SelectedTrooper = nullptr; SelectedTrooper = nullptr;
} }
UE_LOG(LogTemp, Warning, TEXT("Not your turn, %d"), PlayerIndex); UE_LOG(LogTemp, Warning, TEXT("Not your turn, %d"), PlayerIndex);
// AMyGameMode *gameMode = GetMyGameMode(); // AMyGameMode *gameMode = GetMyGameMode();
// gameMode->CycleTurns(); // gameMode->CycleTurns();
// Cast<AMyGameState>(GetWorld()->GetGameState())->CycleTurns(); // Cast<AMyGameState>(GetWorld()->GetGameState())->CycleTurns();
@ -156,8 +164,9 @@ void ABattlePlayerState::OnPlayerAction(const FHitResult &HitResult) {
return; return;
} }
if (NewlySelectedTrooper == nullptr || !NewlySelectedTrooper-> if (HitResult.GetActor()->ActorHasTag(FName("Floor")) ||
IsValidLowLevel() || NewlySelectedTrooper->GetPlayerIndex() != NewlySelectedTrooper != nullptr &&
NewlySelectedTrooper->GetPlayerIndex() !=
PlayerIndex) { PlayerIndex) {
if (SelectedTrooper != nullptr && SelectedTrooper-> if (SelectedTrooper != nullptr && SelectedTrooper->
IsValidLowLevel()) { IsValidLowLevel()) {

@ -4,6 +4,7 @@
#include "Trooper/Trooper.h" #include "Trooper/Trooper.h"
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "BattlePlayerController.h"
#include "GameFramework/PlayerState.h" #include "GameFramework/PlayerState.h"
#include "BattlePlayerState.generated.h" #include "BattlePlayerState.generated.h"
@ -58,8 +59,14 @@ public:
UFUNCTION(Client, Reliable) UFUNCTION(Client, Reliable)
void GameOver(int PlayerLoseIndex); void GameOver(int PlayerLoseIndex);
// UFUNCTION(Client, Reliable)
// void SetBattleWidget(UBattleUI *BattleWidget);
protected: protected:
// UPROPERTY()
// UBattleUI *BattleUI;
UPROPERTY(EditAnywhere, BlueprintReadWrite) UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<UUserWidget> GameOverWidgetClass; TSubclassOf<UUserWidget> GameOverWidgetClass;

@ -0,0 +1,63 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "BattleUI.h"
#include "Components/Button.h"
#include "Components/TextBlock.h"
#include "BattlePlayerController.h"
#include "BattlePlayerState.h"
void UBattleUI::NativeConstruct() {
Super::NativeConstruct();
EndTurnButton->OnClicked.AddDynamic(this, &ThisClass::OnEndTurnClicked);
ButtonAction_0->OnClicked.AddDynamic(this, &ThisClass::OnActionSwitched_0);
ButtonAction_1->OnClicked.AddDynamic(this, &ThisClass::OnActionSwitched_1);
ButtonAction_2->OnClicked.AddDynamic(this, &ThisClass::OnActionSwitched_2);
}
void UBattleUI::SetWidgetText_Implementation(const FString &Text) {
InformationText->SetText(FText::FromString(Text));
}
void UBattleUI::SetWhoseTurnText_Implementation(bool IsThisPlayerTurn) {
if (IsThisPlayerTurn) {
SetWidgetText(TEXT("Your turn!"));
} else {
SetWidgetText(TEXT("Opponent's turn"));
}
}
void UBattleUI::OnEndTurnClicked() {
Cast<ABattlePlayerController>(GetWorld()->GetFirstPlayerController())->
EndTurn();
}
void UBattleUI::OnActionSwitched_0() {
ButtonAction_0->SetIsEnabled(false);
ButtonAction_1->SetIsEnabled(true);
ButtonAction_2->SetIsEnabled(true);
ActionType = 0;
OnActionSwitched();
}
void UBattleUI::OnActionSwitched_1() {
ButtonAction_0->SetIsEnabled(true);
ButtonAction_1->SetIsEnabled(false);
ButtonAction_2->SetIsEnabled(true);
ActionType = 1;
OnActionSwitched();
}
void UBattleUI::OnActionSwitched_2() {
ButtonAction_0->SetIsEnabled(true);
ButtonAction_1->SetIsEnabled(true);
ButtonAction_2->SetIsEnabled(false);
ActionType = 2;
OnActionSwitched();
}
void UBattleUI::OnActionSwitched() const {
Cast<ABattlePlayerController>(GetWorld()->GetFirstPlayerController())->
GetPlayerState<ABattlePlayerState>()->SetCurrentAction(ActionType);
}

@ -0,0 +1,58 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "BattleUI.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API UBattleUI : public UUserWidget {
GENERATED_BODY()
public:
virtual void NativeConstruct() override;
UFUNCTION(Client, Reliable)
void SetWhoseTurnText(bool IsThisPlayerTurn);
UFUNCTION(Client, Reliable)
void SetWidgetText(const FString &Text);
protected:
int ActionType = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UButton *EndTurnButton;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UButton *ButtonAction_0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UButton *ButtonAction_1;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UButton *ButtonAction_2;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UTextBlock *InformationText;
UFUNCTION()
void OnEndTurnClicked();
UFUNCTION()
void OnActionSwitched_0();
UFUNCTION()
void OnActionSwitched_1();
UFUNCTION()
void OnActionSwitched_2();
UFUNCTION()
void OnActionSwitched() const;
};

@ -2,6 +2,7 @@
#include "SinglePlayerGM.h" #include "SinglePlayerGM.h"
#include "SinglePlayerGS.h" #include "SinglePlayerGS.h"
#include "TurnBasedTutorial/BattleMode/BattlePlayerController.h"
ASinglePlayerGM::ASinglePlayerGM() ASinglePlayerGM::ASinglePlayerGM()
: Super() { : Super() {
@ -12,10 +13,12 @@ ASinglePlayerGM::ASinglePlayerGM()
void ASinglePlayerGM::BeginPlay() { void ASinglePlayerGM::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
UE_LOG(LogTemp, Warning, TEXT("SinglePlayer GameMode BeginPlay")); UE_LOG(LogTemp, Warning, TEXT("SinglePlayer GameMode BeginPlay"));
GameStateClass = ASinglePlayerGS::StaticClass(); // GameStateClass = ASinglePlayerGS::StaticClass();
StartGame(); // StartGame();
} }
void ASinglePlayerGM::PostLogin(APlayerController *NewPlayer) { // void ASinglePlayerGM::PostLogin(APlayerController *NewPlayer) {
AGameMode::PostLogin(NewPlayer); // AGameMode::PostLogin(NewPlayer);
} // Cast<ABattlePlayerController>(NewPlayer)->
// StartPlayingMusic(BackgroundSound);
// }

@ -18,5 +18,5 @@ public:
virtual void BeginPlay() override; virtual void BeginPlay() override;
virtual void PostLogin(APlayerController *NewPlayer) override; // virtual void PostLogin(APlayerController *NewPlayer) override;
}; };

@ -42,8 +42,8 @@ AProjectile::AProjectile() {
} }
void AProjectile::Initialize(const UAbility *Ability, void AProjectile::Initialize(const UAbility *Ability,
uint8 playerIndex, uint8 playerIndex,
float PathLength) { float PathLength) {
ProjectileMovementComponent->InitialSpeed = ProjectileMovementComponent->InitialSpeed =
ProjectileMovementComponent->MaxSpeed = Ability->Speed; ProjectileMovementComponent->MaxSpeed = Ability->Speed;
Damage = Ability->Damage; Damage = Ability->Damage;
@ -69,9 +69,16 @@ void AProjectile::NotifyActorBeginOverlap(AActor *OtherActor) {
), ),
OtherTrooper->GetId(), OtherTrooper->GetPlayerIndex(), Damage, OtherTrooper->GetId(), OtherTrooper->GetPlayerIndex(), Damage,
PlayerIndex); PlayerIndex);
if (PlayerIndex != -1 && PlayerIndex != OtherTrooper-> if (Damage > 0) {
GetPlayerIndex()) { if (PlayerIndex != -1 && PlayerIndex != OtherTrooper->
OtherTrooper->TrooperTakeDamage(Damage); GetPlayerIndex()) {
OtherTrooper->TrooperTakeDamage(Damage);
}
} else {
if (PlayerIndex != -1 && PlayerIndex == OtherTrooper->
GetPlayerIndex()) {
OtherTrooper->TrooperTakeDamage(Damage);
}
} }
} else { } else {
UE_LOG(LogTemp, Warning, TEXT("Overlapped not a trooper")); UE_LOG(LogTemp, Warning, TEXT("Overlapped not a trooper"));

@ -308,15 +308,20 @@ void ATrooper::TrooperTakeDamage_Implementation(float Damage) {
if (bIsTakingDamage || bIsDead) { if (bIsTakingDamage || bIsDead) {
return; return;
} }
HitPoints = FMath::Max<float>(0, HitPoints - Damage); if (Damage > 0) {
if (HitPoints == 0) { HitPoints = FMath::Max<float>(0, HitPoints - Damage);
bIsDead = true; if (HitPoints == 0) {
SetLifeSpan(DyingAnimationDuration); bIsDead = true;
GetWorld()->GetGameState<ABattleGameState>()->DecreaseLivingTroopers( SetLifeSpan(DyingAnimationDuration);
PlayerIndex); GetWorld()->GetGameState<ABattleGameState>()->
DecreaseLivingTroopers(
PlayerIndex);
} else {
// bIsTakingDamage = true;
SetIsTakingDamage(true);
}
} else { } else {
// bIsTakingDamage = true; HitPoints = FMath::Min<float>(StartHitPoints, HitPoints - Damage);
SetIsTakingDamage(true);
} }
} }

@ -12,18 +12,19 @@ void UMainMenuWidget::NativeConstruct() {
this, &ThisClass::UMainMenuWidget::OnHostOnlineGameButtonClicked); this, &ThisClass::UMainMenuWidget::OnHostOnlineGameButtonClicked);
GetMyGameSubsystem()->OnCreateSessionCompleteEvent.AddDynamic( GetMyGameSubsystem()->OnCreateSessionCompleteEvent.AddDynamic(
this, &ThisClass::StartSessionWhenCreatingSessonComplete); this, &ThisClass::StartSessionWhenCreatingSessionComplete);
} }
void UMainMenuWidget::OnHostOnlineGameButtonClicked() { void UMainMenuWidget::OnHostOnlineGameButtonClicked() {
// Ensure we have left any session // Ensure we have left any session
GetMyGameSubsystem()->DestroySession(); GetMyGameSubsystem()->DestroySession();
GetMyGameSubsystem()->CreateSession( const FString SessionName = "Lobby " + FString::FromInt(
"Lobby " + FString::FromInt(FMath::RandRange(1, 1e6)), 2, true); FMath::RandRange(1, 1e6));
GetMyGameSubsystem()->CreateSession(SessionName, 2, true);
} }
void UMainMenuWidget::StartSessionWhenCreatingSessonComplete(bool bSuccess) { void UMainMenuWidget::StartSessionWhenCreatingSessionComplete(bool bSuccess) {
if (!bSuccess) { if (!bSuccess) {
return; return;
} }

@ -26,7 +26,7 @@ protected:
void OnHostOnlineGameButtonClicked(); void OnHostOnlineGameButtonClicked();
UFUNCTION() UFUNCTION()
void StartSessionWhenCreatingSessonComplete(bool bSuccess); void StartSessionWhenCreatingSessionComplete(bool bSuccess);
private: private:
USessionsGameInstanceSubsystem *GetMyGameSubsystem() const; USessionsGameInstanceSubsystem *GetMyGameSubsystem() const;

@ -4,10 +4,18 @@
#include "SessionListEntryWidget.h" #include "SessionListEntryWidget.h"
#include "OnlineSessionSettings.h" #include "OnlineSessionSettings.h"
#include "Components/TextBlock.h" #include "Components/TextBlock.h"
#include "Components/Button.h"
#include "Kismet/GameplayStatics.h"
void USessionListEntryWidget::NativeConstruct() {
Super::NativeConstruct();
JoinSessionButton->OnClicked.AddDynamic(
this, &ThisClass::OnJoinButton);
}
void USessionListEntryWidget::Update(int SessionIndex, void USessionListEntryWidget::Update(int SessionIndex,
const FOnlineSessionSearchResult & const FOnlineSessionSearchResult &
Session) { Session) {
SessionId = SessionIndex; SessionId = SessionIndex;
IndexText->SetText(FText::AsNumber(SessionIndex + 1)); IndexText->SetText(FText::AsNumber(SessionIndex + 1));
@ -22,3 +30,16 @@ void USessionListEntryWidget::Update(int SessionIndex,
PlayersCountText->SetText(FText::AsNumber(CurPlayerCount)); PlayersCountText->SetText(FText::AsNumber(CurPlayerCount));
PingText->SetText(FText::AsNumber(Session.PingInMs)); PingText->SetText(FText::AsNumber(Session.PingInMs));
} }
void USessionListEntryWidget::OnJoinButton() {
GetMyGameSubsystem()->JoinSession(SessionId);
}
USessionsGameInstanceSubsystem *
USessionListEntryWidget::GetMyGameSubsystem() const {
const UGameInstance *GameInstance = UGameplayStatics::GetGameInstance(
GetWorld());
USessionsGameInstanceSubsystem *GameInstanceSubsystem = GameInstance->
GetSubsystem<USessionsGameInstanceSubsystem>();
return GameInstanceSubsystem;
}

@ -3,6 +3,7 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "../SessionsGameInstanceSubsystem.h"
#include "Blueprint/UserWidget.h" #include "Blueprint/UserWidget.h"
#include "SessionListEntryWidget.generated.h" #include "SessionListEntryWidget.generated.h"
@ -14,6 +15,8 @@ class TURNBASEDTUTORIAL_API USessionListEntryWidget : public UUserWidget {
GENERATED_BODY() GENERATED_BODY()
public: public:
virtual void NativeConstruct() override;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget)) UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UTextBlock *IndexText; class UTextBlock *IndexText;
@ -26,8 +29,18 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget)) UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UTextBlock *PingText; class UTextBlock *PingText;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UButton *JoinSessionButton;
void Update(int SessionIndex, const FOnlineSessionSearchResult &Session); void Update(int SessionIndex, const FOnlineSessionSearchResult &Session);
protected:
int SessionId; int SessionId;
FString SessionName; FString SessionName;
USessionsGameInstanceSubsystem *GetMyGameSubsystem() const;
UFUNCTION()
void OnJoinButton();
}; };

@ -13,8 +13,8 @@ void USessionListWidget::NativeConstruct() {
RefreshListButton->OnClicked.AddDynamic( RefreshListButton->OnClicked.AddDynamic(
this, &ThisClass::OnRefreshListButtonClicked); this, &ThisClass::OnRefreshListButtonClicked);
ConnectToSelectedSessionButton->OnClicked.AddDynamic( // ConnectToSelectedSessionButton->OnClicked.AddDynamic(
this, &ThisClass::ConnectToFirstSession); // this, &ThisClass::ConnectToFirstSession);
const auto MyGameInstanceSubsystem = GetMyGameSubsystem(); const auto MyGameInstanceSubsystem = GetMyGameSubsystem();
MyGameInstanceSubsystem->OnFindSessionsCompleteEvent.AddUObject( MyGameInstanceSubsystem->OnFindSessionsCompleteEvent.AddUObject(
@ -54,9 +54,9 @@ void USessionListWidget::OnRefreshListButtonClicked() {
GetMyGameSubsystem()->FindSessions(10, true); GetMyGameSubsystem()->FindSessions(10, true);
} }
void USessionListWidget::ConnectToFirstSession() { // void USessionListWidget::ConnectToFirstSession() {
GetMyGameSubsystem()->JoinSession(0); // GetMyGameSubsystem()->JoinSession(0);
} // }
void USessionListWidget::OnJoinSessionSuccess( void USessionListWidget::OnJoinSessionSuccess(

@ -17,8 +17,8 @@ class TURNBASEDTUTORIAL_API USessionListWidget : public UUserWidget {
protected: protected:
virtual void NativeConstruct() override; virtual void NativeConstruct() override;
UPROPERTY(meta = (BindWidget)) // UPROPERTY(meta = (BindWidget))
class UButton *ConnectToSelectedSessionButton; // class UButton *ConnectToSelectedSessionButton;
UPROPERTY(meta = (BindWidget)) UPROPERTY(meta = (BindWidget))
class UButton *GoBackToMainMenuButton; class UButton *GoBackToMainMenuButton;
@ -43,6 +43,6 @@ private:
UFUNCTION() UFUNCTION()
void OnRefreshListButtonClicked(); void OnRefreshListButtonClicked();
UFUNCTION() // UFUNCTION()
void ConnectToFirstSession(); // void ConnectToFirstSession();
}; };

@ -2,10 +2,48 @@
#include "ManageSquadGameState.h" #include "ManageSquadGameState.h"
AManageSquadGameState::AManageSquadGameState() { #include "ManageSquadTrooper.h"
TroopersKinds = {0, 0, 0, 0, 0}; #include "SelectedTrooperSaveGame.h"
#include "Kismet/GameplayStatics.h"
void AManageSquadGameState::BeginPlay() {
// USelectedTrooperSaveGame *SaveGameInstance = Cast<USelectedTrooperSaveGame>(
// UGameplayStatics::CreateSaveGameObject(
// USelectedTrooperSaveGame::StaticClass()));
if (UGameplayStatics::DoesSaveGameExist("Selected troopers", 0)) {
const USelectedTrooperSaveGame *SaveGameInstance = Cast<
USelectedTrooperSaveGame>(
UGameplayStatics::LoadGameFromSlot(TEXT("Selected troopers"), 0));
TroopersKinds = SaveGameInstance->SelectedTroopers;
} else {
TroopersKinds = {0, 0, 0, 0, 0};
}
InitializeTroopers();
} }
void AManageSquadGameState::ChangeSquad(int TrooperIndex, int TrooperKind) { void AManageSquadGameState::ChangeSquad(int TrooperIndex, int TrooperKind) {
TroopersKinds[TrooperIndex] = TrooperKind; TroopersKinds[TrooperIndex] = TrooperKind;
} }
TArray<uint8> AManageSquadGameState::GetSquad() const {
return TroopersKinds;
}
void AManageSquadGameState::InitializeTroopers() const {
FVector Location(-1150.0f, -2850.0f, 3000.0f);
const FRotator Rotation(0.0f, 90.0f, 0.0f);
for (int index = 0; index < 5; ++index) {
constexpr float DeltaX = 500.0f;
FTransform SpawnLocationAndRotation(Rotation);
SpawnLocationAndRotation.SetLocation(Location);
if (TroopersBpAssets.Num() > TroopersKinds[index]) {
AActor *Spawned = GetWorld()->SpawnActorDeferred<AManageSquadTrooper>(
TroopersBpAssets[TroopersKinds[index]], SpawnLocationAndRotation);
Cast<AManageSquadTrooper>(Spawned)->Initialize(index);
Spawned->SetActorRelativeScale3D({1.5f, 1.5f, 1.5f});
Spawned->FinishSpawning(SpawnLocationAndRotation);
Spawned->SetActorLocation(Location);
}
Location += {DeltaX, 0.f, 0.0f};
}
}

@ -14,12 +14,21 @@ class TURNBASEDTUTORIAL_API AManageSquadGameState : public AGameState {
GENERATED_BODY() GENERATED_BODY()
public: public:
AManageSquadGameState(); virtual void BeginPlay() override;
UFUNCTION() UFUNCTION()
void ChangeSquad(int TrooperIndex, int TrooperKind); void ChangeSquad(int TrooperIndex, int TrooperKind);
private: UFUNCTION()
TArray<uint8> GetSquad() const;
protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<UClass *> TroopersBpAssets;
UFUNCTION()
void InitializeTroopers() const;
UPROPERTY() UPROPERTY()
TArray<int> TroopersKinds; TArray<uint8> TroopersKinds;
}; };

@ -3,6 +3,7 @@
#include "ManageSquadPlayerController.h" #include "ManageSquadPlayerController.h"
#include "ManageSquadGameState.h" #include "ManageSquadGameState.h"
#include "ManageSquadWidget.h"
AManageSquadPlayerController::AManageSquadPlayerController() { AManageSquadPlayerController::AManageSquadPlayerController() {
SetShowMouseCursor(true); SetShowMouseCursor(true);
@ -14,6 +15,19 @@ void AManageSquadPlayerController::SetupInputComponent() {
&AManageSquadPlayerController::OnLeftMouseClick); &AManageSquadPlayerController::OnLeftMouseClick);
} }
void AManageSquadPlayerController::BeginPlay() {
Super::BeginPlay();
const TSoftClassPtr<UUserWidget> WidgetClass = TSoftClassPtr<
UUserWidget>(FSoftObjectPath(
"WidgetBlueprint'/Game/ManageSquadMenu/BP_ManageSquadWidget.BP_ManageSquadWidget_C'"
));
UUserWidget *CreatedWidget = CreateWidget<UUserWidget>(
GetWorld(), WidgetClass.LoadSynchronous());
if (CreatedWidget) {
CreatedWidget->AddToViewport();
}
}
void AManageSquadPlayerController::OnLeftMouseClick() { void AManageSquadPlayerController::OnLeftMouseClick() {
UE_LOG(LogTemp, Warning, TEXT("Mouse clicked")); UE_LOG(LogTemp, Warning, TEXT("Mouse clicked"));
FHitResult HitResult; FHitResult HitResult;

@ -20,6 +20,8 @@ public:
virtual void SetupInputComponent() override; virtual void SetupInputComponent() override;
virtual void BeginPlay() override;
private: private:
UPROPERTY() UPROPERTY()
AManageSquadTrooper *SelectedTrooper; AManageSquadTrooper *SelectedTrooper;

@ -29,3 +29,8 @@ ETrooperType AManageSquadTrooper::GetType() const {
int AManageSquadTrooper::GetIndex() const { int AManageSquadTrooper::GetIndex() const {
return Index; return Index;
} }
void AManageSquadTrooper::Initialize(int TrooperIndex) {
Index = TrooperIndex;
Type = ETrooperType::TROOPER_IN_SQUAD;
}

@ -40,4 +40,7 @@ public:
UFUNCTION() UFUNCTION()
int GetIndex() const; int GetIndex() const;
UFUNCTION()
void Initialize(int TrooperIndex);
}; };

@ -0,0 +1,27 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "ManageSquadWidget.h"
#include "ManageSquadGameState.h"
#include "SelectedTrooperSaveGame.h"
#include "Components/Button.h"
#include "Kismet/GameplayStatics.h"
void UManageSquadWidget::NativeConstruct() {
Super::NativeConstruct();
BackButton->OnClicked.AddDynamic(
this, &ThisClass::UManageSquadWidget::OnBackButtonClicked);
}
void UManageSquadWidget::OnBackButtonClicked() {
USelectedTrooperSaveGame *SaveGameInstance = Cast<USelectedTrooperSaveGame>(
UGameplayStatics::CreateSaveGameObject(
USelectedTrooperSaveGame::StaticClass()));
SaveGameInstance->SelectedTroopers = GetWorld()->GetGameState<
AManageSquadGameState>()->GetSquad();
UGameplayStatics::SaveGameToSlot(
SaveGameInstance,TEXT("Selected troopers"), 0);
UGameplayStatics::OpenLevel(GetWorld(), "MainMenuLevel");
RemoveFromParent();
}

@ -0,0 +1,25 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "ManageSquadWidget.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API UManageSquadWidget : public UUserWidget {
GENERATED_BODY()
public:
virtual void NativeConstruct() override;
protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UButton *BackButton;
UFUNCTION()
void OnBackButtonClicked();
};

@ -0,0 +1,8 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "SelectedTrooperSaveGame.h"
USelectedTrooperSaveGame::USelectedTrooperSaveGame()
: Super() {
}

@ -0,0 +1,21 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/SaveGame.h"
#include "SelectedTrooperSaveGame.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API USelectedTrooperSaveGame : public USaveGame {
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, Category=Basic)
TArray<uint8> SelectedTroopers;
USelectedTrooperSaveGame();
};

@ -1,6 +1,6 @@
{ {
"FileVersion": 3, "FileVersion": 3,
"EngineAssociation": "4.27", "EngineAssociation": "{B4FE6467-4579-3D84-B22A-558A3D607596}",
"Category": "", "Category": "",
"Description": "", "Description": "",
"Modules": [ "Modules": [

Loading…
Cancel
Save