Compare commits

..

10 Commits

@ -1,13 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/contentModel.xml
/projectSettingsUpdater.xml
/.idea.TurnBased.iml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

@ -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")

@ -1,2 +1,25 @@
# awesome_game # Arena Squad Strategy
### Overview
<p float="left">
<img src="misc/gameplay_1.png" alt="drawing" width="400">
<img src="misc/gameplay_2.png" alt="drawing" width="400">
</p>
[Video Preview](https://drive.google.com/file/d/1knR5V4S7jIn-r3ljkLcgxQ3JZdWQdmzB/preview)
Arena Squad Strategy is a step-by-step battlefield strategy game. The main objective is to kill enemy troopers first combining your troopers abilities and movement. The game supports LAN-multiplayer mode.
### Installation
Download Windows x86-64 build in *Releases* tab.
### Getting source code
Clone the project using `git`:
```
git clone https://git.eyakm.one/eyakm1/awesome_game.git
```
Unfortunately this git-hosting does not support ssh yet.

@ -35,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) {
@ -52,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(
@ -69,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(
@ -79,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);
} }
} }
@ -140,8 +135,17 @@ void ABattleGameMode::PostLogin(APlayerController *NewPlayer) {
CurrentNumberOfPlayers - 1); CurrentNumberOfPlayers - 1);
Cast<ABattlePlayerController>(NewPlayer)-> Cast<ABattlePlayerController>(NewPlayer)->
StartPlayingMusic(BackgroundSound); 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 *>(

@ -36,6 +36,12 @@ protected:
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,9 +156,23 @@ 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( void ABattlePlayerController::StartPlayingMusic_Implementation(
USoundBase *BackgroundSound) const { USoundBase *BackgroundSound) const {
UGameplayStatics::PlaySound2D(GetWorld(), BackgroundSound); UGameplayStatics::PlaySound2D(GetWorld(), BackgroundSound, 0.25f);
} }
// float AMyPlayerController::SetCurrentActionAndReturnRadius(int action) { // float AMyPlayerController::SetCurrentActionAndReturnRadius(int 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"
@ -53,7 +54,19 @@ public:
UFUNCTION(Client, Reliable) UFUNCTION(Client, Reliable)
void StartPlayingMusic(USoundBase *BackgroundSound) const; 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);
@ -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();

@ -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"
@ -59,7 +60,13 @@ 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;
};

@ -13,12 +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)-> // Cast<ABattlePlayerController>(NewPlayer)->
StartPlayingMusic(BackgroundSound); // 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;
}; };

@ -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,25 +0,0 @@
TurnBased/Binaries/Win64/TurnBasedTutorial.exe 2023-03-16T03:05:02.259Z
TurnBased/Binaries/Win64/OpenImageDenoise.dll 2023-03-16T01:52:15.842Z
TurnBased/Binaries/Win64/tbb12.dll 2023-03-16T01:52:15.844Z
Engine/Extras/Redist/en-us/UE4PrereqSetup_x64.exe 2023-03-16T01:46:38.646Z
Engine/Binaries/ThirdParty/Oculus/OVRPlugin/OVRPlugin/Win64/OVRPlugin.dll 2023-03-16T01:41:33.496Z
Engine/Binaries/ThirdParty/DbgHelp/dbghelp.dll 2023-03-16T01:41:25.090Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/PxFoundationPROFILE_x64.dll 2023-03-16T01:41:46.155Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/PxPvdSDKPROFILE_x64.dll 2023-03-16T01:41:46.339Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/PhysX3PROFILE_x64.dll 2023-03-16T01:41:45.025Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/PhysX3CookingPROFILE_x64.dll 2023-03-16T01:41:45.005Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/PhysX3CommonPROFILE_x64.dll 2023-03-16T01:41:44.869Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/APEX_ClothingPROFILE_x64.dll 2023-03-16T01:41:41.229Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/APEX_LegacyPROFILE_x64.dll 2023-03-16T01:41:42.482Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/ApexFrameworkPROFILE_x64.dll 2023-03-16T01:41:43.065Z
Engine/Binaries/ThirdParty/PhysX3/Win64/VS2015/NvClothPROFILE_x64.dll 2023-03-16T01:41:43.666Z
Engine/Binaries/ThirdParty/Ogg/Win64/VS2015/libogg_64.dll 2023-03-16T01:41:33.497Z
Engine/Binaries/ThirdParty/Vorbis/Win64/VS2015/libvorbis_64.dll 2023-03-16T01:41:53.464Z
Engine/Binaries/ThirdParty/Vorbis/Win64/VS2015/libvorbisfile_64.dll 2023-03-16T01:41:53.464Z
Engine/Binaries/ThirdParty/NVIDIA/NVaftermath/Win64/GFSDK_Aftermath_Lib.x64.dll 2023-03-16T01:41:32.651Z
Engine/Binaries/ThirdParty/OpenXR/win64/openxr_loader.dll 2023-03-16T01:41:33.921Z
Engine/Binaries/ThirdParty/OpenVR/OpenVRv1_5_17/Win64/openvr_api.dll 2023-03-16T01:41:33.917Z
Engine/Binaries/ThirdParty/NVIDIA/GeForceNOW/Win64/GfnRuntimeSdk.dll 2023-03-16T01:41:32.648Z
Engine/Binaries/ThirdParty/Windows/WinPixEventRuntime/x64/WinPixEventRuntime.dll 2023-03-16T01:41:53.487Z
Engine/Binaries/ThirdParty/Windows/XAudio2_9/x64/xaudio2_9redist.dll 2023-03-16T01:41:54.149Z
TurnBasedTutorial.exe 2023-03-16T03:07:14.267Z

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Loading…
Cancel
Save