refactoring

pull/6/head
m4xxx1m 2 years ago
parent efa99f3fd7
commit d7b7c46cd5

@ -26,7 +26,6 @@ AppliedDefaultGraphicsPerformance=Maximum
+ActiveGameNameRedirects=(OldGameName="/Script/TP_Blank",NewGameName="/Script/TurnBasedTutorial") +ActiveGameNameRedirects=(OldGameName="/Script/TP_Blank",NewGameName="/Script/TurnBasedTutorial")
+ActiveClassRedirects=(OldClassName="TP_BlankGameModeBase",NewClassName="TurnBasedTutorialGameModeBase") +ActiveClassRedirects=(OldClassName="TP_BlankGameModeBase",NewClassName="TurnBasedTutorialGameModeBase")
[CoreRedirects] [CoreRedirects]
+PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.OnPlayersSide",NewName="/Script/TurnBasedTutorial.Trooper.bOnPlayersSide") +PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.OnPlayersSide",NewName="/Script/TurnBasedTutorial.Trooper.bOnPlayersSide")
+FunctionRedirects=(OldName="/Script/TurnBasedTutorial.MyPlayerController.MoveHero",NewName="/Script/TurnBasedTutorial.MyPlayerController.MoveTropper") +FunctionRedirects=(OldName="/Script/TurnBasedTutorial.MyPlayerController.MoveHero",NewName="/Script/TurnBasedTutorial.MyPlayerController.MoveTropper")
@ -39,6 +38,18 @@ AppliedDefaultGraphicsPerformance=Maximum
+FunctionRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.HighlightEnemy",NewName="/Script/TurnBasedTutorial.Trooper.HighlightAsEnemy") +FunctionRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.HighlightEnemy",NewName="/Script/TurnBasedTutorial.Trooper.HighlightAsEnemy")
+PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.bIsDying",NewName="/Script/TurnBasedTutorial.Trooper.bIsDead") +PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.bIsDying",NewName="/Script/TurnBasedTutorial.Trooper.bIsDead")
+PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.bIsDying",NewName="/Script/TurnBasedTutorial.Trooper.bIsDead") +PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.bIsDying",NewName="/Script/TurnBasedTutorial.Trooper.bIsDead")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MyGameInstanceSubsystem",NewName="/Script/TurnBasedTutorial.SessionsGameInstanceSubsystem")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MyMainMenu",NewName="/Script/TurnBasedTutorial.MainMenuWidget")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MySessionListEntryWidget",NewName="/Script/TurnBasedTutorial.SessionListEntryWidget")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MySessionListWidget",NewName="/Script/TurnBasedTutorial.SessionListWidget")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MyGameMode",NewName="/Script/TurnBasedTutorial.BattleGameMode")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MyGameState",NewName="/Script/TurnBasedTutorial.BattleGameState")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MyPawn",NewName="/Script/TurnBasedTutorial.BattlePawn")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MyPlayerController",NewName="/Script/TurnBasedTutorial.BattlePlayerController")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MyPlayerStart",NewName="/Script/TurnBasedTutorial.BattlePlayerStart")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MyPlayerState",NewName="/Script/TurnBasedTutorial.BattlePlayerState")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MyExplosion",NewName="/Script/TurnBasedTutorial.Explosion")
+ClassRedirects=(OldName="/Script/TurnBasedTutorial.MyProjectile",NewName="/Script/TurnBasedTutorial.Projectile")
[OnlineSubsystem] [OnlineSubsystem]
DefaultPlatformService=Null DefaultPlatformService=Null

Binary file not shown.

@ -1,33 +1,32 @@
// Fill out your copyright notice in the Description page of Project Settings. // Fill out your copyright notice in the Description page of Project Settings.
#include "MyGameMode.h" #include "BattleGameMode.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "MyPawn.h" #include "BattlePawn.h"
#include "MyGameState.h" #include "BattleGameState.h"
#include "MyPlayerController.h" #include "BattlePlayerController.h"
#include "MyPlayerState.h" #include "BattlePlayerState.h"
#include "SinglePlayerGS.h" #include "Trooper/Trooper.h"
#include "Trooper.h"
ABattleGameMode::ABattleGameMode()
AMyGameMode::AMyGameMode()
: Super() { : Super() {
UE_LOG(LogTemp, Warning, TEXT("GameMode Constructor")); UE_LOG(LogTemp, Warning, TEXT("GameMode Constructor"));
GameStateClass = AMyGameState::StaticClass(); GameStateClass = ABattleGameState::StaticClass();
PlayerControllerClass = AMyPlayerController::StaticClass(); PlayerControllerClass = ABattlePlayerController::StaticClass();
PlayerStateClass = AMyPlayerState::StaticClass(); PlayerStateClass = ABattlePlayerState::StaticClass();
DefaultPawnClass = AMyPawn::StaticClass(); DefaultPawnClass = ABattlePawn::StaticClass();
} }
void AMyGameMode::BeginPlay() { void ABattleGameMode::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
} }
auto AMyGameMode::GetMyGameState() const { auto ABattleGameMode::GetMyGameState() const {
return GetGameState<AMyGameState>(); return GetGameState<ABattleGameState>();
} }
void AMyGameMode::InitializeBattleField_Implementation() { void ABattleGameMode::InitializeBattleField_Implementation() {
UE_LOG(LogTemp, Warning, TEXT("InitializeBattleField")); UE_LOG(LogTemp, Warning, TEXT("InitializeBattleField"));
FVector Location(2000.0f, -1000.0f, 0.0f); FVector Location(2000.0f, -1000.0f, 0.0f);
FRotator Rotation(0.0f, 180.0f, 0.0f); FRotator Rotation(0.0f, 180.0f, 0.0f);
@ -87,7 +86,7 @@ void AMyGameMode::InitializeBattleField_Implementation() {
} }
} }
AActor *AMyGameMode::ChoosePlayerStart_Implementation(AController *Player) { AActor *ABattleGameMode::ChoosePlayerStart_Implementation(AController *Player) {
UE_LOG(LogTemp, Warning, TEXT("GameMode ChoosePlayerStart %d"), UE_LOG(LogTemp, Warning, TEXT("GameMode ChoosePlayerStart %d"),
GetNumPlayers()); GetNumPlayers());
InitializeSpawnPointsIfNeeded(Player); InitializeSpawnPointsIfNeeded(Player);
@ -97,7 +96,7 @@ AActor *AMyGameMode::ChoosePlayerStart_Implementation(AController *Player) {
return CurrentPlayerStart; return CurrentPlayerStart;
} }
void AMyGameMode::InitializeSpawnPointsIfNeeded(AController *Player) { void ABattleGameMode::InitializeSpawnPointsIfNeeded(AController *Player) {
UE_LOG(LogTemp, Warning, TEXT("InitializeSpawnPointsIfNeeded")); UE_LOG(LogTemp, Warning, TEXT("InitializeSpawnPointsIfNeeded"));
if (SpawnPoints.Num() != 0) { if (SpawnPoints.Num() != 0) {
UE_LOG(LogTemp, Warning, TEXT("InitializeSpawnPointsIfNeeded Exit %d"), UE_LOG(LogTemp, Warning, TEXT("InitializeSpawnPointsIfNeeded Exit %d"),
@ -106,7 +105,7 @@ void AMyGameMode::InitializeSpawnPointsIfNeeded(AController *Player) {
} }
UE_LOG(LogTemp, Warning, TEXT("Rebuilding spawnpoints")); UE_LOG(LogTemp, Warning, TEXT("Rebuilding spawnpoints"));
const auto World = GetWorld(); const auto World = GetWorld();
for (TActorIterator<AMyPlayerStart> PlayerStartIterator(GetWorld()); for (TActorIterator<ABattlePlayerStart> PlayerStartIterator(GetWorld());
PlayerStartIterator; ++PlayerStartIterator) { PlayerStartIterator; ++PlayerStartIterator) {
const auto PlayerStart = *PlayerStartIterator; const auto PlayerStart = *PlayerStartIterator;
const UClass *PawnClass = GetDefaultPawnClassForController(Player); const UClass *PawnClass = GetDefaultPawnClassForController(Player);
@ -127,7 +126,7 @@ void AMyGameMode::InitializeSpawnPointsIfNeeded(AController *Player) {
} }
} }
void AMyGameMode::PostLogin(APlayerController *NewPlayer) { void ABattleGameMode::PostLogin(APlayerController *NewPlayer) {
Super::PostLogin(NewPlayer); Super::PostLogin(NewPlayer);
NewPlayer->SetShowMouseCursor(true); NewPlayer->SetShowMouseCursor(true);
UE_LOG(LogTemp, Warning, TEXT("PostLogin")); UE_LOG(LogTemp, Warning, TEXT("PostLogin"));
@ -136,7 +135,7 @@ void AMyGameMode::PostLogin(APlayerController *NewPlayer) {
const auto CurrentNumberOfPlayers = GetNumPlayers(); const auto CurrentNumberOfPlayers = GetNumPlayers();
// 0-indexation // 0-indexation
Cast<AMyPlayerController>(NewPlayer)->SetPlayerIndex( Cast<ABattlePlayerController>(NewPlayer)->SetPlayerIndex(
CurrentNumberOfPlayers - 1); CurrentNumberOfPlayers - 1);
UE_LOG(LogTemp, Warning, TEXT("%d"), CurrentNumberOfPlayers); UE_LOG(LogTemp, Warning, TEXT("%d"), CurrentNumberOfPlayers);
if (CurrentNumberOfPlayers == 2) { if (CurrentNumberOfPlayers == 2) {
@ -154,7 +153,7 @@ void AMyGameMode::PostLogin(APlayerController *NewPlayer) {
} }
} }
void AMyGameMode::StartGame_Implementation() { void ABattleGameMode::StartGame_Implementation() {
InitializeBattleField(); InitializeBattleField();
// PlayerNotInTurn()->SetEnemySelection(Troopers); // PlayerNotInTurn()->SetEnemySelection(Troopers);
// PlayerInTurn()->SetEnemySelection(Troopers); // PlayerInTurn()->SetEnemySelection(Troopers);

@ -4,17 +4,16 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "EngineUtils.h" #include "EngineUtils.h"
// #include "MyPlayerController.h" #include "BattlePlayerStart.h"
#include "MyPlayerStart.h"
#include "GameFramework/GameMode.h" #include "GameFramework/GameMode.h"
#include "MyGameMode.generated.h" #include "BattleGameMode.generated.h"
UCLASS() UCLASS()
class TURNBASEDTUTORIAL_API AMyGameMode : public AGameMode { class TURNBASEDTUTORIAL_API ABattleGameMode : public AGameMode {
GENERATED_BODY() GENERATED_BODY()
public: public:
AMyGameMode(); ABattleGameMode();
virtual AActor * virtual AActor *
ChoosePlayerStart_Implementation(AController *Player) override; ChoosePlayerStart_Implementation(AController *Player) override;
@ -40,7 +39,7 @@ protected:
void InitializeBattleField(); void InitializeBattleField();
UPROPERTY() UPROPERTY()
TMap<uint8, AMyPlayerStart *> SpawnPoints{}; TMap<uint8, ABattlePlayerStart *> SpawnPoints{};
// UPROPERTY() // UPROPERTY()
// mutable TArray<ATrooper *> Troopers; // mutable TArray<ATrooper *> Troopers;

@ -1,26 +1,27 @@
// Fill out your copyright notice in the Description page of Project Settings. // Fill out your copyright notice in the Description page of Project Settings.
#include "MyGameState.h" #include "BattleGameState.h"
// #include "GameOverWidget.h" // #include "GameOverWidget.h"
#include "MyPlayerState.h" #include "BattlePlayerState.h"
#include "Trooper.h" #include "Trooper/Trooper.h"
#include "Blueprint/UserWidget.h" #include "Blueprint/UserWidget.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
auto AMyGameState::GetMyPlayerState(uint8 PlayerIndex) const { auto ABattleGameState::GetMyPlayerState(uint8 PlayerIndex) const {
return Cast<AMyPlayerState>(PlayerArray[PlayerIndex]); return Cast<ABattlePlayerState>(PlayerArray[PlayerIndex]);
} }
AMyGameState::AMyGameState() : Super() { ABattleGameState::ABattleGameState()
: Super() {
} }
void AMyGameState::BeginPlay() { void ABattleGameState::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
LivingTroopersCount.SetNum(2); LivingTroopersCount.SetNum(2);
} }
void AMyGameState::AddTrooper_Implementation(ATrooper *Trooper) { void ABattleGameState::AddTrooper_Implementation(ATrooper *Trooper) {
if (Trooper->GetPlayerIndex() >= 0 && Trooper->GetPlayerIndex() <= if (Trooper->GetPlayerIndex() >= 0 && Trooper->GetPlayerIndex() <=
LivingTroopersCount.Num()) { LivingTroopersCount.Num()) {
if (LivingTroopersCount.Num() < 2) { if (LivingTroopersCount.Num() < 2) {
@ -31,14 +32,14 @@ void AMyGameState::AddTrooper_Implementation(ATrooper *Trooper) {
Troopers.Add(Trooper); Troopers.Add(Trooper);
} }
void AMyGameState::StartGame_Implementation() { void ABattleGameState::StartGame_Implementation() {
// PlayerNotInTurn()->SetEnemySelection(); // PlayerNotInTurn()->SetEnemySelection();
PlayerInTurn()->SetEnemySelection(); PlayerInTurn()->SetEnemySelection();
bGameStarted = true; bGameStarted = true;
PlayerInTurn()->StartTurn(); PlayerInTurn()->StartTurn();
} }
void AMyGameState::CycleTurns_Implementation() { void ABattleGameState::CycleTurns_Implementation() {
PlayerInTurn()->EndTurn(); PlayerInTurn()->EndTurn();
for (const auto Trooper : Troopers) { for (const auto Trooper : Troopers) {
if (Trooper != nullptr) { if (Trooper != nullptr) {
@ -62,27 +63,27 @@ void AMyGameState::CycleTurns_Implementation() {
// } // }
// } // }
AMyPlayerState *AMyGameState::PlayerInTurn() const { ABattlePlayerState *ABattleGameState::PlayerInTurn() const {
return GetMyPlayerState(CurrentPlayerTurn); return GetMyPlayerState(CurrentPlayerTurn);
} }
AMyPlayerState *AMyGameState::PlayerNotInTurn() const { ABattlePlayerState *ABattleGameState::PlayerNotInTurn() const {
return GetMyPlayerState(!CurrentPlayerTurn); return GetMyPlayerState(!CurrentPlayerTurn);
} }
TArray<ATrooper *> AMyGameState::GetTroopers() const { TArray<ATrooper *> ABattleGameState::GetTroopers() const {
return Troopers; return Troopers;
} }
bool AMyGameState::IsInTurn(uint8 PlayerIndex) const { bool ABattleGameState::IsInTurn(uint8 PlayerIndex) const {
return PlayerIndex == CurrentPlayerTurn; return PlayerIndex == CurrentPlayerTurn;
} }
bool AMyGameState::IsGameStarted() const { bool ABattleGameState::IsGameStarted() const {
return bGameStarted; return bGameStarted;
} }
void AMyGameState::DecreaseLivingTroopers(int PlayerIndex) { void ABattleGameState::DecreaseLivingTroopers(int PlayerIndex) {
if (bGameIsOver) if (bGameIsOver)
return; return;
LivingTroopersCount[PlayerIndex]--; LivingTroopersCount[PlayerIndex]--;
@ -96,10 +97,10 @@ void AMyGameState::DecreaseLivingTroopers(int PlayerIndex) {
} }
} }
void AMyGameState::GameOver(int PlayerIndexLose) const { void ABattleGameState::GameOver(int PlayerIndexLose) const {
Cast<AMyPlayerState>(PlayerArray[0])->GameOver(PlayerIndexLose); Cast<ABattlePlayerState>(PlayerArray[0])->GameOver(PlayerIndexLose);
if (bIsMultiplayer) { if (bIsMultiplayer) {
Cast<AMyPlayerState>(PlayerArray[1])->GameOver(PlayerIndexLose); Cast<ABattlePlayerState>(PlayerArray[1])->GameOver(PlayerIndexLose);
} }
} }
@ -111,10 +112,10 @@ void AMyGameState::GameOver(int PlayerIndexLose) const {
// } // }
void AMyGameState::GetLifetimeReplicatedProps( void ABattleGameState::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const { TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyGameState, Troopers); DOREPLIFETIME(ABattleGameState, Troopers);
DOREPLIFETIME(AMyGameState, CurrentPlayerTurn); DOREPLIFETIME(ABattleGameState, CurrentPlayerTurn);
DOREPLIFETIME(AMyGameState, bGameStarted); DOREPLIFETIME(ABattleGameState, bGameStarted);
} }

@ -3,19 +3,19 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "MyPlayerState.h" #include "BattlePlayerState.h"
#include "GameFramework/GameState.h" #include "GameFramework/GameState.h"
#include "MyGameState.generated.h" #include "BattleGameState.generated.h"
/** /**
* *
*/ */
UCLASS() UCLASS()
class TURNBASEDTUTORIAL_API AMyGameState : public AGameState { class TURNBASEDTUTORIAL_API ABattleGameState : public AGameState {
GENERATED_BODY() GENERATED_BODY()
public: public:
AMyGameState(); ABattleGameState();
virtual void BeginPlay() override; virtual void BeginPlay() override;
@ -29,10 +29,10 @@ public:
virtual void CycleTurns(); virtual void CycleTurns();
UFUNCTION(BlueprintPure) UFUNCTION(BlueprintPure)
AMyPlayerState *PlayerInTurn() const; ABattlePlayerState *PlayerInTurn() const;
UFUNCTION(BlueprintPure) UFUNCTION(BlueprintPure)
AMyPlayerState *PlayerNotInTurn() const; ABattlePlayerState *PlayerNotInTurn() const;
UFUNCTION() UFUNCTION()
TArray<ATrooper *> GetTroopers() const; TArray<ATrooper *> GetTroopers() const;

@ -1,35 +1,34 @@
// Fill out your copyright notice in the Description page of Project Settings. // Fill out your copyright notice in the Description page of Project Settings.
#include "MyPawn.h" #include "BattlePawn.h"
// Sets default values // Sets default values
AMyPawn::AMyPawn() { ABattlePawn::ABattlePawn() {
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true; PrimaryActorTick.bCanEverTick = true;
} }
// Called when the game starts or when spawned // Called when the game starts or when spawned
void AMyPawn::BeginPlay() { void ABattlePawn::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
} }
void AMyPawn::MoveForward(float Val) { void ABattlePawn::MoveForward(float Val) {
if (Val != 0.f) if (Val != 0.f) {
{ if (Controller) {
if (Controller)
{
FRotator ControlSpaceRot = Controller->GetControlRotation(); FRotator ControlSpaceRot = Controller->GetControlRotation();
ControlSpaceRot.Pitch = 0; ControlSpaceRot.Pitch = 0;
// transform to world space and add it // transform to world space and add it
AddMovementInput( FRotationMatrix(ControlSpaceRot).GetScaledAxis( EAxis::X ), Val ); AddMovementInput(
FRotationMatrix(ControlSpaceRot).GetScaledAxis(EAxis::X), Val);
} }
} }
} }
// Called to bind functionality to input // Called to bind functionality to input
void AMyPawn::SetupPlayerInputComponent(UInputComponent *PlayerInputComponent) { void ABattlePawn::SetupPlayerInputComponent(UInputComponent *PlayerInputComponent) {
Super::SetupPlayerInputComponent(PlayerInputComponent); Super::SetupPlayerInputComponent(PlayerInputComponent);
} }

@ -3,17 +3,16 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "GameFramework/SpectatorPawn.h" #include "GameFramework/SpectatorPawn.h"
#include "MyPawn.generated.h" #include "BattlePawn.generated.h"
UCLASS() UCLASS()
class TURNBASEDTUTORIAL_API AMyPawn : public ASpectatorPawn { class TURNBASEDTUTORIAL_API ABattlePawn : public ASpectatorPawn {
GENERATED_BODY() GENERATED_BODY()
public: public:
// Sets default values for this pawn's properties // Sets default values for this pawn's properties
AMyPawn(); ABattlePawn();
protected: protected:
// Called when the game starts or when spawned // Called when the game starts or when spawned
@ -22,7 +21,6 @@ protected:
virtual void MoveForward(float Val) override; virtual void MoveForward(float Val) override;
public: public:
// Called to bind functionality to input // Called to bind functionality to input
virtual void SetupPlayerInputComponent( virtual void SetupPlayerInputComponent(
class UInputComponent *PlayerInputComponent) override; class UInputComponent *PlayerInputComponent) override;

@ -1,31 +1,31 @@
// Fill out your copyright notice in the Description page of Project Settings. // Fill out your copyright notice in the Description page of Project Settings.
#include "MyPlayerController.h" #include "BattlePlayerController.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "MyGameMode.h" #include "BattleGameMode.h"
#include "MyGameState.h" #include "BattleGameState.h"
#include "MyPlayerState.h" #include "BattlePlayerState.h"
#include "Blueprint/UserWidget.h" #include "Blueprint/UserWidget.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
AMyPlayerController::AMyPlayerController() 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;
} }
void AMyPlayerController::BeginPlay() { void ABattlePlayerController::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
UUserWidget *CreatedWidget = CreateWidget<UUserWidget>( UUserWidget *CreatedWidget = CreateWidget<UUserWidget>(
GetWorld(), WidgetClass); GetWorld(), WidgetClass);
CreatedWidget->AddToViewport(); CreatedWidget->AddToViewport();
} }
void AMyPlayerController::SetupInputComponent() { void ABattlePlayerController::SetupInputComponent() {
Super::SetupInputComponent(); Super::SetupInputComponent();
InputComponent->BindAction("MyAction", IE_Pressed, this, InputComponent->BindAction("MyAction", IE_Pressed, this,
&AMyPlayerController::OnLeftMouseClick); &ABattlePlayerController::OnLeftMouseClick);
} }
// void AMyPlayerController::SetMyTurn(bool bMyTurn) { // void AMyPlayerController::SetMyTurn(bool bMyTurn) {
@ -44,22 +44,22 @@ void AMyPlayerController::SetupInputComponent() {
// UE_LOG(LogTemp, Warning, TEXT("Your turn, %d"), PlayerIndex); // UE_LOG(LogTemp, Warning, TEXT("Your turn, %d"), PlayerIndex);
// } // }
auto AMyPlayerController::GetMyGameState() const { auto ABattlePlayerController::GetMyGameState() const {
return Cast<AMyGameState>(UGameplayStatics::GetGameState(GetWorld())); return Cast<ABattleGameState>(UGameplayStatics::GetGameState(GetWorld()));
} }
auto AMyPlayerController::GetMyPlayerState() const { auto ABattlePlayerController::GetMyPlayerState() const {
return GetPlayerState<AMyPlayerState>(); return GetPlayerState<ABattlePlayerState>();
} }
auto AMyPlayerController::GetMyGameMode() const { auto ABattlePlayerController::GetMyGameMode() const {
return Cast<AMyGameMode>( return Cast<ABattleGameMode>(
UGameplayStatics::GetGameMode(GetWorld())); UGameplayStatics::GetGameMode(GetWorld()));
} }
void AMyPlayerController::EndTurn_Implementation() { void ABattlePlayerController::EndTurn_Implementation() {
// if (GetMyPlayerState()->IsMyTurn()) { // if (GetMyPlayerState()->IsMyTurn()) {
// GetMyGameState()->CycleTurns(); // GetMyGameState()->CycleTurns();
// } // }
@ -136,14 +136,14 @@ void AMyPlayerController::EndTurn_Implementation() {
// } // }
// } // }
void AMyPlayerController::SetPlayerIndex(uint8 NewPlayerIndex) { void ABattlePlayerController::SetPlayerIndex(uint8 NewPlayerIndex) {
PlayerIndex = NewPlayerIndex; PlayerIndex = NewPlayerIndex;
GetMyPlayerState()->SetPlayerIndex(NewPlayerIndex); GetMyPlayerState()->SetPlayerIndex(NewPlayerIndex);
// GetMyPlayerState()->PlayerIndex = NewPlayerIndex; // GetMyPlayerState()->PlayerIndex = NewPlayerIndex;
} }
uint8 AMyPlayerController::GetPlayerIndex() const { uint8 ABattlePlayerController::GetPlayerIndex() const {
return PlayerIndex; return PlayerIndex;
} }
@ -191,16 +191,16 @@ uint8 AMyPlayerController::GetPlayerIndex() const {
// } // }
// } // }
void AMyPlayerController::GetLifetimeReplicatedProps( void ABattlePlayerController::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const { TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyPlayerController, PlayerIndex); DOREPLIFETIME(ABattlePlayerController, PlayerIndex);
// DOREPLIFETIME(AMyPlayerController, CurrentAction); // DOREPLIFETIME(AMyPlayerController, CurrentAction);
// DOREPLIFETIME(AMyPlayerController, bIsMyTurn); // DOREPLIFETIME(AMyPlayerController, bIsMyTurn);
// DOREPLIFETIME(AMyPlayerController, SelectedTrooper); // DOREPLIFETIME(AMyPlayerController, SelectedTrooper);
} }
void AMyPlayerController::OnLeftMouseClick() { void ABattlePlayerController::OnLeftMouseClick() {
if (!GetMyPlayerState()->IsMyTurn()) { if (!GetMyPlayerState()->IsMyTurn()) {
return; return;
} }

@ -3,12 +3,12 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/PlayerController.h" #include "GameFramework/PlayerController.h"
#include "MyPlayerController.generated.h" #include "BattlePlayerController.generated.h"
// DECLARE_DYNAMIC_DELEGATE_OneParam(FOnMyTurnChangedDelegate, bool, bMyTurn); // DECLARE_DYNAMIC_DELEGATE_OneParam(FOnMyTurnChangedDelegate, bool, bMyTurn);
UCLASS() UCLASS()
class TURNBASEDTUTORIAL_API AMyPlayerController : public APlayerController { class TURNBASEDTUTORIAL_API ABattlePlayerController : public APlayerController {
GENERATED_BODY() GENERATED_BODY()
public: public:
@ -18,7 +18,7 @@ public:
virtual void SetupInputComponent() override; virtual void SetupInputComponent() override;
AMyPlayerController(); ABattlePlayerController();
UFUNCTION(BlueprintCallable, Server, Reliable) UFUNCTION(BlueprintCallable, Server, Reliable)
void EndTurn(); void EndTurn();

@ -1,8 +1,8 @@
// Fill out your copyright notice in the Description page of Project Settings. // Fill out your copyright notice in the Description page of Project Settings.
#include "MyPlayerStart.h" #include "BattlePlayerStart.h"
uint8 AMyPlayerStart::GetPlayerIndex() const { uint8 ABattlePlayerStart::GetPlayerIndex() const {
return PlayerIndex; return PlayerIndex;
} }

@ -4,13 +4,13 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/PlayerStart.h" #include "GameFramework/PlayerStart.h"
#include "MyPlayerStart.generated.h" #include "BattlePlayerStart.generated.h"
/** /**
* *
*/ */
UCLASS() UCLASS()
class TURNBASEDTUTORIAL_API AMyPlayerStart : public APlayerStart { class TURNBASEDTUTORIAL_API ABattlePlayerStart : public APlayerStart {
GENERATED_BODY() GENERATED_BODY()
public: public:

@ -1,23 +1,23 @@
// Fill out your copyright notice in the Description page of Project Settings. // Fill out your copyright notice in the Description page of Project Settings.
#include "MyPlayerState.h" #include "BattlePlayerState.h"
#include "GameOverWidget.h" #include "GameOverWidget.h"
#include "MyGameState.h" #include "BattleGameState.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
AMyPlayerState::AMyPlayerState() ABattlePlayerState::ABattlePlayerState()
: Super(), bIsMyTurn(false), SelectedTrooper(nullptr) { : Super(), bIsMyTurn(false), SelectedTrooper(nullptr) {
// PrimaryActorTick.bCanEverTick = true; // PrimaryActorTick.bCanEverTick = true;
} }
void AMyPlayerState::BeginPlay() { void ABattlePlayerState::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
} }
auto AMyPlayerState::GetMyGameState() const { auto ABattlePlayerState::GetMyGameState() const {
return Cast<AMyGameState>(GetWorld()->GetGameState()); return Cast<ABattleGameState>(GetWorld()->GetGameState());
} }
// void AMyPlayerState::Tick(float DeltaSeconds) { // void AMyPlayerState::Tick(float DeltaSeconds) {
@ -35,18 +35,18 @@ auto AMyPlayerState::GetMyGameState() const {
// } // }
// } // }
void AMyPlayerState::SetPlayerIndex(uint8 NewPlayerIndex) { void ABattlePlayerState::SetPlayerIndex(uint8 NewPlayerIndex) {
PlayerIndex = NewPlayerIndex; PlayerIndex = NewPlayerIndex;
} }
void AMyPlayerState::GameOver_Implementation(int PlayerLoseIndex) { void ABattlePlayerState::GameOver_Implementation(int PlayerLoseIndex) {
UGameOverWidget *CreatedWidget = CreateWidget<UGameOverWidget>( UGameOverWidget *CreatedWidget = CreateWidget<UGameOverWidget>(
GetWorld(), GameOverWidgetClass); GetWorld(), GameOverWidgetClass);
CreatedWidget->AddToViewport(); CreatedWidget->AddToViewport();
CreatedWidget->SetWidgetText(PlayerLoseIndex != PlayerIndex); CreatedWidget->SetWidgetText(PlayerLoseIndex != PlayerIndex);
} }
void AMyPlayerState::SetEnemySelection_Implementation( void ABattlePlayerState::SetEnemySelection_Implementation(
/*const TArray<AActor *> &Troopers*/) const { /*const TArray<AActor *> &Troopers*/) const {
TArray<AActor *> Troopers; TArray<AActor *> Troopers;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), UGameplayStatics::GetAllActorsOfClass(GetWorld(),
@ -60,7 +60,7 @@ void AMyPlayerState::SetEnemySelection_Implementation(
} }
} }
void AMyPlayerState::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)) {
@ -86,7 +86,7 @@ void AMyPlayerState::MoveTrooper_Implementation(ATrooper *Trooper,
// } // }
// } // }
void AMyPlayerState::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)) {
@ -110,11 +110,11 @@ void AMyPlayerState::Attack_Implementation(ATrooper *Attacker,
// } // }
// } // }
bool AMyPlayerState::IsMyTurn() const { bool ABattlePlayerState::IsMyTurn() const {
return bIsMyTurn; return bIsMyTurn;
} }
void AMyPlayerState::SetMyTurn(bool bMyTurn) { void ABattlePlayerState::SetMyTurn(bool bMyTurn) {
bIsMyTurn = bMyTurn; bIsMyTurn = bMyTurn;
if (bIsMyTurn) { if (bIsMyTurn) {
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green,
@ -124,12 +124,12 @@ void AMyPlayerState::SetMyTurn(bool bMyTurn) {
} }
} }
void AMyPlayerState::StartTurn_Implementation() { void ABattlePlayerState::StartTurn_Implementation() {
SetMyTurn(true); SetMyTurn(true);
UE_LOG(LogTemp, Warning, TEXT("Your turn, %d"), PlayerIndex); UE_LOG(LogTemp, Warning, TEXT("Your turn, %d"), PlayerIndex);
} }
void AMyPlayerState::EndTurn_Implementation() { void ABattlePlayerState::EndTurn_Implementation() {
if (bIsMyTurn) { if (bIsMyTurn) {
UE_LOG(LogTemp, Warning, TEXT("End Turn from player %d"), UE_LOG(LogTemp, Warning, TEXT("End Turn from player %d"),
PlayerIndex); PlayerIndex);
@ -145,7 +145,7 @@ void AMyPlayerState::EndTurn_Implementation() {
} }
} }
void AMyPlayerState::OnPlayerAction(const FHitResult &HitResult) { void ABattlePlayerState::OnPlayerAction(const FHitResult &HitResult) {
auto const NewlySelectedLocation = HitResult.Location; auto const NewlySelectedLocation = HitResult.Location;
ATrooper *NewlySelectedTrooper = Cast<ATrooper>( ATrooper *NewlySelectedTrooper = Cast<ATrooper>(
HitResult.GetActor()); HitResult.GetActor());
@ -194,7 +194,7 @@ void AMyPlayerState::OnPlayerAction(const FHitResult &HitResult) {
} }
} }
void AMyPlayerState::SetCurrentAction_Implementation(int Action) { void ABattlePlayerState::SetCurrentAction_Implementation(int Action) {
CurrentAction = Action; CurrentAction = Action;
if (SelectedTrooper) { if (SelectedTrooper) {
SelectedTrooper->UpdateSelectionRadius(Action); SelectedTrooper->UpdateSelectionRadius(Action);
@ -204,16 +204,16 @@ void AMyPlayerState::SetCurrentAction_Implementation(int Action) {
"with index %d"), CurrentAction, PlayerIndex); "with index %d"), CurrentAction, PlayerIndex);
} }
uint8 AMyPlayerState::GetPlayerIndex() const { uint8 ABattlePlayerState::GetPlayerIndex() const {
return PlayerIndex; return PlayerIndex;
} }
void AMyPlayerState::GetLifetimeReplicatedProps( void ABattlePlayerState::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const { TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyPlayerState, PlayerIndex); DOREPLIFETIME(ABattlePlayerState, PlayerIndex);
DOREPLIFETIME(AMyPlayerState, CurrentAction); DOREPLIFETIME(ABattlePlayerState, CurrentAction);
DOREPLIFETIME(AMyPlayerState, bIsMyTurn); DOREPLIFETIME(ABattlePlayerState, bIsMyTurn);
DOREPLIFETIME(AMyPlayerState, SelectedTrooper); DOREPLIFETIME(ABattlePlayerState, SelectedTrooper);
DOREPLIFETIME(AMyPlayerState, bIsSelectionInitialized); DOREPLIFETIME(ABattlePlayerState, bIsSelectionInitialized);
} }

@ -2,20 +2,20 @@
#pragma once #pragma once
#include "Trooper.h" #include "Trooper/Trooper.h"
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/PlayerState.h" #include "GameFramework/PlayerState.h"
#include "MyPlayerState.generated.h" #include "BattlePlayerState.generated.h"
/** /**
* *
*/ */
UCLASS() UCLASS()
class TURNBASEDTUTORIAL_API AMyPlayerState : public APlayerState { class TURNBASEDTUTORIAL_API ABattlePlayerState : public APlayerState {
GENERATED_BODY() GENERATED_BODY()
public: public:
AMyPlayerState(); ABattlePlayerState();
virtual void BeginPlay() override; virtual void BeginPlay() override;

@ -0,0 +1,29 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "GameOverWidget.h"
#include "../SessionsGameInstanceSubsystem.h"
#include "Components/Button.h"
#include "Components/TextBlock.h"
#include "Kismet/GameplayStatics.h"
void UGameOverWidget::NativeConstruct() {
ButtonToMenu->OnClicked.AddDynamic(this, &ThisClass::QuitCurrentSession);
}
void UGameOverWidget::QuitCurrentSession_Implementation() {
const UGameInstance *GameInstance = UGameplayStatics::GetGameInstance(
GetWorld());
USessionsGameInstanceSubsystem *GameInstanceSubsystem = GameInstance->GetSubsystem
<USessionsGameInstanceSubsystem>();
GameInstanceSubsystem->QuitCurrentSession();
}
void UGameOverWidget::SetWidgetText_Implementation(bool HasWon) {
if (HasWon) {
GameOverText->SetText(FText::FromString("You won!"));
} else {
GameOverText->SetText(FText::FromString("You lose!"));
}
}

@ -19,7 +19,7 @@ public:
UFUNCTION(Client, Reliable) UFUNCTION(Client, Reliable)
void SetWidgetText(bool HasWon); void SetWidgetText(bool HasWon);
UFUNCTION() UFUNCTION(Client, Reliable)
void QuitCurrentSession(); void QuitCurrentSession();
protected: protected:

@ -3,7 +3,8 @@
#include "SinglePlayerGM.h" #include "SinglePlayerGM.h"
#include "SinglePlayerGS.h" #include "SinglePlayerGS.h"
ASinglePlayerGM::ASinglePlayerGM() : Super() { ASinglePlayerGM::ASinglePlayerGM()
: Super() {
GameStateClass = ASinglePlayerGS::StaticClass(); GameStateClass = ASinglePlayerGS::StaticClass();
bIsMultiplayer = false; bIsMultiplayer = false;
} }

@ -3,14 +3,14 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "MyGameMode.h" #include "../BattleGameMode.h"
#include "SinglePlayerGM.generated.h" #include "SinglePlayerGM.generated.h"
/** /**
* *
*/ */
UCLASS() UCLASS()
class TURNBASEDTUTORIAL_API ASinglePlayerGM : public AMyGameMode { class TURNBASEDTUTORIAL_API ASinglePlayerGM : public ABattleGameMode {
GENERATED_BODY() GENERATED_BODY()
public: public:
@ -19,5 +19,4 @@ public:
virtual void BeginPlay() override; virtual void BeginPlay() override;
virtual void PostLogin(APlayerController *NewPlayer) override; virtual void PostLogin(APlayerController *NewPlayer) override;
}; };

@ -4,14 +4,14 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "EnemyAIController.h" #include "EnemyAIController.h"
#include "MyGameState.h" #include "../BattleGameState.h"
#include "SinglePlayerGS.generated.h" #include "SinglePlayerGS.generated.h"
/** /**
* *
*/ */
UCLASS() UCLASS()
class TURNBASEDTUTORIAL_API ASinglePlayerGS : public AMyGameState { class TURNBASEDTUTORIAL_API ASinglePlayerGS : public ABattleGameState {
GENERATED_BODY() GENERATED_BODY()
public: public:

@ -5,13 +5,11 @@
// Sets default values for this component's properties // Sets default values for this component's properties
UAbility::UAbility() { UAbility::UAbility() {
PrimaryComponentTick.bCanEverTick = false; PrimaryComponentTick.bCanEverTick = false;
} }
// Called when the game starts // Called when the game starts
void UAbility::BeginPlay() { void UAbility::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
} }
// void UAbility::TickComponent(float DeltaTime, // void UAbility::TickComponent(float DeltaTime,

@ -1,13 +1,12 @@
// Fill out your copyright notice in the Description page of Project Settings. // Fill out your copyright notice in the Description page of Project Settings.
#include "MyExplosion.h" #include "Explosion.h"
#include "Trooper.h" #include "Trooper.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#include "Particles/ParticleSystemComponent.h" #include "Particles/ParticleSystemComponent.h"
AMyExplosion::AMyExplosion() { AExplosion::AExplosion() {
// if (!CollisionComponent) { // if (!CollisionComponent) {
// CollisionComponent = CreateDefaultSubobject<USphereComponent>( // CollisionComponent = CreateDefaultSubobject<USphereComponent>(
// TEXT("SphereComponent")); // TEXT("SphereComponent"));
@ -22,7 +21,7 @@ AMyExplosion::AMyExplosion() {
InitialLifeSpan = 1.0f; InitialLifeSpan = 1.0f;
} }
void AMyExplosion::Initialize(float damage, void AExplosion::Initialize(float damage,
float splashRadius, float splashRadius,
uint8 playerIndex) { uint8 playerIndex) {
Damage = damage; Damage = damage;
@ -34,11 +33,11 @@ void AMyExplosion::Initialize(float damage,
} }
} }
void AMyExplosion::BeginPlay() { void AExplosion::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
} }
void AMyExplosion::NotifyActorBeginOverlap(AActor *OtherActor) { void AExplosion::NotifyActorBeginOverlap(AActor *OtherActor) {
Super::NotifyActorBeginOverlap(OtherActor); Super::NotifyActorBeginOverlap(OtherActor);
ATrooper *OtherTrooper = Cast<ATrooper>(OtherActor); ATrooper *OtherTrooper = Cast<ATrooper>(OtherActor);
if (OtherTrooper) { if (OtherTrooper) {
@ -57,11 +56,11 @@ void AMyExplosion::NotifyActorBeginOverlap(AActor *OtherActor) {
} }
} }
void AMyExplosion::GetLifetimeReplicatedProps( void AExplosion::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const { TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyExplosion, Damage); DOREPLIFETIME(AExplosion, Damage);
DOREPLIFETIME(AMyExplosion, PlayerIndex); DOREPLIFETIME(AExplosion, PlayerIndex);
// DOREPLIFETIME(AMyExplosion, CollisionComponent); // DOREPLIFETIME(AMyExplosion, CollisionComponent);
DOREPLIFETIME(AMyExplosion, ParticleSystemComponent); DOREPLIFETIME(AExplosion, ParticleSystemComponent);
} }

@ -4,14 +4,14 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/Actor.h" #include "GameFramework/Actor.h"
#include "MyExplosion.generated.h" #include "Explosion.generated.h"
UCLASS() UCLASS()
class TURNBASEDTUTORIAL_API AMyExplosion : public AActor { class TURNBASEDTUTORIAL_API AExplosion : public AActor {
GENERATED_BODY() GENERATED_BODY()
public: public:
AMyExplosion(); AExplosion();
void Initialize(float damage, void Initialize(float damage,
float splashRadius, float splashRadius,

@ -14,5 +14,6 @@ void UHealthBar::NativeTick(const FGeometry &MyGeometry, float InDeltaTime) {
if (!OwnerTrooper.IsValid()) if (!OwnerTrooper.IsValid())
return; return;
HealthBar->SetPercent(OwnerTrooper->GetHitPoints() / OwnerTrooper->GetMaxHitPoints()); HealthBar->SetPercent(
OwnerTrooper->GetHitPoints() / OwnerTrooper->GetMaxHitPoints());
} }

@ -13,6 +13,7 @@
UCLASS(Abstract) UCLASS(Abstract)
class TURNBASEDTUTORIAL_API UHealthBar : public UUserWidget { class TURNBASEDTUTORIAL_API UHealthBar : public UUserWidget {
GENERATED_BODY() GENERATED_BODY()
public: public:
void SetOwnerTrooper(ATrooper *Trooper); void SetOwnerTrooper(ATrooper *Trooper);
@ -22,5 +23,6 @@ protected:
UPROPERTY(meta=(BindWidget)) UPROPERTY(meta=(BindWidget))
class UProgressBar *HealthBar; class UProgressBar *HealthBar;
virtual void NativeTick(const FGeometry &MyGeometry, float InDeltaTime) override; virtual void
NativeTick(const FGeometry &MyGeometry, float InDeltaTime) override;
}; };

@ -1,12 +1,12 @@
// Fill out your copyright notice in the Description page of Project Settings. // Fill out your copyright notice in the Description page of Project Settings.
#include "MyProjectile.h" #include "Projectile.h"
#include "Trooper.h" #include "Trooper.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
AMyProjectile::AMyProjectile() { AProjectile::AProjectile() {
// if (!RootComponent) { // if (!RootComponent) {
// RootComponent = CreateDefaultSubobject<USceneComponent>( // RootComponent = CreateDefaultSubobject<USceneComponent>(
// TEXT("ProjectileSceneComponent")); // TEXT("ProjectileSceneComponent"));
@ -41,7 +41,7 @@ AMyProjectile::AMyProjectile() {
InitialLifeSpan = 2.0f; InitialLifeSpan = 2.0f;
} }
void AMyProjectile::Initialize(const UAbility *Ability, void AProjectile::Initialize(const UAbility *Ability,
uint8 playerIndex, uint8 playerIndex,
float PathLength) { float PathLength) {
ProjectileMovementComponent->InitialSpeed = ProjectileMovementComponent->InitialSpeed =
@ -55,12 +55,12 @@ void AMyProjectile::Initialize(const UAbility *Ability,
SetLifeSpan(PathLength / Ability->Speed); SetLifeSpan(PathLength / Ability->Speed);
} }
void AMyProjectile::Shoot(FVector From, FVector To) const { void AProjectile::Shoot(FVector From, FVector To) const {
ProjectileMovementComponent->Velocity = ProjectileMovementComponent->Velocity =
(To - From).GetSafeNormal() * ProjectileMovementComponent->InitialSpeed; (To - From).GetSafeNormal() * ProjectileMovementComponent->InitialSpeed;
} }
void AMyProjectile::NotifyActorBeginOverlap(AActor *OtherActor) { void AProjectile::NotifyActorBeginOverlap(AActor *OtherActor) {
Super::NotifyActorBeginOverlap(OtherActor); Super::NotifyActorBeginOverlap(OtherActor);
ATrooper *OtherTrooper = Cast<ATrooper>(OtherActor); ATrooper *OtherTrooper = Cast<ATrooper>(OtherActor);
if (OtherTrooper) { if (OtherTrooper) {
@ -106,34 +106,34 @@ void AMyProjectile::NotifyActorBeginOverlap(AActor *OtherActor) {
// } // }
void AMyProjectile::BeginPlay() { void AProjectile::BeginPlay() {
Super::BeginPlay(); Super::BeginPlay();
} }
void AMyProjectile::EndPlay(const EEndPlayReason::Type EndPlayReason) { void AProjectile::EndPlay(const EEndPlayReason::Type EndPlayReason) {
Super::EndPlay(EndPlayReason); Super::EndPlay(EndPlayReason);
Explode(); Explode();
} }
void AMyProjectile::Explode_Implementation() const { void AProjectile::Explode_Implementation() const {
const FTransform SpawnTransform = GetTransform(); const FTransform SpawnTransform = GetTransform();
FActorSpawnParameters SpawnParameters; FActorSpawnParameters SpawnParameters;
SpawnParameters.Instigator = GetInstigator(); SpawnParameters.Instigator = GetInstigator();
SpawnParameters.SpawnCollisionHandlingOverride = SpawnParameters.SpawnCollisionHandlingOverride =
ESpawnActorCollisionHandlingMethod::AlwaysSpawn; ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
AMyExplosion *Explosion = GetWorld()->SpawnActor<AMyExplosion>( AExplosion *Explosion = GetWorld()->SpawnActor<AExplosion>(
ExplosionSubclass, SpawnTransform, SpawnParameters); ExplosionSubclass, SpawnTransform, SpawnParameters);
Explosion->Initialize(Damage, SplashRadius, PlayerIndex); Explosion->Initialize(Damage, SplashRadius, PlayerIndex);
Explosion->SetActorLocation(GetActorLocation()); Explosion->SetActorLocation(GetActorLocation());
} }
void AMyProjectile::GetLifetimeReplicatedProps( void AProjectile::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const { TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyProjectile, Damage); DOREPLIFETIME(AProjectile, Damage);
DOREPLIFETIME(AMyProjectile, PlayerIndex); DOREPLIFETIME(AProjectile, PlayerIndex);
// DOREPLIFETIME(AMyProjectile, CollisionComponent); // DOREPLIFETIME(AMyProjectile, CollisionComponent);
DOREPLIFETIME(AMyProjectile, ProjectileMeshComponent); DOREPLIFETIME(AProjectile, ProjectileMeshComponent);
DOREPLIFETIME(AMyProjectile, ProjectileMovementComponent); DOREPLIFETIME(AProjectile, ProjectileMovementComponent);
DOREPLIFETIME(AMyProjectile, SplashRadius); DOREPLIFETIME(AProjectile, SplashRadius);
} }

@ -4,18 +4,18 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Ability.h" #include "Ability.h"
#include "MyExplosion.h" #include "Explosion.h"
#include "Components/SphereComponent.h" #include "Components/SphereComponent.h"
#include "GameFramework/Actor.h" #include "GameFramework/Actor.h"
#include "GameFramework/ProjectileMovementComponent.h" #include "GameFramework/ProjectileMovementComponent.h"
#include "MyProjectile.generated.h" #include "Projectile.generated.h"
UCLASS() UCLASS()
class TURNBASEDTUTORIAL_API AMyProjectile : public AActor { class TURNBASEDTUTORIAL_API AProjectile : public AActor {
GENERATED_BODY() GENERATED_BODY()
public: public:
AMyProjectile(); AProjectile();
void Initialize(const UAbility *Ability, void Initialize(const UAbility *Ability,
uint8 playerIndex, uint8 playerIndex,
@ -27,7 +27,7 @@ protected:
virtual void NotifyActorBeginOverlap(AActor *OtherActor) override; virtual void NotifyActorBeginOverlap(AActor *OtherActor) override;
UPROPERTY(EditAnywhere, BlueprintReadWrite) UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<AMyExplosion> ExplosionSubclass; TSubclassOf<AExplosion> ExplosionSubclass;
// virtual void NotifyHit(UPrimitiveComponent *MyComp, // virtual void NotifyHit(UPrimitiveComponent *MyComp,
// AActor *Other, // AActor *Other,

@ -2,8 +2,8 @@
#include <Kismet/GameplayStatics.h> #include <Kismet/GameplayStatics.h>
#include "HealthBar.h" #include "HealthBar.h"
#include "MyGameState.h" #include "../BattleGameState.h"
#include "MyProjectile.h" #include "Projectile.h"
#include "Components/WidgetComponent.h" #include "Components/WidgetComponent.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
@ -312,14 +312,15 @@ void ATrooper::TrooperTakeDamage_Implementation(float Damage) {
if (HitPoints == 0) { if (HitPoints == 0) {
bIsDead = true; bIsDead = true;
SetLifeSpan(DyingAnimationDuration); SetLifeSpan(DyingAnimationDuration);
GetWorld()->GetGameState<AMyGameState>()->DecreaseLivingTroopers(PlayerIndex); GetWorld()->GetGameState<ABattleGameState>()->DecreaseLivingTroopers(
PlayerIndex);
} else { } else {
// bIsTakingDamage = true; // bIsTakingDamage = true;
SetIsTakingDamage(true); SetIsTakingDamage(true);
} }
} }
TSubclassOf<AMyProjectile> ATrooper::GetProjectileClass( TSubclassOf<AProjectile> ATrooper::GetProjectileClass(
uint8 AbilityIndex) const { uint8 AbilityIndex) const {
switch (AbilityIndex) { switch (AbilityIndex) {
case 1: case 1:
@ -327,7 +328,7 @@ TSubclassOf<AMyProjectile> ATrooper::GetProjectileClass(
case 2: case 2:
return SpecialProjectileClass; return SpecialProjectileClass;
default: default:
return AMyProjectile::StaticClass(); return AProjectile::StaticClass();
} }
} }
@ -346,7 +347,7 @@ void ATrooper::FireProjectile_Implementation() {
SpawnParameters.Instigator = GetInstigator(); SpawnParameters.Instigator = GetInstigator();
SpawnParameters.SpawnCollisionHandlingOverride = SpawnParameters.SpawnCollisionHandlingOverride =
ESpawnActorCollisionHandlingMethod::AlwaysSpawn; ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
AMyProjectile *Projectile = GetWorld()->SpawnActor<AMyProjectile>( AProjectile *Projectile = GetWorld()->SpawnActor<AProjectile>(
GetProjectileClass(CurrentAbilityIndex), SpawnTransform, GetProjectileClass(CurrentAbilityIndex), SpawnTransform,
SpawnParameters); SpawnParameters);
Projectile->SetActorLocation(SpawnLocation); Projectile->SetActorLocation(SpawnLocation);

@ -2,7 +2,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Ability.h" #include "Ability.h"
#include "EnemyAIController.h" #include "../Singleplayer/EnemyAIController.h"
#include "GameFramework/Character.h" #include "GameFramework/Character.h"
#include "Trooper.generated.h" #include "Trooper.generated.h"
@ -31,7 +31,8 @@ public:
bool CheckMoveCorrectness(const FVector newPos) const; bool CheckMoveCorrectness(const FVector newPos) const;
UFUNCTION() UFUNCTION()
bool CheckAttackCorrectness(const FVector attackLocation, int abilityIndex) const; bool CheckAttackCorrectness(const FVector attackLocation,
int abilityIndex) const;
UFUNCTION() UFUNCTION()
FVector GetLocation() const; FVector GetLocation() const;
@ -97,13 +98,13 @@ protected:
UAbility *SpecialAbility; UAbility *SpecialAbility;
UPROPERTY(EditAnywhere, BlueprintReadWrite) UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<AMyProjectile> AttackProjectileClass; TSubclassOf<AProjectile> AttackProjectileClass;
UPROPERTY(EditAnywhere, BlueprintReadWrite) UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<AMyProjectile> SpecialProjectileClass; TSubclassOf<AProjectile> SpecialProjectileClass;
UFUNCTION() UFUNCTION()
TSubclassOf<AMyProjectile> GetProjectileClass(uint8 AbilityIndex) const; TSubclassOf<AProjectile> GetProjectileClass(uint8 AbilityIndex) const;
UFUNCTION(Server, Reliable) UFUNCTION(Server, Reliable)
void FireProjectile(); void FireProjectile();

@ -1,34 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "GameOverWidget.h"
#include "MyGameInstanceSubsystem.h"
#include "Components/Button.h"
#include "Components/TextBlock.h"
#include "Kismet/GameplayStatics.h"
void UGameOverWidget::NativeConstruct()
{
ButtonToMenu->OnClicked.AddDynamic(this, &ThisClass::QuitCurrentSession);
}
void UGameOverWidget::QuitCurrentSession()
{
const UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(GetWorld());
UMyGameInstanceSubsystem* GameInstanceSubsystem = GameInstance->GetSubsystem<UMyGameInstanceSubsystem>();
GameInstanceSubsystem->QuitCurrentSession();
}
void UGameOverWidget::SetWidgetText_Implementation(bool HasWon)
{
if (HasWon)
{
GameOverText->SetText(FText::FromString("You won!"));
}
else
{
GameOverText->SetText(FText::FromString("You lose!"));
}
}

@ -0,0 +1,34 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "MainMenuWidget.h"
#include "Components/Button.h"
#include "Kismet/GameplayStatics.h"
void UMainMenuWidget::NativeConstruct() {
Super::NativeConstruct();
HostOnlineGameButton->OnClicked.AddDynamic(
this, &ThisClass::UMainMenuWidget::OnHostOnlineGameButtonClicked);
GetMyGameSubsystem()->OnCreateSessionCompleteEvent.AddDynamic(
this, &ThisClass::StartSessionWhenCreatingSessonComplete);
}
void UMainMenuWidget::OnHostOnlineGameButtonClicked() {
GetMyGameSubsystem()->CreateSession(
"Lobby " + FString::FromInt(FMath::RandRange(1, 1e6)), 2, true);
}
void UMainMenuWidget::StartSessionWhenCreatingSessonComplete(bool bSuccess) {
GetMyGameSubsystem()->StartSession();
}
USessionsGameInstanceSubsystem *UMainMenuWidget::GetMyGameSubsystem() const {
const UGameInstance *GameInstance = UGameplayStatics::GetGameInstance(
GetWorld());
USessionsGameInstanceSubsystem *GameInstanceSubsystem = GameInstance->
GetSubsystem<USessionsGameInstanceSubsystem>();
return GameInstanceSubsystem;
}

@ -0,0 +1,33 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "../SessionsGameInstanceSubsystem.h"
#include "MainMenuWidget.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API UMainMenuWidget : public UUserWidget {
GENERATED_BODY()
public:
UPROPERTY(meta = (BindWidget))
class UButton *HostOnlineGameButton;
virtual void NativeConstruct() override;
protected:
UFUNCTION()
void OnHostOnlineGameButtonClicked();
UFUNCTION()
void StartSessionWhenCreatingSessonComplete(bool bSuccess);
private:
USessionsGameInstanceSubsystem *GetMyGameSubsystem() const;
};

@ -0,0 +1,24 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "SessionListEntryWidget.h"
#include "OnlineSessionSettings.h"
#include "Components/TextBlock.h"
void USessionListEntryWidget::Update(int SessionIndex,
const FOnlineSessionSearchResult &
Session) {
SessionId = SessionIndex;
IndexText->SetText(FText::AsNumber(SessionIndex + 1));
Session.Session.SessionSettings.Get(SETTING_MAPNAME, SessionName);
SessionNameText->SetText(FText::FromString(SessionName));
const int MaxPlayerCount = Session.Session.SessionSettings.
NumPublicConnections;
const int CurPlayerCount = MaxPlayerCount - Session.Session.
NumOpenPublicConnections;
PlayersCountText->SetText(FText::AsNumber(CurPlayerCount));
PingText->SetText(FText::AsNumber(Session.PingInMs));
}

@ -0,0 +1,33 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "SessionListEntryWidget.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API USessionListEntryWidget : public UUserWidget {
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UTextBlock *IndexText;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UTextBlock *SessionNameText;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UTextBlock *PlayersCountText;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UTextBlock *PingText;
void Update(int SessionIndex, const FOnlineSessionSearchResult &Session);
int SessionId;
FString SessionName;
};

@ -0,0 +1,80 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "SessionListWidget.h"
#include "../SessionsGameInstanceSubsystem.h"
#include "Components/VerticalBox.h"
#include "SessionListEntryWidget.h"
#include "Components/Button.h"
#include "Kismet/GameplayStatics.h"
void USessionListWidget::NativeConstruct() {
Super::NativeConstruct();
RefreshListButton->OnClicked.AddDynamic(
this, &ThisClass::OnRefreshListButtonClicked);
ConnectToSelectedSessionButton->OnClicked.AddDynamic(
this, &ThisClass::ConnectToFirstSession);
const auto MyGameInstanceSubsystem = GetMyGameSubsystem();
MyGameInstanceSubsystem->OnFindSessionsCompleteEvent.AddUObject(
this, &ThisClass::RefreshList);
MyGameInstanceSubsystem->OnJoinSessionCompleteEvent.AddUObject(
this, &ThisClass::OnJoinSessionSuccess);
// Initiate search
MyGameInstanceSubsystem->FindSessions(10, true);
}
void USessionListWidget::RefreshList(
const TArray<FOnlineSessionSearchResult> &SessionResults,
bool bSuccessful) {
if (!bSuccessful) {
UE_LOG(LogTemp, Error, TEXT("Find sessions FAILED!!!!"));
// TODO: Mark find sessions error
return;
}
SessionListBox->ClearChildren();
for (const auto &Session : SessionResults) {
auto *ItemWidget = CreateWidget<USessionListEntryWidget>(
this, EntryClass);
ItemWidget->Update(SessionListBox->GetChildrenCount(), Session);
SessionListBox->AddChild(ItemWidget);
}
}
void USessionListWidget::OnRefreshListButtonClicked() {
// TODO: Show that we started searching...
// Initiate search
SessionListBox->ClearChildren();
GetMyGameSubsystem()->FindSessions(10, true);
}
void USessionListWidget::ConnectToFirstSession() {
GetMyGameSubsystem()->JoinSession(0);
}
void USessionListWidget::OnJoinSessionSuccess(
EOnJoinSessionCompleteResult::Type Result) {
if (Result != EOnJoinSessionCompleteResult::Success) {
UE_LOG(LogTemp, Error, TEXT("Failed to connect to session!!"));
return;
}
if (!GetMyGameSubsystem()->TryConnectToCurrentSession()) {
UE_LOG(LogTemp, Error, TEXT("Failed to travel client to session!!"));
return;
}
UE_LOG(LogTemp, Display, TEXT("Connected and travelled to session!!!"));
}
USessionsGameInstanceSubsystem *
USessionListWidget::GetMyGameSubsystem() const {
const UGameInstance *GameInstance = UGameplayStatics::GetGameInstance(
GetWorld());
USessionsGameInstanceSubsystem *GameInstanceSubsystem = GameInstance->
GetSubsystem<USessionsGameInstanceSubsystem>();
return GameInstanceSubsystem;
}

@ -0,0 +1,48 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "../SessionsGameInstanceSubsystem.h"
#include "Blueprint/UserWidget.h"
#include "SessionListWidget.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API USessionListWidget : public UUserWidget {
GENERATED_BODY()
protected:
virtual void NativeConstruct() override;
UPROPERTY(meta = (BindWidget))
class UButton *ConnectToSelectedSessionButton;
UPROPERTY(meta = (BindWidget))
class UButton *GoBackToMainMenuButton;
UPROPERTY(meta = (BindWidget))
class UButton *RefreshListButton;
UPROPERTY(meta = (BindWidget))
class UVerticalBox *SessionListBox;
UPROPERTY(EditDefaultsOnly, Category="Session Info Class")
TSubclassOf<class USessionListEntryWidget> EntryClass;
void RefreshList(const TArray<FOnlineSessionSearchResult> &SessionResults,
bool bSuccessful);
void OnJoinSessionSuccess(EOnJoinSessionCompleteResult::Type Result);
private:
USessionsGameInstanceSubsystem *GetMyGameSubsystem() const;
UFUNCTION()
void OnRefreshListButtonClicked();
UFUNCTION()
void ConnectToFirstSession();
};

@ -3,7 +3,8 @@
#include "ManageSquadTrooper.h" #include "ManageSquadTrooper.h"
AManageSquadTrooper::AManageSquadTrooper() { AManageSquadTrooper::AManageSquadTrooper() {
GetMesh()->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap); GetMesh()->SetCollisionResponseToAllChannels(
ECollisionResponse::ECR_Overlap);
} }
// Called when the game starts or when spawned // Called when the game starts or when spawned
@ -17,7 +18,7 @@ void AManageSquadTrooper::Tick(float DeltaTime) {
} }
void AManageSquadTrooper:: void AManageSquadTrooper::
ChangeSkeletalMesh(const AManageSquadTrooper *OtherTrooper) { ChangeSkeletalMesh(const AManageSquadTrooper *OtherTrooper) const {
GetMesh()->SetSkeletalMesh(OtherTrooper->GetMesh()->SkeletalMesh); GetMesh()->SetSkeletalMesh(OtherTrooper->GetMesh()->SkeletalMesh);
} }

@ -33,7 +33,7 @@ public:
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;
UFUNCTION() UFUNCTION()
void ChangeSkeletalMesh(const AManageSquadTrooper *OtherTrooper); void ChangeSkeletalMesh(const AManageSquadTrooper *OtherTrooper) const;
UFUNCTION() UFUNCTION()
ETrooperType GetType() const; ETrooperType GetType() const;

@ -1,368 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyGameInstanceSubsystem.h"
#include "MyPlayerController.h"
#include "OnlineSubsystemUtils.h"
#include "GameFramework/GameModeBase.h"
#include "Kismet/GameplayStatics.h"
UMyGameInstanceSubsystem::UMyGameInstanceSubsystem() : CreateSessionCompleteDelegate(
FOnCreateSessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnCreateSessionCompleted)),
UpdateSessionCompleteDelegate(
FOnUpdateSessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnUpdateSessionCompleted)),
StartSessionCompleteDelegate(
FOnStartSessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnStartSessionCompleted)),
EndSessionCompleteDelegate(
FOnEndSessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnEndSessionCompleted)),
DestroySessionCompleteDelegate(
FOnDestroySessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnDestroySessionCompleted)),
FindSessionsCompleteDelegate(
FOnFindSessionsCompleteDelegate::CreateUObject(
this, &ThisClass::OnFindSessionsCompleted)),
JoinSessionCompleteDelegate(
FOnJoinSessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnJoinSessionCompleted)),
bIsHost(false)
{
}
void UMyGameInstanceSubsystem::CreateSession(FString SessionName, int32 NumPublicConnections, bool bIsLANMatch)
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (!SessionInterface.IsValid())
{
OnCreateSessionCompleteEvent.Broadcast(false);
return;
}
LastSessionSettings = MakeShareable(new FOnlineSessionSettings());
LastSessionSettings->NumPrivateConnections = 0;
LastSessionSettings->NumPublicConnections = NumPublicConnections;
LastSessionSettings->bAllowInvites = true;
LastSessionSettings->bAllowJoinInProgress = true;
LastSessionSettings->bAllowJoinViaPresence = true;
LastSessionSettings->bAllowJoinViaPresenceFriendsOnly = true;
LastSessionSettings->bUsesPresence = true;
LastSessionSettings->bIsLANMatch = bIsLANMatch;
LastSessionSettings->bShouldAdvertise = true;
LastSessionSettings->Set(SETTING_MAPNAME, SessionName,
EOnlineDataAdvertisementType::ViaOnlineService);
CreateSessionCompleteDelegateHandle = SessionInterface->AddOnCreateSessionCompleteDelegate_Handle(
CreateSessionCompleteDelegate);
const ULocalPlayer* localPlayer = GetWorld()->GetFirstLocalPlayerFromController();
if (!SessionInterface->CreateSession(*localPlayer->GetPreferredUniqueNetId(), NAME_GameSession,
*LastSessionSettings))
{
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
OnCreateSessionCompleteEvent.Broadcast(false);
}
}
void UMyGameInstanceSubsystem::OnCreateSessionCompleted(FName SessionName, bool bSuccessful)
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (SessionInterface.IsValid())
{
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
}
bIsHost = true;
OnCreateSessionCompleteEvent.Broadcast(bSuccessful);
}
void UMyGameInstanceSubsystem::UpdateSession()
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (!SessionInterface.IsValid())
{
OnCreateSessionCompleteEvent.Broadcast(false);
return;
}
const TSharedPtr<FOnlineSessionSettings> UpdatedSessionSettings = MakeShareable(
new FOnlineSessionSettings(*LastSessionSettings));
// Here we can insert any changes we want
UpdatedSessionSettings->Set(SETTING_MAPNAME, FString("Updated Level Name"),
EOnlineDataAdvertisementType::ViaOnlineService);
UpdateSessionCompleteDelegateHandle =
SessionInterface->AddOnUpdateSessionCompleteDelegate_Handle(UpdateSessionCompleteDelegate);
if (!SessionInterface->UpdateSession(NAME_GameSession, *UpdatedSessionSettings))
{
SessionInterface->ClearOnUpdateSessionCompleteDelegate_Handle(UpdateSessionCompleteDelegateHandle);
OnUpdateSessionCompleteEvent.Broadcast(false);
}
else
{
LastSessionSettings = UpdatedSessionSettings;
}
}
void UMyGameInstanceSubsystem::OnUpdateSessionCompleted(FName SessionName, bool bSuccessful)
{
const IOnlineSessionPtr sessionInterface = Online::GetSessionInterface(GetWorld());
if (sessionInterface.IsValid())
{
sessionInterface->ClearOnUpdateSessionCompleteDelegate_Handle(UpdateSessionCompleteDelegateHandle);
}
OnUpdateSessionCompleteEvent.Broadcast(bSuccessful);
}
void UMyGameInstanceSubsystem::StartSession()
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (!SessionInterface.IsValid())
{
OnCreateSessionCompleteEvent.Broadcast(false);
return;
}
StartSessionCompleteDelegateHandle = SessionInterface->AddOnStartSessionCompleteDelegate_Handle(
StartSessionCompleteDelegate);
if (!SessionInterface->StartSession(NAME_GameSession))
{
SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(StartSessionCompleteDelegateHandle);
OnStartSessionCompleteEvent.Broadcast(false);
}
}
void UMyGameInstanceSubsystem::OnStartSessionCompleted(FName SessionName, bool bSuccessful)
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (SessionInterface.IsValid())
{
SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(StartSessionCompleteDelegateHandle);
}
OnStartSessionCompleteEvent.Broadcast(bSuccessful);
// TODO: Move this from gameinstance subsystem. This should not be here.
UGameplayStatics::OpenLevel(GetWorld(), "BattleFieldMap", true, "listen");
}
void UMyGameInstanceSubsystem::EndSession()
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (!SessionInterface.IsValid())
{
OnCreateSessionCompleteEvent.Broadcast(false);
return;
}
EndSessionCompleteDelegateHandle = SessionInterface->AddOnEndSessionCompleteDelegate_Handle(
EndSessionCompleteDelegate);
if (!SessionInterface->EndSession(NAME_GameSession))
{
SessionInterface->ClearOnEndSessionCompleteDelegate_Handle(EndSessionCompleteDelegateHandle);
OnEndSessionCompleteEvent.Broadcast(false);
}
}
void UMyGameInstanceSubsystem::OnEndSessionCompleted(FName SessionName, bool bSuccessful)
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (SessionInterface.IsValid())
{
SessionInterface->ClearOnEndSessionCompleteDelegate_Handle(EndSessionCompleteDelegateHandle);
}
OnEndSessionCompleteEvent.Broadcast(bSuccessful);
}
void UMyGameInstanceSubsystem::DestroySession()
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (!SessionInterface.IsValid())
{
OnDestroySessionCompleteEvent.Broadcast(false);
return;
}
DestroySessionCompleteDelegateHandle = SessionInterface->AddOnDestroySessionCompleteDelegate_Handle(
DestroySessionCompleteDelegate);
if (!SessionInterface->DestroySession(NAME_GameSession))
{
SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(EndSessionCompleteDelegateHandle);
OnDestroySessionCompleteEvent.Broadcast(false);
}
}
void UMyGameInstanceSubsystem::OnDestroySessionCompleted(FName SessionName, bool bSuccessful)
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (SessionInterface.IsValid())
{
SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(DestroySessionCompleteDelegateHandle);
}
OnDestroySessionCompleteEvent.Broadcast(bSuccessful);
}
void UMyGameInstanceSubsystem::FindSessions(int32 MaxSearchResults, bool bIsLANQuery)
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (!SessionInterface.IsValid())
{
OnFindSessionsCompleteEvent.Broadcast(TArray<FOnlineSessionSearchResult>(), false);
return;
}
FindSessionsCompleteDelegateHandle = SessionInterface->AddOnFindSessionsCompleteDelegate_Handle(
FindSessionsCompleteDelegate);
LastSessionSearch = MakeShareable(new FOnlineSessionSearch());
LastSessionSearch->MaxSearchResults = MaxSearchResults;
LastSessionSearch->bIsLanQuery = bIsLANQuery;
// Disable dedicated server search (maybe enable later, when dedicated server is implemented)
// LastSessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
if (!SessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(), LastSessionSearch.ToSharedRef()))
{
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegateHandle);
OnFindSessionsCompleteEvent.Broadcast(TArray<FOnlineSessionSearchResult>(), false);
}
}
void UMyGameInstanceSubsystem::OnFindSessionsCompleted(bool bSuccessful)
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (SessionInterface.IsValid())
{
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegateHandle);
}
if (LastSessionSearch->SearchResults.Num() <= 0)
{
OnFindSessionsCompleteEvent.Broadcast(TArray<FOnlineSessionSearchResult>(), bSuccessful);
return;
}
OnFindSessionsCompleteEvent.Broadcast(LastSessionSearch->SearchResults, bSuccessful);
}
void UMyGameInstanceSubsystem::JoinSession(const FOnlineSessionSearchResult& SessionSearchResult)
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (!SessionInterface.IsValid())
{
OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
return;
}
JoinSessionCompleteDelegateHandle = SessionInterface->AddOnJoinSessionCompleteDelegate_Handle(
JoinSessionCompleteDelegate);
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
if (!SessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, SessionSearchResult))
{
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
}
}
void UMyGameInstanceSubsystem::JoinSession(const int32 Index)
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (!SessionInterface.IsValid())
{
OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
return;
}
if (!LastSessionSearch.IsValid() || Index >= LastSessionSearch->SearchResults.Num())
{
OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
return;
}
JoinSessionCompleteDelegateHandle = SessionInterface->AddOnJoinSessionCompleteDelegate_Handle(
JoinSessionCompleteDelegate);
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
if (!SessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession,
LastSessionSearch->SearchResults[Index]))
{
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
}
}
void UMyGameInstanceSubsystem::OnJoinSessionCompleted(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (SessionInterface.IsValid())
{
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
}
OnJoinSessionCompleteEvent.Broadcast(Result);
}
bool UMyGameInstanceSubsystem::TryConnectToCurrentSession() const
{
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
if (!SessionInterface.IsValid())
{
return false;
}
FString ConnectString;
if (!SessionInterface->GetResolvedConnectString(NAME_GameSession, ConnectString))
{
return false;
}
APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
PlayerController->ClientTravel(ConnectString, TRAVEL_Absolute);
return true;
}
void UMyGameInstanceSubsystem::QuitCurrentSession()
{
if (bIsHost)
{
UGameplayStatics::GetGameMode(GetWorld())->ReturnToMainMenuHost();
}
else
{
APlayerController* LocalController = GEngine->GetFirstLocalPlayerController(GetWorld());
LocalController->ClientReturnToMainMenuWithTextReason(FText::FromString("Session ended"));
}
bIsHost = false;
DestroySession();
}

@ -1,107 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "OnlineSessionSettings.h"
#include "Interfaces/OnlineSessionInterface.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "MyGameInstanceSubsystem.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnCreateSessionComplete, bool, bSuccessful);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnUpdateSessionComplete, bool, bSuccessful);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnStartSessionCompete, bool, bSuccessful);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnEndSessionComplete, bool, bSuccessful);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnDestroySessionComplete, bool, bSuccessful);
DECLARE_MULTICAST_DELEGATE_TwoParams(FMyOnFindSessionsComplete,
const TArray<FOnlineSessionSearchResult>& SessionResults, bool bSuccessful);
DECLARE_MULTICAST_DELEGATE_OneParam(FMyOnJoinSessionCompele, EOnJoinSessionCompleteResult::Type Result);
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API UMyGameInstanceSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
UMyGameInstanceSubsystem();
void CreateSession(FString SessionName, int32 NumPublicConnections, bool bIsLANMatch);
void UpdateSession();
void StartSession();
void EndSession();
void DestroySession();
void FindSessions(int32 MaxSearchResults, bool bIsLANQuery);
void JoinSession(const FOnlineSessionSearchResult& SessionSearchResult);
void JoinSession(const int32 Index);
bool TryConnectToCurrentSession() const;
void QuitCurrentSession();
void UpdateSessionName(FString NewSessionName);
FMyOnCreateSessionComplete OnCreateSessionCompleteEvent;
FMyOnUpdateSessionComplete OnUpdateSessionCompleteEvent;
FMyOnStartSessionCompete OnStartSessionCompleteEvent;
FMyOnEndSessionComplete OnEndSessionCompleteEvent;
FMyOnDestroySessionComplete OnDestroySessionCompleteEvent;
FMyOnFindSessionsComplete OnFindSessionsCompleteEvent;
FMyOnJoinSessionCompele OnJoinSessionCompleteEvent;
protected:
void OnCreateSessionCompleted(FName SessionName, bool bSuccessful);
void OnUpdateSessionCompleted(FName SessionName, bool bSuccessful);
void OnStartSessionCompleted(FName SessionName, bool bSuccessful);
void OnEndSessionCompleted(FName SessionName, bool bSuccessful);
void OnDestroySessionCompleted(FName SessionName, bool bSuccessful);
void OnFindSessionsCompleted(bool bSuccessful);
void OnJoinSessionCompleted(FName SessionName, EOnJoinSessionCompleteResult::Type Result);
private:
bool bIsHost;
FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate;
FDelegateHandle CreateSessionCompleteDelegateHandle;
TSharedPtr<FOnlineSessionSettings> LastSessionSettings;
FOnUpdateSessionCompleteDelegate UpdateSessionCompleteDelegate;
FDelegateHandle UpdateSessionCompleteDelegateHandle;
FOnStartSessionCompleteDelegate StartSessionCompleteDelegate;
FDelegateHandle StartSessionCompleteDelegateHandle;
FOnEndSessionCompleteDelegate EndSessionCompleteDelegate;
FDelegateHandle EndSessionCompleteDelegateHandle;
FOnDestroySessionCompleteDelegate DestroySessionCompleteDelegate;
FDelegateHandle DestroySessionCompleteDelegateHandle;
FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate;
FDelegateHandle FindSessionsCompleteDelegateHandle;
TSharedPtr<FOnlineSessionSearch> LastSessionSearch;
FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate;
FDelegateHandle JoinSessionCompleteDelegateHandle;
};

@ -1,35 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyMainMenu.h"
#include "Components/Button.h"
#include "Kismet/GameplayStatics.h"
void UMyMainMenu::NativeConstruct()
{
Super::NativeConstruct();
HostOnlineGameButton->OnClicked.AddDynamic(this, &ThisClass::UMyMainMenu::OnHostOnlineGameButtonClicked);
GetMyGameSubsystem()->OnCreateSessionCompleteEvent.AddDynamic(this, &ThisClass::StartSessionWhenCreatingSessonComplete);
}
void UMyMainMenu::OnHostOnlineGameButtonClicked()
{
GetMyGameSubsystem()->CreateSession("Lobby " + FString::FromInt(FMath::RandRange(1, 1e6)),2, true);
}
void UMyMainMenu::StartSessionWhenCreatingSessonComplete(bool bSuccess)
{
GetMyGameSubsystem()->StartSession();
}
UMyGameInstanceSubsystem* UMyMainMenu::GetMyGameSubsystem() const
{
const UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(GetWorld());
UMyGameInstanceSubsystem* GameInstanceSubsystem = GameInstance->GetSubsystem<UMyGameInstanceSubsystem>();
return GameInstanceSubsystem;
}

@ -1,34 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "MyGameInstanceSubsystem.h"
#include "MyMainMenu.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API UMyMainMenu : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(meta = (BindWidget))
class UButton* HostOnlineGameButton;
virtual void NativeConstruct() override;
protected:
UFUNCTION()
void OnHostOnlineGameButtonClicked();
UFUNCTION()
void StartSessionWhenCreatingSessonComplete(bool bSuccess);
private:
UMyGameInstanceSubsystem* GetMyGameSubsystem() const;
};

@ -1,23 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "MySessionListEntryWidget.h"
#include "OnlineSessionSettings.h"
#include "Interfaces/OnlineSessionInterface.h"
#include "Components/TextBlock.h"
void UMySessionListEntryWidget::Update(int SessionIndex, const FOnlineSessionSearchResult& Session)
{
SessionId = SessionIndex;
IndexText->SetText(FText::AsNumber(SessionIndex + 1));
Session.Session.SessionSettings.Get(SETTING_MAPNAME, SessionName);
SessionNameText->SetText(FText::FromString(SessionName));
int MaxPlayerCount = Session.Session.SessionSettings.NumPublicConnections;
int CurPlayerCount = MaxPlayerCount - Session.Session.NumOpenPublicConnections;
PlayersCountText->SetText(FText::AsNumber(CurPlayerCount));
PingText->SetText(FText::AsNumber(Session.PingInMs));
}

@ -1,35 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Interfaces/OnlineSessionInterface.h"
#include "Blueprint/UserWidget.h"
#include "MySessionListEntryWidget.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API UMySessionListEntryWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UTextBlock* IndexText;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UTextBlock* SessionNameText;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UTextBlock* PlayersCountText;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
class UTextBlock* PingText;
void Update(int SessionIndex, const FOnlineSessionSearchResult& Session);
int SessionId;
FString SessionName;
};

@ -1,81 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "MySessionListWidget.h"
#include "MyGameInstanceSubsystem.h"
#include "Components/VerticalBox.h"
#include "MySessionListEntryWidget.h"
#include "Components/Button.h"
#include "Kismet/GameplayStatics.h"
void UMySessionListWidget::NativeConstruct()
{
Super::NativeConstruct();
RefreshListButton->OnClicked.AddDynamic(this, &ThisClass::OnRefreshListButtonClicked);
ConnectToSelectedSessionButton->OnClicked.AddDynamic(this, &ThisClass::ConnectToFirstSession);
const auto MyGameInstanceSubsystem = GetMyGameSubsystem();
MyGameInstanceSubsystem->OnFindSessionsCompleteEvent.AddUObject(this, &ThisClass::RefreshList);
MyGameInstanceSubsystem->OnJoinSessionCompleteEvent.AddUObject(this, &ThisClass::OnJoinSessionSuccess);
// Initiate search
MyGameInstanceSubsystem->FindSessions(10, true);
}
void UMySessionListWidget::RefreshList(const TArray<FOnlineSessionSearchResult>& SessionResults,
bool bSuccessful)
{
if (!bSuccessful)
{
UE_LOG(LogTemp, Error, TEXT("Find sessions FAILED!!!!"));
// TODO: Mark find sessions error
return;
}
SessionListBox->ClearChildren();
for (const auto &Session: SessionResults)
{
auto *ItemWidget = CreateWidget<UMySessionListEntryWidget>(this, EntryClass);
ItemWidget->Update(SessionListBox->GetChildrenCount(), Session);
SessionListBox->AddChild(ItemWidget);
}
}
void UMySessionListWidget::OnRefreshListButtonClicked()
{
// TODO: Show that we started searching...
// Initiate search
SessionListBox->ClearChildren();
GetMyGameSubsystem()->FindSessions(10, true);
}
void UMySessionListWidget::ConnectToFirstSession()
{
GetMyGameSubsystem()->JoinSession(0);
}
void UMySessionListWidget::OnJoinSessionSuccess(EOnJoinSessionCompleteResult::Type Result)
{
if (Result != EOnJoinSessionCompleteResult::Success)
{
UE_LOG(LogTemp, Error, TEXT("Failed to connect to session!!"));
return;
}
if (!GetMyGameSubsystem()->TryConnectToCurrentSession())
{
UE_LOG(LogTemp, Error, TEXT("Failed to travel client to session!!"));
return;
}
UE_LOG(LogTemp, Display, TEXT("Connected and travelled to session!!!"));
}
UMyGameInstanceSubsystem* UMySessionListWidget::GetMyGameSubsystem() const
{
const UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(GetWorld());
UMyGameInstanceSubsystem* GameInstanceSubsystem = GameInstance->GetSubsystem<UMyGameInstanceSubsystem>();
return GameInstanceSubsystem;
}

@ -1,49 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "MyGameInstanceSubsystem.h"
#include "Blueprint/UserWidget.h"
#include "MySessionListWidget.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API UMySessionListWidget : public UUserWidget
{
GENERATED_BODY()
protected:
virtual void NativeConstruct() override;
UPROPERTY(meta = (BindWidget))
class UButton* ConnectToSelectedSessionButton;
UPROPERTY(meta = (BindWidget))
class UButton* GoBackToMainMenuButton;
UPROPERTY(meta = (BindWidget))
class UButton* RefreshListButton;
UPROPERTY(meta = (BindWidget))
class UVerticalBox* SessionListBox;
UPROPERTY(EditDefaultsOnly, Category="Session Info Class")
TSubclassOf<class UMySessionListEntryWidget> EntryClass;
void RefreshList(const TArray<FOnlineSessionSearchResult>& SessionResults, bool bSuccessful);
void OnJoinSessionSuccess(EOnJoinSessionCompleteResult::Type Result);
private:
UMyGameInstanceSubsystem* GetMyGameSubsystem() const;
UFUNCTION()
void OnRefreshListButtonClicked();
UFUNCTION()
void ConnectToFirstSession();
};

@ -0,0 +1,399 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "SessionsGameInstanceSubsystem.h"
#include "BattleMode/BattlePlayerController.h"
#include "OnlineSubsystemUtils.h"
#include "GameFramework/GameModeBase.h"
#include "Kismet/GameplayStatics.h"
USessionsGameInstanceSubsystem::USessionsGameInstanceSubsystem()
: bIsHost(false),
CreateSessionCompleteDelegate(
FOnCreateSessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnCreateSessionCompleted)),
UpdateSessionCompleteDelegate(
FOnUpdateSessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnUpdateSessionCompleted)),
StartSessionCompleteDelegate(
FOnStartSessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnStartSessionCompleted)),
EndSessionCompleteDelegate(
FOnEndSessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnEndSessionCompleted)),
DestroySessionCompleteDelegate(
FOnDestroySessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnDestroySessionCompleted)),
FindSessionsCompleteDelegate(
FOnFindSessionsCompleteDelegate::CreateUObject(
this, &ThisClass::OnFindSessionsCompleted)),
JoinSessionCompleteDelegate(
FOnJoinSessionCompleteDelegate::CreateUObject(
this, &ThisClass::OnJoinSessionCompleted)) {
}
void USessionsGameInstanceSubsystem::CreateSession(FString SessionName,
int32 NumPublicConnections,
bool bIsLANMatch) {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (!SessionInterface.IsValid()) {
OnCreateSessionCompleteEvent.Broadcast(false);
return;
}
LastSessionSettings = MakeShareable(new FOnlineSessionSettings());
LastSessionSettings->NumPrivateConnections = 0;
LastSessionSettings->NumPublicConnections = NumPublicConnections;
LastSessionSettings->bAllowInvites = true;
LastSessionSettings->bAllowJoinInProgress = true;
LastSessionSettings->bAllowJoinViaPresence = true;
LastSessionSettings->bAllowJoinViaPresenceFriendsOnly = true;
LastSessionSettings->bUsesPresence = true;
LastSessionSettings->bIsLANMatch = bIsLANMatch;
LastSessionSettings->bShouldAdvertise = true;
LastSessionSettings->Set(SETTING_MAPNAME, SessionName,
EOnlineDataAdvertisementType::ViaOnlineService);
CreateSessionCompleteDelegateHandle = SessionInterface->
AddOnCreateSessionCompleteDelegate_Handle(
CreateSessionCompleteDelegate);
const ULocalPlayer *localPlayer = GetWorld()->
GetFirstLocalPlayerFromController();
if (!SessionInterface->CreateSession(
*localPlayer->GetPreferredUniqueNetId(), NAME_GameSession,
*LastSessionSettings)) {
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(
CreateSessionCompleteDelegateHandle);
OnCreateSessionCompleteEvent.Broadcast(false);
}
}
void USessionsGameInstanceSubsystem::OnCreateSessionCompleted(
FName SessionName,
bool bSuccessful) {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (SessionInterface.IsValid()) {
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(
CreateSessionCompleteDelegateHandle);
}
bIsHost = true;
OnCreateSessionCompleteEvent.Broadcast(bSuccessful);
}
void USessionsGameInstanceSubsystem::UpdateSession() {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (!SessionInterface.IsValid()) {
OnCreateSessionCompleteEvent.Broadcast(false);
return;
}
const TSharedPtr<FOnlineSessionSettings> UpdatedSessionSettings =
MakeShareable(
new FOnlineSessionSettings(*LastSessionSettings));
// Here we can insert any changes we want
UpdatedSessionSettings->Set(SETTING_MAPNAME, FString("Updated Level Name"),
EOnlineDataAdvertisementType::ViaOnlineService);
UpdateSessionCompleteDelegateHandle =
SessionInterface->AddOnUpdateSessionCompleteDelegate_Handle(
UpdateSessionCompleteDelegate);
if (!SessionInterface->UpdateSession(NAME_GameSession,
*UpdatedSessionSettings)) {
SessionInterface->ClearOnUpdateSessionCompleteDelegate_Handle(
UpdateSessionCompleteDelegateHandle);
OnUpdateSessionCompleteEvent.Broadcast(false);
} else {
LastSessionSettings = UpdatedSessionSettings;
}
}
void USessionsGameInstanceSubsystem::OnUpdateSessionCompleted(
FName SessionName,
bool bSuccessful) {
const IOnlineSessionPtr sessionInterface = Online::GetSessionInterface(
GetWorld());
if (sessionInterface.IsValid()) {
sessionInterface->ClearOnUpdateSessionCompleteDelegate_Handle(
UpdateSessionCompleteDelegateHandle);
}
OnUpdateSessionCompleteEvent.Broadcast(bSuccessful);
}
void USessionsGameInstanceSubsystem::StartSession() {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (!SessionInterface.IsValid()) {
OnCreateSessionCompleteEvent.Broadcast(false);
return;
}
StartSessionCompleteDelegateHandle = SessionInterface->
AddOnStartSessionCompleteDelegate_Handle(
StartSessionCompleteDelegate);
if (!SessionInterface->StartSession(NAME_GameSession)) {
SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(
StartSessionCompleteDelegateHandle);
OnStartSessionCompleteEvent.Broadcast(false);
}
}
void USessionsGameInstanceSubsystem::OnStartSessionCompleted(
FName SessionName,
bool bSuccessful) {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (SessionInterface.IsValid()) {
SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(
StartSessionCompleteDelegateHandle);
}
OnStartSessionCompleteEvent.Broadcast(bSuccessful);
// TODO: Move this from gameinstance subsystem. This should not be here.
UGameplayStatics::OpenLevel(GetWorld(), "BattleFieldMap", true, "listen");
}
void USessionsGameInstanceSubsystem::EndSession() {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (!SessionInterface.IsValid()) {
OnCreateSessionCompleteEvent.Broadcast(false);
return;
}
EndSessionCompleteDelegateHandle = SessionInterface->
AddOnEndSessionCompleteDelegate_Handle(
EndSessionCompleteDelegate);
if (!SessionInterface->EndSession(NAME_GameSession)) {
SessionInterface->ClearOnEndSessionCompleteDelegate_Handle(
EndSessionCompleteDelegateHandle);
OnEndSessionCompleteEvent.Broadcast(false);
}
}
void USessionsGameInstanceSubsystem::OnEndSessionCompleted(
FName SessionName,
bool bSuccessful) {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (SessionInterface.IsValid()) {
SessionInterface->ClearOnEndSessionCompleteDelegate_Handle(
EndSessionCompleteDelegateHandle);
}
OnEndSessionCompleteEvent.Broadcast(bSuccessful);
}
void USessionsGameInstanceSubsystem::DestroySession() {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (!SessionInterface.IsValid()) {
OnDestroySessionCompleteEvent.Broadcast(false);
return;
}
DestroySessionCompleteDelegateHandle = SessionInterface->
AddOnDestroySessionCompleteDelegate_Handle(
DestroySessionCompleteDelegate);
if (!SessionInterface->DestroySession(NAME_GameSession)) {
SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(
EndSessionCompleteDelegateHandle);
OnDestroySessionCompleteEvent.Broadcast(false);
}
}
void USessionsGameInstanceSubsystem::OnDestroySessionCompleted(
FName SessionName,
bool bSuccessful) {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (SessionInterface.IsValid()) {
SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(
DestroySessionCompleteDelegateHandle);
}
OnDestroySessionCompleteEvent.Broadcast(bSuccessful);
}
void USessionsGameInstanceSubsystem::FindSessions(int32 MaxSearchResults,
bool bIsLANQuery) {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (!SessionInterface.IsValid()) {
OnFindSessionsCompleteEvent.Broadcast(
TArray<FOnlineSessionSearchResult>(), false);
return;
}
FindSessionsCompleteDelegateHandle = SessionInterface->
AddOnFindSessionsCompleteDelegate_Handle(
FindSessionsCompleteDelegate);
LastSessionSearch = MakeShareable(new FOnlineSessionSearch());
LastSessionSearch->MaxSearchResults = MaxSearchResults;
LastSessionSearch->bIsLanQuery = bIsLANQuery;
// Disable dedicated server search (maybe enable later, when dedicated server is implemented)
// LastSessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
const ULocalPlayer *LocalPlayer = GetWorld()->
GetFirstLocalPlayerFromController();
if (!SessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(),
LastSessionSearch.ToSharedRef())) {
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(
FindSessionsCompleteDelegateHandle);
OnFindSessionsCompleteEvent.Broadcast(
TArray<FOnlineSessionSearchResult>(), false);
}
}
void USessionsGameInstanceSubsystem::OnFindSessionsCompleted(bool bSuccessful) {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (SessionInterface.IsValid()) {
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(
FindSessionsCompleteDelegateHandle);
}
if (LastSessionSearch->SearchResults.Num() <= 0) {
OnFindSessionsCompleteEvent.Broadcast(
TArray<FOnlineSessionSearchResult>(), bSuccessful);
return;
}
OnFindSessionsCompleteEvent.Broadcast(LastSessionSearch->SearchResults,
bSuccessful);
}
void USessionsGameInstanceSubsystem::JoinSession(
const FOnlineSessionSearchResult &SessionSearchResult) {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (!SessionInterface.IsValid()) {
OnJoinSessionCompleteEvent.Broadcast(
EOnJoinSessionCompleteResult::UnknownError);
return;
}
JoinSessionCompleteDelegateHandle = SessionInterface->
AddOnJoinSessionCompleteDelegate_Handle(
JoinSessionCompleteDelegate);
const ULocalPlayer *LocalPlayer = GetWorld()->
GetFirstLocalPlayerFromController();
if (!SessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(),
NAME_GameSession, SessionSearchResult)) {
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(
JoinSessionCompleteDelegateHandle);
OnJoinSessionCompleteEvent.Broadcast(
EOnJoinSessionCompleteResult::UnknownError);
}
}
void USessionsGameInstanceSubsystem::JoinSession(const int32 Index) {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (!SessionInterface.IsValid()) {
OnJoinSessionCompleteEvent.Broadcast(
EOnJoinSessionCompleteResult::UnknownError);
return;
}
if (!LastSessionSearch.IsValid() || Index >= LastSessionSearch->
SearchResults.Num()) {
OnJoinSessionCompleteEvent.Broadcast(
EOnJoinSessionCompleteResult::UnknownError);
return;
}
JoinSessionCompleteDelegateHandle = SessionInterface->
AddOnJoinSessionCompleteDelegate_Handle(
JoinSessionCompleteDelegate);
const ULocalPlayer *LocalPlayer = GetWorld()->
GetFirstLocalPlayerFromController();
if (!SessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(),
NAME_GameSession,
LastSessionSearch->SearchResults[
Index])) {
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(
JoinSessionCompleteDelegateHandle);
OnJoinSessionCompleteEvent.Broadcast(
EOnJoinSessionCompleteResult::UnknownError);
}
}
void USessionsGameInstanceSubsystem::OnJoinSessionCompleted(
FName SessionName,
EOnJoinSessionCompleteResult::Type Result) {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (SessionInterface.IsValid()) {
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(
JoinSessionCompleteDelegateHandle);
}
OnJoinSessionCompleteEvent.Broadcast(Result);
}
bool USessionsGameInstanceSubsystem::TryConnectToCurrentSession() const {
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
GetWorld());
if (!SessionInterface.IsValid()) {
return false;
}
FString ConnectString;
if (!SessionInterface->GetResolvedConnectString(
NAME_GameSession, ConnectString)) {
return false;
}
APlayerController *PlayerController = GetWorld()->
GetFirstPlayerController();
PlayerController->ClientTravel(ConnectString, TRAVEL_Absolute);
return true;
}
void USessionsGameInstanceSubsystem::QuitCurrentSession() {
if (bIsHost) {
UGameplayStatics::GetGameMode(GetWorld())->ReturnToMainMenuHost();
} else {
APlayerController *LocalController = GEngine->
GetFirstLocalPlayerController(GetWorld());
LocalController->ClientReturnToMainMenuWithTextReason(
FText::FromString("Session ended"));
}
bIsHost = false;
DestroySession();
}

@ -0,0 +1,116 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "OnlineSessionSettings.h"
#include "Interfaces/OnlineSessionInterface.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "SessionsGameInstanceSubsystem.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnCreateSessionComplete, bool,
bSuccessful);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnUpdateSessionComplete, bool,
bSuccessful);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnStartSessionCompete, bool,
bSuccessful);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnEndSessionComplete, bool,
bSuccessful);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnDestroySessionComplete, bool,
bSuccessful);
DECLARE_MULTICAST_DELEGATE_TwoParams(FMyOnFindSessionsComplete,
const TArray<FOnlineSessionSearchResult>&
SessionResults, bool bSuccessful);
DECLARE_MULTICAST_DELEGATE_OneParam(FMyOnJoinSessionCompele,
EOnJoinSessionCompleteResult::Type Result);
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API USessionsGameInstanceSubsystem
: public UGameInstanceSubsystem {
GENERATED_BODY()
public:
USessionsGameInstanceSubsystem();
void CreateSession(FString SessionName,
int32 NumPublicConnections,
bool bIsLANMatch);
void UpdateSession();
void StartSession();
void EndSession();
void DestroySession();
void FindSessions(int32 MaxSearchResults, bool bIsLANQuery);
void JoinSession(const FOnlineSessionSearchResult &SessionSearchResult);
void JoinSession(const int32 Index);
bool TryConnectToCurrentSession() const;
void QuitCurrentSession();
void UpdateSessionName(FString NewSessionName);
FMyOnCreateSessionComplete OnCreateSessionCompleteEvent;
FMyOnUpdateSessionComplete OnUpdateSessionCompleteEvent;
FMyOnStartSessionCompete OnStartSessionCompleteEvent;
FMyOnEndSessionComplete OnEndSessionCompleteEvent;
FMyOnDestroySessionComplete OnDestroySessionCompleteEvent;
FMyOnFindSessionsComplete OnFindSessionsCompleteEvent;
FMyOnJoinSessionCompele OnJoinSessionCompleteEvent;
protected:
void OnCreateSessionCompleted(FName SessionName, bool bSuccessful);
void OnUpdateSessionCompleted(FName SessionName, bool bSuccessful);
void OnStartSessionCompleted(FName SessionName, bool bSuccessful);
void OnEndSessionCompleted(FName SessionName, bool bSuccessful);
void OnDestroySessionCompleted(FName SessionName, bool bSuccessful);
void OnFindSessionsCompleted(bool bSuccessful);
void OnJoinSessionCompleted(FName SessionName,
EOnJoinSessionCompleteResult::Type Result);
private:
bool bIsHost;
FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate;
FDelegateHandle CreateSessionCompleteDelegateHandle;
TSharedPtr<FOnlineSessionSettings> LastSessionSettings;
FOnUpdateSessionCompleteDelegate UpdateSessionCompleteDelegate;
FDelegateHandle UpdateSessionCompleteDelegateHandle;
FOnStartSessionCompleteDelegate StartSessionCompleteDelegate;
FDelegateHandle StartSessionCompleteDelegateHandle;
FOnEndSessionCompleteDelegate EndSessionCompleteDelegate;
FDelegateHandle EndSessionCompleteDelegateHandle;
FOnDestroySessionCompleteDelegate DestroySessionCompleteDelegate;
FDelegateHandle DestroySessionCompleteDelegateHandle;
FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate;
FDelegateHandle FindSessionsCompleteDelegateHandle;
TSharedPtr<FOnlineSessionSearch> LastSessionSearch;
FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate;
FDelegateHandle JoinSessionCompleteDelegateHandle;
};

@ -3,4 +3,5 @@
#include "TurnBasedTutorial.h" #include "TurnBasedTutorial.h"
#include "Modules/ModuleManager.h" #include "Modules/ModuleManager.h"
IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, TurnBasedTutorial, "TurnBasedTutorial" ); IMPLEMENT_PRIMARY_GAME_MODULE(FDefaultGameModuleImpl, TurnBasedTutorial,
"TurnBasedTutorial");

@ -3,4 +3,3 @@
#pragma once #pragma once
#include "Core.h" #include "Core.h"

Loading…
Cancel
Save