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")
+ActiveClassRedirects=(OldClassName="TP_BlankGameModeBase",NewClassName="TurnBasedTutorialGameModeBase")
[CoreRedirects]
+PropertyRedirects=(OldName="/Script/TurnBasedTutorial.Trooper.OnPlayersSide",NewName="/Script/TurnBasedTutorial.Trooper.bOnPlayersSide")
+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")
+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]
DefaultPlatformService=Null

Binary file not shown.

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

@ -4,17 +4,16 @@
#include "CoreMinimal.h"
#include "EngineUtils.h"
// #include "MyPlayerController.h"
#include "MyPlayerStart.h"
#include "BattlePlayerStart.h"
#include "GameFramework/GameMode.h"
#include "MyGameMode.generated.h"
#include "BattleGameMode.generated.h"
UCLASS()
class TURNBASEDTUTORIAL_API AMyGameMode : public AGameMode {
class TURNBASEDTUTORIAL_API ABattleGameMode : public AGameMode {
GENERATED_BODY()
public:
AMyGameMode();
ABattleGameMode();
virtual AActor *
ChoosePlayerStart_Implementation(AController *Player) override;
@ -30,18 +29,18 @@ public:
protected:
UPROPERTY()
TArray<UClass *> LoadedBpAssets;
UPROPERTY()
bool bIsMultiplayer = true;
void InitializeSpawnPointsIfNeeded(AController *Player);
UFUNCTION(Server, Reliable)
void InitializeBattleField();
UPROPERTY()
TMap<uint8, AMyPlayerStart *> SpawnPoints{};
TMap<uint8, ABattlePlayerStart *> SpawnPoints{};
// UPROPERTY()
// mutable TArray<ATrooper *> Troopers;

@ -1,120 +1,121 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyGameState.h"
// #include "GameOverWidget.h"
#include "MyPlayerState.h"
#include "Trooper.h"
#include "Blueprint/UserWidget.h"
#include "Net/UnrealNetwork.h"
auto AMyGameState::GetMyPlayerState(uint8 PlayerIndex) const {
return Cast<AMyPlayerState>(PlayerArray[PlayerIndex]);
}
AMyGameState::AMyGameState() : Super() {
}
void AMyGameState::BeginPlay() {
Super::BeginPlay();
LivingTroopersCount.SetNum(2);
}
void AMyGameState::AddTrooper_Implementation(ATrooper *Trooper) {
if (Trooper->GetPlayerIndex() >= 0 && Trooper->GetPlayerIndex() <=
LivingTroopersCount.Num()) {
if (LivingTroopersCount.Num() < 2) {
LivingTroopersCount.SetNum(2);
}
LivingTroopersCount[Trooper->GetPlayerIndex()]++;
}
Troopers.Add(Trooper);
}
void AMyGameState::StartGame_Implementation() {
// PlayerNotInTurn()->SetEnemySelection();
PlayerInTurn()->SetEnemySelection();
bGameStarted = true;
PlayerInTurn()->StartTurn();
}
void AMyGameState::CycleTurns_Implementation() {
PlayerInTurn()->EndTurn();
for (const auto Trooper : Troopers) {
if (Trooper != nullptr) {
Trooper->ResetActionPoints();
}
}
CurrentPlayerTurn = !CurrentPlayerTurn;
PlayerInTurn()->StartTurn();
}
// void AMyGameState::CycleTurns(uint8 CurrentPlayerIndex) {
// if (CurrentPlayerTurn == CurrentPlayerIndex) {
// PlayerInTurn()->EndTurn();
// for (const auto Trooper : Troopers) {
// if (Trooper != nullptr) {
// Trooper->ResetActionPoints();
// }
// }
// CurrentPlayerTurn = !CurrentPlayerTurn;
// PlayerInTurn()->StartTurn();
// }
// }
AMyPlayerState *AMyGameState::PlayerInTurn() const {
return GetMyPlayerState(CurrentPlayerTurn);
}
AMyPlayerState *AMyGameState::PlayerNotInTurn() const {
return GetMyPlayerState(!CurrentPlayerTurn);
}
TArray<ATrooper *> AMyGameState::GetTroopers() const {
return Troopers;
}
bool AMyGameState::IsInTurn(uint8 PlayerIndex) const {
return PlayerIndex == CurrentPlayerTurn;
}
bool AMyGameState::IsGameStarted() const {
return bGameStarted;
}
void AMyGameState::DecreaseLivingTroopers(int PlayerIndex) {
if (bGameIsOver)
return;
LivingTroopersCount[PlayerIndex]--;
if (!bIsMultiplayer && PlayerIndex == 1) {
return;
}
if (LivingTroopersCount[PlayerIndex] <= 0) {
UE_LOG(LogTemp, Warning, TEXT("Player %d lose!"), PlayerIndex);
bGameIsOver = true;
GameOver(PlayerIndex);
}
}
void AMyGameState::GameOver(int PlayerIndexLose) const {
Cast<AMyPlayerState>(PlayerArray[0])->GameOver(PlayerIndexLose);
if (bIsMultiplayer) {
Cast<AMyPlayerState>(PlayerArray[1])->GameOver(PlayerIndexLose);
}
}
// void AMyGameState::GameOver_Implementation(int PlayerIndexLose) {
// UGameOverWidget *CreatedWidget = CreateWidget<UGameOverWidget>(
// GetWorld(), GameOverWidgetClass);
// CreatedWidget->AddToViewport();
// CreatedWidget->SetWidgetText(PlayerIndexLose != );
// }
void AMyGameState::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyGameState, Troopers);
DOREPLIFETIME(AMyGameState, CurrentPlayerTurn);
DOREPLIFETIME(AMyGameState, bGameStarted);
}
// Fill out your copyright notice in the Description page of Project Settings.
#include "BattleGameState.h"
// #include "GameOverWidget.h"
#include "BattlePlayerState.h"
#include "Trooper/Trooper.h"
#include "Blueprint/UserWidget.h"
#include "Net/UnrealNetwork.h"
auto ABattleGameState::GetMyPlayerState(uint8 PlayerIndex) const {
return Cast<ABattlePlayerState>(PlayerArray[PlayerIndex]);
}
ABattleGameState::ABattleGameState()
: Super() {
}
void ABattleGameState::BeginPlay() {
Super::BeginPlay();
LivingTroopersCount.SetNum(2);
}
void ABattleGameState::AddTrooper_Implementation(ATrooper *Trooper) {
if (Trooper->GetPlayerIndex() >= 0 && Trooper->GetPlayerIndex() <=
LivingTroopersCount.Num()) {
if (LivingTroopersCount.Num() < 2) {
LivingTroopersCount.SetNum(2);
}
LivingTroopersCount[Trooper->GetPlayerIndex()]++;
}
Troopers.Add(Trooper);
}
void ABattleGameState::StartGame_Implementation() {
// PlayerNotInTurn()->SetEnemySelection();
PlayerInTurn()->SetEnemySelection();
bGameStarted = true;
PlayerInTurn()->StartTurn();
}
void ABattleGameState::CycleTurns_Implementation() {
PlayerInTurn()->EndTurn();
for (const auto Trooper : Troopers) {
if (Trooper != nullptr) {
Trooper->ResetActionPoints();
}
}
CurrentPlayerTurn = !CurrentPlayerTurn;
PlayerInTurn()->StartTurn();
}
// void AMyGameState::CycleTurns(uint8 CurrentPlayerIndex) {
// if (CurrentPlayerTurn == CurrentPlayerIndex) {
// PlayerInTurn()->EndTurn();
// for (const auto Trooper : Troopers) {
// if (Trooper != nullptr) {
// Trooper->ResetActionPoints();
// }
// }
// CurrentPlayerTurn = !CurrentPlayerTurn;
// PlayerInTurn()->StartTurn();
// }
// }
ABattlePlayerState *ABattleGameState::PlayerInTurn() const {
return GetMyPlayerState(CurrentPlayerTurn);
}
ABattlePlayerState *ABattleGameState::PlayerNotInTurn() const {
return GetMyPlayerState(!CurrentPlayerTurn);
}
TArray<ATrooper *> ABattleGameState::GetTroopers() const {
return Troopers;
}
bool ABattleGameState::IsInTurn(uint8 PlayerIndex) const {
return PlayerIndex == CurrentPlayerTurn;
}
bool ABattleGameState::IsGameStarted() const {
return bGameStarted;
}
void ABattleGameState::DecreaseLivingTroopers(int PlayerIndex) {
if (bGameIsOver)
return;
LivingTroopersCount[PlayerIndex]--;
if (!bIsMultiplayer && PlayerIndex == 1) {
return;
}
if (LivingTroopersCount[PlayerIndex] <= 0) {
UE_LOG(LogTemp, Warning, TEXT("Player %d lose!"), PlayerIndex);
bGameIsOver = true;
GameOver(PlayerIndex);
}
}
void ABattleGameState::GameOver(int PlayerIndexLose) const {
Cast<ABattlePlayerState>(PlayerArray[0])->GameOver(PlayerIndexLose);
if (bIsMultiplayer) {
Cast<ABattlePlayerState>(PlayerArray[1])->GameOver(PlayerIndexLose);
}
}
// void AMyGameState::GameOver_Implementation(int PlayerIndexLose) {
// UGameOverWidget *CreatedWidget = CreateWidget<UGameOverWidget>(
// GetWorld(), GameOverWidgetClass);
// CreatedWidget->AddToViewport();
// CreatedWidget->SetWidgetText(PlayerIndexLose != );
// }
void ABattleGameState::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ABattleGameState, Troopers);
DOREPLIFETIME(ABattleGameState, CurrentPlayerTurn);
DOREPLIFETIME(ABattleGameState, bGameStarted);
}

@ -1,75 +1,75 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "MyPlayerState.h"
#include "GameFramework/GameState.h"
#include "MyGameState.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API AMyGameState : public AGameState {
GENERATED_BODY()
public:
AMyGameState();
virtual void BeginPlay() override;
UFUNCTION(Server, Reliable)
virtual void AddTrooper(ATrooper *Trooper);
UFUNCTION(Server, Reliable)
void StartGame();
UFUNCTION(BlueprintCallable, Server, Reliable)
virtual void CycleTurns();
UFUNCTION(BlueprintPure)
AMyPlayerState *PlayerInTurn() const;
UFUNCTION(BlueprintPure)
AMyPlayerState *PlayerNotInTurn() const;
UFUNCTION()
TArray<ATrooper *> GetTroopers() const;
UFUNCTION()
bool IsInTurn(uint8 PlayerIndex) const;
UFUNCTION()
bool IsGameStarted() const;
UFUNCTION()
void DecreaseLivingTroopers(int PlayerIndex);
UFUNCTION()
void GameOver(int PlayerIndexLose) const;
protected:
// UPROPERTY(EditAnywhere, BlueprintReadWrite)
// TSubclassOf<UUserWidget> GameOverWidgetClass;
UPROPERTY()
bool bIsMultiplayer = true;
UPROPERTY(Replicated)
bool bGameIsOver = false;
UPROPERTY(Replicated)
TArray<ATrooper *> Troopers;
UPROPERTY(Replicated)
TArray<int> LivingTroopersCount;
UPROPERTY(Replicated)
bool bGameStarted = false;
UPROPERTY(Replicated)
uint8 CurrentPlayerTurn{0};
auto GetMyPlayerState(uint8 PlayerIndex) const;
};
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "BattlePlayerState.h"
#include "GameFramework/GameState.h"
#include "BattleGameState.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API ABattleGameState : public AGameState {
GENERATED_BODY()
public:
ABattleGameState();
virtual void BeginPlay() override;
UFUNCTION(Server, Reliable)
virtual void AddTrooper(ATrooper *Trooper);
UFUNCTION(Server, Reliable)
void StartGame();
UFUNCTION(BlueprintCallable, Server, Reliable)
virtual void CycleTurns();
UFUNCTION(BlueprintPure)
ABattlePlayerState *PlayerInTurn() const;
UFUNCTION(BlueprintPure)
ABattlePlayerState *PlayerNotInTurn() const;
UFUNCTION()
TArray<ATrooper *> GetTroopers() const;
UFUNCTION()
bool IsInTurn(uint8 PlayerIndex) const;
UFUNCTION()
bool IsGameStarted() const;
UFUNCTION()
void DecreaseLivingTroopers(int PlayerIndex);
UFUNCTION()
void GameOver(int PlayerIndexLose) const;
protected:
// UPROPERTY(EditAnywhere, BlueprintReadWrite)
// TSubclassOf<UUserWidget> GameOverWidgetClass;
UPROPERTY()
bool bIsMultiplayer = true;
UPROPERTY(Replicated)
bool bGameIsOver = false;
UPROPERTY(Replicated)
TArray<ATrooper *> Troopers;
UPROPERTY(Replicated)
TArray<int> LivingTroopersCount;
UPROPERTY(Replicated)
bool bGameStarted = false;
UPROPERTY(Replicated)
uint8 CurrentPlayerTurn{0};
auto GetMyPlayerState(uint8 PlayerIndex) const;
};

@ -1,35 +1,34 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyPawn.h"
// Sets default values
AMyPawn::AMyPawn() {
// 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;
}
// Called when the game starts or when spawned
void AMyPawn::BeginPlay() {
Super::BeginPlay();
}
void AMyPawn::MoveForward(float Val) {
if (Val != 0.f)
{
if (Controller)
{
FRotator ControlSpaceRot = Controller->GetControlRotation();
ControlSpaceRot.Pitch = 0;
// transform to world space and add it
AddMovementInput( FRotationMatrix(ControlSpaceRot).GetScaledAxis( EAxis::X ), Val );
}
}
}
// Called to bind functionality to input
void AMyPawn::SetupPlayerInputComponent(UInputComponent *PlayerInputComponent) {
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
// Fill out your copyright notice in the Description page of Project Settings.
#include "BattlePawn.h"
// Sets default values
ABattlePawn::ABattlePawn() {
// 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;
}
// Called when the game starts or when spawned
void ABattlePawn::BeginPlay() {
Super::BeginPlay();
}
void ABattlePawn::MoveForward(float Val) {
if (Val != 0.f) {
if (Controller) {
FRotator ControlSpaceRot = Controller->GetControlRotation();
ControlSpaceRot.Pitch = 0;
// transform to world space and add it
AddMovementInput(
FRotationMatrix(ControlSpaceRot).GetScaledAxis(EAxis::X), Val);
}
}
}
// Called to bind functionality to input
void ABattlePawn::SetupPlayerInputComponent(UInputComponent *PlayerInputComponent) {
Super::SetupPlayerInputComponent(PlayerInputComponent);
}

@ -1,29 +1,27 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "GameFramework/SpectatorPawn.h"
#include "MyPawn.generated.h"
UCLASS()
class TURNBASEDTUTORIAL_API AMyPawn : public ASpectatorPawn {
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
AMyPawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual void MoveForward(float Val) override;
public:
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(
class UInputComponent *PlayerInputComponent) override;
};
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/SpectatorPawn.h"
#include "BattlePawn.generated.h"
UCLASS()
class TURNBASEDTUTORIAL_API ABattlePawn : public ASpectatorPawn {
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ABattlePawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual void MoveForward(float Val) override;
public:
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(
class UInputComponent *PlayerInputComponent) override;
};

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

@ -3,22 +3,22 @@
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "MyPlayerController.generated.h"
#include "BattlePlayerController.generated.h"
// DECLARE_DYNAMIC_DELEGATE_OneParam(FOnMyTurnChangedDelegate, bool, bMyTurn);
UCLASS()
class TURNBASEDTUTORIAL_API AMyPlayerController : public APlayerController {
class TURNBASEDTUTORIAL_API ABattlePlayerController : public APlayerController {
GENERATED_BODY()
public:
virtual void BeginPlay() override;
// FOnMyTurnChangedDelegate OnMyTurnChanged;
virtual void SetupInputComponent() override;
AMyPlayerController();
ABattlePlayerController();
UFUNCTION(BlueprintCallable, Server, Reliable)
void EndTurn();
@ -49,11 +49,11 @@ public:
// UFUNCTION(Client, Reliable)
// void SetEnemySelection(const TArray<ATrooper *> &Troopers) const;
private:
UPROPERTY(EditAnywhere)
TSubclassOf<UUserWidget> WidgetClass;
// UPROPERTY(Replicated)
// bool bIsMyTurn;
//

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

@ -1,23 +1,23 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerStart.h"
#include "MyPlayerStart.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API AMyPlayerStart : public APlayerStart {
GENERATED_BODY()
public:
uint8 GetPlayerIndex() const;
protected:
private:
UPROPERTY(EditAnywhere, Category="Spawn Info")
uint8 PlayerIndex = 0;
};
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerStart.h"
#include "BattlePlayerStart.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API ABattlePlayerStart : public APlayerStart {
GENERATED_BODY()
public:
uint8 GetPlayerIndex() const;
protected:
private:
UPROPERTY(EditAnywhere, Category="Spawn Info")
uint8 PlayerIndex = 0;
};

@ -1,23 +1,23 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyPlayerState.h"
#include "BattlePlayerState.h"
#include "GameOverWidget.h"
#include "MyGameState.h"
#include "BattleGameState.h"
#include "Kismet/GameplayStatics.h"
#include "Net/UnrealNetwork.h"
AMyPlayerState::AMyPlayerState()
ABattlePlayerState::ABattlePlayerState()
: Super(), bIsMyTurn(false), SelectedTrooper(nullptr) {
// PrimaryActorTick.bCanEverTick = true;
}
void AMyPlayerState::BeginPlay() {
void ABattlePlayerState::BeginPlay() {
Super::BeginPlay();
}
auto AMyPlayerState::GetMyGameState() const {
return Cast<AMyGameState>(GetWorld()->GetGameState());
auto ABattlePlayerState::GetMyGameState() const {
return Cast<ABattleGameState>(GetWorld()->GetGameState());
}
// 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;
}
void AMyPlayerState::GameOver_Implementation(int PlayerLoseIndex) {
void ABattlePlayerState::GameOver_Implementation(int PlayerLoseIndex) {
UGameOverWidget *CreatedWidget = CreateWidget<UGameOverWidget>(
GetWorld(), GameOverWidgetClass);
CreatedWidget->AddToViewport();
CreatedWidget->SetWidgetText(PlayerLoseIndex != PlayerIndex);
}
void AMyPlayerState::SetEnemySelection_Implementation(
void ABattlePlayerState::SetEnemySelection_Implementation(
/*const TArray<AActor *> &Troopers*/) const {
TArray<AActor *> Troopers;
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) {
Location.Z = 0.0f;
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,
int 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;
}
void AMyPlayerState::SetMyTurn(bool bMyTurn) {
void ABattlePlayerState::SetMyTurn(bool bMyTurn) {
bIsMyTurn = bMyTurn;
if (bIsMyTurn) {
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);
UE_LOG(LogTemp, Warning, TEXT("Your turn, %d"), PlayerIndex);
}
void AMyPlayerState::EndTurn_Implementation() {
void ABattlePlayerState::EndTurn_Implementation() {
if (bIsMyTurn) {
UE_LOG(LogTemp, Warning, TEXT("End Turn from player %d"),
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;
ATrooper *NewlySelectedTrooper = Cast<ATrooper>(
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;
if (SelectedTrooper) {
SelectedTrooper->UpdateSelectionRadius(Action);
@ -204,16 +204,16 @@ void AMyPlayerState::SetCurrentAction_Implementation(int Action) {
"with index %d"), CurrentAction, PlayerIndex);
}
uint8 AMyPlayerState::GetPlayerIndex() const {
uint8 ABattlePlayerState::GetPlayerIndex() const {
return PlayerIndex;
}
void AMyPlayerState::GetLifetimeReplicatedProps(
void ABattlePlayerState::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyPlayerState, PlayerIndex);
DOREPLIFETIME(AMyPlayerState, CurrentAction);
DOREPLIFETIME(AMyPlayerState, bIsMyTurn);
DOREPLIFETIME(AMyPlayerState, SelectedTrooper);
DOREPLIFETIME(AMyPlayerState, bIsSelectionInitialized);
DOREPLIFETIME(ABattlePlayerState, PlayerIndex);
DOREPLIFETIME(ABattlePlayerState, CurrentAction);
DOREPLIFETIME(ABattlePlayerState, bIsMyTurn);
DOREPLIFETIME(ABattlePlayerState, SelectedTrooper);
DOREPLIFETIME(ABattlePlayerState, bIsSelectionInitialized);
}

@ -2,20 +2,20 @@
#pragma once
#include "Trooper.h"
#include "Trooper/Trooper.h"
#include "CoreMinimal.h"
#include "GameFramework/PlayerState.h"
#include "MyPlayerState.generated.h"
#include "BattlePlayerState.generated.h"
/**
*
*/
UCLASS()
class TURNBASEDTUTORIAL_API AMyPlayerState : public APlayerState {
class TURNBASEDTUTORIAL_API ABattlePlayerState : public APlayerState {
GENERATED_BODY()
public:
AMyPlayerState();
ABattlePlayerState();
virtual void BeginPlay() override;
@ -62,10 +62,10 @@ public:
protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<UUserWidget> GameOverWidgetClass;
UPROPERTY(Replicated)
bool bIsSelectionInitialized = false;
UPROPERTY(Replicated)
uint8 PlayerIndex;

@ -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!"));
}
}

@ -15,11 +15,11 @@ class TURNBASEDTUTORIAL_API UGameOverWidget : public UUserWidget {
public:
virtual void NativeConstruct() override;
UFUNCTION(Client, Reliable)
void SetWidgetText(bool HasWon);
UFUNCTION()
UFUNCTION(Client, Reliable)
void QuitCurrentSession();
protected:

@ -28,7 +28,7 @@ public:
void InitializeTroopers(const TArray<ATrooper *> &Troopers);
virtual void BeginPlay() override;
virtual void Tick(float DeltaSeconds) override;
UPROPERTY()
@ -58,12 +58,12 @@ private:
UFUNCTION()
void RemoveDeadTroopers();
FVector GetFreeLocation() const;
UFUNCTION()
void MakeMove();
UPROPERTY()
int TroopersCursor = 0;
@ -76,7 +76,7 @@ private:
bool MoveTo(int TrooperIndex);
void InitializeSpawnPoints();
UPROPERTY()
bool bIsAITurn = false;

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

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

@ -50,11 +50,11 @@ void ASinglePlayerGS::Tick(float DeltaSeconds) {
}
}
AEnemyAIController * ASinglePlayerGS::GetEnemyAIController() const {
AEnemyAIController *ASinglePlayerGS::GetEnemyAIController() const {
return EnemyAiManager;
}
const TArray<TSubclassOf<ATrooper>> & ASinglePlayerGS::
const TArray<TSubclassOf<ATrooper>> &ASinglePlayerGS::
GetTroopersAssets() const {
return TrooperBpAssets;
}

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

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

@ -35,7 +35,7 @@ public:
UPROPERTY(EditAnywhere)
float Speed = 1500.0f;
// Called every frame
// virtual void TickComponent(float DeltaTime,
// ELevelTick TickType,

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

@ -4,14 +4,14 @@
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyExplosion.generated.h"
#include "Explosion.generated.h"
UCLASS()
class TURNBASEDTUTORIAL_API AMyExplosion : public AActor {
class TURNBASEDTUTORIAL_API AExplosion : public AActor {
GENERATED_BODY()
public:
AMyExplosion();
AExplosion();
void Initialize(float damage,
float splashRadius,
@ -27,7 +27,7 @@ protected:
UPROPERTY(Replicated)
int8 PlayerIndex = -1;
// UPROPERTY(EditAnywhere, Replicated)
// USphereComponent *CollisionComponent;

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

@ -13,14 +13,16 @@
UCLASS(Abstract)
class TURNBASEDTUTORIAL_API UHealthBar : public UUserWidget {
GENERATED_BODY()
public:
void SetOwnerTrooper(ATrooper *Trooper);
protected:
TWeakObjectPtr<ATrooper> OwnerTrooper;
UPROPERTY(meta=(BindWidget))
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.
#include "MyProjectile.h"
#include "Projectile.h"
#include "Trooper.h"
#include "Net/UnrealNetwork.h"
AMyProjectile::AMyProjectile() {
AProjectile::AProjectile() {
// if (!RootComponent) {
// RootComponent = CreateDefaultSubobject<USceneComponent>(
// TEXT("ProjectileSceneComponent"));
@ -41,7 +41,7 @@ AMyProjectile::AMyProjectile() {
InitialLifeSpan = 2.0f;
}
void AMyProjectile::Initialize(const UAbility *Ability,
void AProjectile::Initialize(const UAbility *Ability,
uint8 playerIndex,
float PathLength) {
ProjectileMovementComponent->InitialSpeed =
@ -55,12 +55,12 @@ void AMyProjectile::Initialize(const UAbility *Ability,
SetLifeSpan(PathLength / Ability->Speed);
}
void AMyProjectile::Shoot(FVector From, FVector To) const {
void AProjectile::Shoot(FVector From, FVector To) const {
ProjectileMovementComponent->Velocity =
(To - From).GetSafeNormal() * ProjectileMovementComponent->InitialSpeed;
}
void AMyProjectile::NotifyActorBeginOverlap(AActor *OtherActor) {
void AProjectile::NotifyActorBeginOverlap(AActor *OtherActor) {
Super::NotifyActorBeginOverlap(OtherActor);
ATrooper *OtherTrooper = Cast<ATrooper>(OtherActor);
if (OtherTrooper) {
@ -106,34 +106,34 @@ void AMyProjectile::NotifyActorBeginOverlap(AActor *OtherActor) {
// }
void AMyProjectile::BeginPlay() {
void AProjectile::BeginPlay() {
Super::BeginPlay();
}
void AMyProjectile::EndPlay(const EEndPlayReason::Type EndPlayReason) {
void AProjectile::EndPlay(const EEndPlayReason::Type EndPlayReason) {
Super::EndPlay(EndPlayReason);
Explode();
}
void AMyProjectile::Explode_Implementation() const {
void AProjectile::Explode_Implementation() const {
const FTransform SpawnTransform = GetTransform();
FActorSpawnParameters SpawnParameters;
SpawnParameters.Instigator = GetInstigator();
SpawnParameters.SpawnCollisionHandlingOverride =
ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
AMyExplosion *Explosion = GetWorld()->SpawnActor<AMyExplosion>(
AExplosion *Explosion = GetWorld()->SpawnActor<AExplosion>(
ExplosionSubclass, SpawnTransform, SpawnParameters);
Explosion->Initialize(Damage, SplashRadius, PlayerIndex);
Explosion->SetActorLocation(GetActorLocation());
}
void AMyProjectile::GetLifetimeReplicatedProps(
void AProjectile::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty> &OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyProjectile, Damage);
DOREPLIFETIME(AMyProjectile, PlayerIndex);
DOREPLIFETIME(AProjectile, Damage);
DOREPLIFETIME(AProjectile, PlayerIndex);
// DOREPLIFETIME(AMyProjectile, CollisionComponent);
DOREPLIFETIME(AMyProjectile, ProjectileMeshComponent);
DOREPLIFETIME(AMyProjectile, ProjectileMovementComponent);
DOREPLIFETIME(AMyProjectile, SplashRadius);
DOREPLIFETIME(AProjectile, ProjectileMeshComponent);
DOREPLIFETIME(AProjectile, ProjectileMovementComponent);
DOREPLIFETIME(AProjectile, SplashRadius);
}

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

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

@ -2,7 +2,7 @@
#include "CoreMinimal.h"
#include "Ability.h"
#include "EnemyAIController.h"
#include "../Singleplayer/EnemyAIController.h"
#include "GameFramework/Character.h"
#include "Trooper.generated.h"
@ -31,17 +31,18 @@ public:
bool CheckMoveCorrectness(const FVector newPos) const;
UFUNCTION()
bool CheckAttackCorrectness(const FVector attackLocation, int abilityIndex) const;
bool CheckAttackCorrectness(const FVector attackLocation,
int abilityIndex) const;
UFUNCTION()
FVector GetLocation() const;
UFUNCTION(BlueprintCallable)
int GetAnimationValue();
UFUNCTION(Server, Reliable)
void Attack(int AbilityIndex, FVector ToLocation);
UFUNCTION()
float GetActionRadius(int action) const;
@ -62,7 +63,7 @@ public:
UFUNCTION(Client, Reliable)
void HighlightAsEnemy(int8 Index) const;
UFUNCTION()
void ResetActionPoints();
@ -83,13 +84,13 @@ protected:
UPROPERTY()
AEnemyAIController *AIController = nullptr;
UPROPERTY(EditAnywhere)
UMaterialInterface *GreenMaterial = nullptr;
UPROPERTY(EditAnywhere)
UMaterialInterface *RedMaterial = nullptr;
UPROPERTY(EditAnywhere)
UAbility *AttackAbility;
@ -97,13 +98,13 @@ protected:
UAbility *SpecialAbility;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<AMyProjectile> AttackProjectileClass;
TSubclassOf<AProjectile> AttackProjectileClass;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<AMyProjectile> SpecialProjectileClass;
TSubclassOf<AProjectile> SpecialProjectileClass;
UFUNCTION()
TSubclassOf<AMyProjectile> GetProjectileClass(uint8 AbilityIndex) const;
TSubclassOf<AProjectile> GetProjectileClass(uint8 AbilityIndex) const;
UFUNCTION(Server, Reliable)
void FireProjectile();
@ -113,7 +114,7 @@ protected:
UPROPERTY(Replicated)
FVector CurrentAbilityDestination = {};
UPROPERTY(EditAnywhere)
float Speed = 300.0f;
@ -125,13 +126,13 @@ protected:
UPROPERTY(EditAnywhere)
float StartActionPoints = 100.0f;
UPROPERTY(Replicated)
float HitPoints;
UPROPERTY(Replicated)
float ActionPoints;
UPROPERTY(Replicated)
bool bIsAttacking = false;
@ -147,17 +148,17 @@ protected:
UPROPERTY(Replicated)
bool bIsTakingDamage = false;
UPROPERTY(Replicated)
float TakingDamagePlayedTime;
const float TakingDamageDuration = 1.46667f;
const float DyingAnimationDuration = 2.83333f;
UPROPERTY(Replicated)
bool bIsDead = false;
virtual void BeginPlay() override;
virtual void Tick(float const DeltaTime) override;
@ -177,13 +178,13 @@ protected:
// UFUNCTION()
// void OnRepNotify_PlayerIndex() const;
UPROPERTY(Replicated/*Using = OnRepNotify_PlayerIndex*/)
int8 PlayerIndex = -1;
UPROPERTY(Replicated)
uint8 Id;
UPROPERTY(Replicated)
FVector CurrentLocation;

@ -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();
};

@ -17,9 +17,9 @@ class TURNBASEDTUTORIAL_API AManageSquadPlayerController
public:
AManageSquadPlayerController();
virtual void SetupInputComponent() override;
private:
UPROPERTY()
AManageSquadTrooper *SelectedTrooper;

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

@ -33,7 +33,7 @@ public:
virtual void Tick(float DeltaTime) override;
UFUNCTION()
void ChangeSkeletalMesh(const AManageSquadTrooper *OtherTrooper);
void ChangeSkeletalMesh(const AManageSquadTrooper *OtherTrooper) const;
UFUNCTION()
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 "Modules/ModuleManager.h"
IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, TurnBasedTutorial, "TurnBasedTutorial" );
IMPLEMENT_PRIMARY_GAME_MODULE(FDefaultGameModuleImpl, TurnBasedTutorial,
"TurnBasedTutorial");

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

Loading…
Cancel
Save