diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini index c12c8fa..57ead6b 100644 --- a/Config/DefaultEngine.ini +++ b/Config/DefaultEngine.ini @@ -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 diff --git a/Content/Animations/BP_TrooperAnimations.uasset b/Content/Animations/BP_TrooperAnimations.uasset new file mode 100644 index 0000000..1dda306 Binary files /dev/null and b/Content/Animations/BP_TrooperAnimations.uasset differ diff --git a/Content/Animations/MyAnimBlueprint.uasset b/Content/Animations/MyAnimBlueprint.uasset deleted file mode 100644 index b964de5..0000000 Binary files a/Content/Animations/MyAnimBlueprint.uasset and /dev/null differ diff --git a/Content/BattleField/BP_BattlePawn.uasset b/Content/BattleField/BP_BattlePawn.uasset new file mode 100644 index 0000000..a02872f Binary files /dev/null and b/Content/BattleField/BP_BattlePawn.uasset differ diff --git a/Content/BattleField/BP_BattlePlayerController.uasset b/Content/BattleField/BP_BattlePlayerController.uasset new file mode 100644 index 0000000..5f65d44 Binary files /dev/null and b/Content/BattleField/BP_BattlePlayerController.uasset differ diff --git a/Content/BattleField/BP_BattlePlayerState.uasset b/Content/BattleField/BP_BattlePlayerState.uasset new file mode 100644 index 0000000..f9d5f91 Binary files /dev/null and b/Content/BattleField/BP_BattlePlayerState.uasset differ diff --git a/Content/BattleField/BP_BattleUI.uasset b/Content/BattleField/BP_BattleUI.uasset index 74315dc..8c09052 100644 Binary files a/Content/BattleField/BP_BattleUI.uasset and b/Content/BattleField/BP_BattleUI.uasset differ diff --git a/Content/BattleField/BP_MyPawn.uasset b/Content/BattleField/BP_MyPawn.uasset deleted file mode 100644 index 6454e04..0000000 Binary files a/Content/BattleField/BP_MyPawn.uasset and /dev/null differ diff --git a/Content/BattleField/BP_MyPlayerController.uasset b/Content/BattleField/BP_MyPlayerController.uasset deleted file mode 100644 index b400662..0000000 Binary files a/Content/BattleField/BP_MyPlayerController.uasset and /dev/null differ diff --git a/Content/BattleField/BP_MyPlayerState.uasset b/Content/BattleField/BP_MyPlayerState.uasset deleted file mode 100644 index 31d3e7a..0000000 Binary files a/Content/BattleField/BP_MyPlayerState.uasset and /dev/null differ diff --git a/Content/BattleField/Multiplayer/BP_BattleGameMode.uasset b/Content/BattleField/Multiplayer/BP_BattleGameMode.uasset new file mode 100644 index 0000000..ce38b8d Binary files /dev/null and b/Content/BattleField/Multiplayer/BP_BattleGameMode.uasset differ diff --git a/Content/BattleField/Multiplayer/BP_BattleGameState.uasset b/Content/BattleField/Multiplayer/BP_BattleGameState.uasset new file mode 100644 index 0000000..fc721a6 Binary files /dev/null and b/Content/BattleField/Multiplayer/BP_BattleGameState.uasset differ diff --git a/Content/BattleField/Multiplayer/BP_MyGameMode.uasset b/Content/BattleField/Multiplayer/BP_MyGameMode.uasset index a01d968..2ac5118 100644 Binary files a/Content/BattleField/Multiplayer/BP_MyGameMode.uasset and b/Content/BattleField/Multiplayer/BP_MyGameMode.uasset differ diff --git a/Content/BattleField/Multiplayer/BP_MyGameState.uasset b/Content/BattleField/Multiplayer/BP_MyGameState.uasset deleted file mode 100644 index 954272f..0000000 Binary files a/Content/BattleField/Multiplayer/BP_MyGameState.uasset and /dev/null differ diff --git a/Content/BattleField/Multiplayer/BattleFieldMap.umap b/Content/BattleField/Multiplayer/BattleFieldMap.umap index 9284f7d..9d0bed5 100644 Binary files a/Content/BattleField/Multiplayer/BattleFieldMap.umap and b/Content/BattleField/Multiplayer/BattleFieldMap.umap differ diff --git a/Content/BattleField/SinglePlayer/BP_SinglePlayerGM.uasset b/Content/BattleField/SinglePlayer/BP_SinglePlayerGM.uasset index a9efbb5..0a6b17d 100644 Binary files a/Content/BattleField/SinglePlayer/BP_SinglePlayerGM.uasset and b/Content/BattleField/SinglePlayer/BP_SinglePlayerGM.uasset differ diff --git a/Content/MainMenu/BP_MainMenuPlayerController.uasset b/Content/MainMenu/BP_MainMenuPlayerController.uasset index caf849d..a99d706 100644 Binary files a/Content/MainMenu/BP_MainMenuPlayerController.uasset and b/Content/MainMenu/BP_MainMenuPlayerController.uasset differ diff --git a/Content/MainMenu/BP_MainMenuWidget.uasset b/Content/MainMenu/BP_MainMenuWidget.uasset new file mode 100644 index 0000000..dc53399 Binary files /dev/null and b/Content/MainMenu/BP_MainMenuWidget.uasset differ diff --git a/Content/MainMenu/MainMenu.uasset b/Content/MainMenu/MainMenu.uasset deleted file mode 100644 index ae87ceb..0000000 Binary files a/Content/MainMenu/MainMenu.uasset and /dev/null differ diff --git a/Content/MainMenu/MainMenuLevel.umap b/Content/MainMenu/MainMenuLevel.umap index da732e9..d882ad5 100644 Binary files a/Content/MainMenu/MainMenuLevel.umap and b/Content/MainMenu/MainMenuLevel.umap differ diff --git a/Content/Troopers/TrooperSkeletonMelee.uasset b/Content/Troopers/TrooperSkeletonMelee.uasset index 03c4572..1b5a4c6 100644 Binary files a/Content/Troopers/TrooperSkeletonMelee.uasset and b/Content/Troopers/TrooperSkeletonMelee.uasset differ diff --git a/Content/Troopers/TrooperWizard.uasset b/Content/Troopers/TrooperWizard.uasset index a204267..fee6f8c 100644 Binary files a/Content/Troopers/TrooperWizard.uasset and b/Content/Troopers/TrooperWizard.uasset differ diff --git a/Source/TurnBasedTutorial/MyGameMode.cpp b/Source/TurnBasedTutorial/BattleMode/BattleGameMode.cpp similarity index 85% rename from Source/TurnBasedTutorial/MyGameMode.cpp rename to Source/TurnBasedTutorial/BattleMode/BattleGameMode.cpp index ef8dd3b..016aff9 100644 --- a/Source/TurnBasedTutorial/MyGameMode.cpp +++ b/Source/TurnBasedTutorial/BattleMode/BattleGameMode.cpp @@ -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(); +auto ABattleGameMode::GetMyGameState() const { + return GetGameState(); } -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(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 PlayerStartIterator(GetWorld()); + for (TActorIterator 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(NewPlayer)->SetPlayerIndex( + Cast(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); diff --git a/Source/TurnBasedTutorial/MyGameMode.h b/Source/TurnBasedTutorial/BattleMode/BattleGameMode.h similarity index 83% rename from Source/TurnBasedTutorial/MyGameMode.h rename to Source/TurnBasedTutorial/BattleMode/BattleGameMode.h index dbff953..c411706 100644 --- a/Source/TurnBasedTutorial/MyGameMode.h +++ b/Source/TurnBasedTutorial/BattleMode/BattleGameMode.h @@ -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 LoadedBpAssets; - + UPROPERTY() bool bIsMultiplayer = true; - + void InitializeSpawnPointsIfNeeded(AController *Player); UFUNCTION(Server, Reliable) void InitializeBattleField(); UPROPERTY() - TMap SpawnPoints{}; - + TMap SpawnPoints{}; + // UPROPERTY() // mutable TArray Troopers; diff --git a/Source/TurnBasedTutorial/MyGameState.cpp b/Source/TurnBasedTutorial/BattleMode/BattleGameState.cpp similarity index 65% rename from Source/TurnBasedTutorial/MyGameState.cpp rename to Source/TurnBasedTutorial/BattleMode/BattleGameState.cpp index 45ed445..0c71a63 100644 --- a/Source/TurnBasedTutorial/MyGameState.cpp +++ b/Source/TurnBasedTutorial/BattleMode/BattleGameState.cpp @@ -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(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 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(PlayerArray[0])->GameOver(PlayerIndexLose); - if (bIsMultiplayer) { - Cast(PlayerArray[1])->GameOver(PlayerIndexLose); - } -} - -// void AMyGameState::GameOver_Implementation(int PlayerIndexLose) { -// UGameOverWidget *CreatedWidget = CreateWidget( -// GetWorld(), GameOverWidgetClass); -// CreatedWidget->AddToViewport(); -// CreatedWidget->SetWidgetText(PlayerIndexLose != ); -// } - - -void AMyGameState::GetLifetimeReplicatedProps( - TArray &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(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 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(PlayerArray[0])->GameOver(PlayerIndexLose); + if (bIsMultiplayer) { + Cast(PlayerArray[1])->GameOver(PlayerIndexLose); + } +} + +// void AMyGameState::GameOver_Implementation(int PlayerIndexLose) { +// UGameOverWidget *CreatedWidget = CreateWidget( +// GetWorld(), GameOverWidgetClass); +// CreatedWidget->AddToViewport(); +// CreatedWidget->SetWidgetText(PlayerIndexLose != ); +// } + + +void ABattleGameState::GetLifetimeReplicatedProps( + TArray &OutLifetimeProps) const { + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + DOREPLIFETIME(ABattleGameState, Troopers); + DOREPLIFETIME(ABattleGameState, CurrentPlayerTurn); + DOREPLIFETIME(ABattleGameState, bGameStarted); +} diff --git a/Source/TurnBasedTutorial/MyGameState.h b/Source/TurnBasedTutorial/BattleMode/BattleGameState.h similarity index 79% rename from Source/TurnBasedTutorial/MyGameState.h rename to Source/TurnBasedTutorial/BattleMode/BattleGameState.h index 1a30b60..bc40ed8 100644 --- a/Source/TurnBasedTutorial/MyGameState.h +++ b/Source/TurnBasedTutorial/BattleMode/BattleGameState.h @@ -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 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 GameOverWidgetClass; - - UPROPERTY() - bool bIsMultiplayer = true; - - UPROPERTY(Replicated) - bool bGameIsOver = false; - - UPROPERTY(Replicated) - TArray Troopers; - - UPROPERTY(Replicated) - TArray 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 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 GameOverWidgetClass; + + UPROPERTY() + bool bIsMultiplayer = true; + + UPROPERTY(Replicated) + bool bGameIsOver = false; + + UPROPERTY(Replicated) + TArray Troopers; + + UPROPERTY(Replicated) + TArray LivingTroopersCount; + + UPROPERTY(Replicated) + bool bGameStarted = false; + + UPROPERTY(Replicated) + uint8 CurrentPlayerTurn{0}; + + auto GetMyPlayerState(uint8 PlayerIndex) const; +}; diff --git a/Source/TurnBasedTutorial/MyPawn.cpp b/Source/TurnBasedTutorial/BattleMode/BattlePawn.cpp similarity index 62% rename from Source/TurnBasedTutorial/MyPawn.cpp rename to Source/TurnBasedTutorial/BattleMode/BattlePawn.cpp index b8698e3..5c4a650 100644 --- a/Source/TurnBasedTutorial/MyPawn.cpp +++ b/Source/TurnBasedTutorial/BattleMode/BattlePawn.cpp @@ -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); +} diff --git a/Source/TurnBasedTutorial/MyPawn.h b/Source/TurnBasedTutorial/BattleMode/BattlePawn.h similarity index 77% rename from Source/TurnBasedTutorial/MyPawn.h rename to Source/TurnBasedTutorial/BattleMode/BattlePawn.h index c8ba2ea..de42606 100644 --- a/Source/TurnBasedTutorial/MyPawn.h +++ b/Source/TurnBasedTutorial/BattleMode/BattlePawn.h @@ -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; +}; diff --git a/Source/TurnBasedTutorial/MyPlayerController.cpp b/Source/TurnBasedTutorial/BattleMode/BattlePlayerController.cpp similarity index 91% rename from Source/TurnBasedTutorial/MyPlayerController.cpp rename to Source/TurnBasedTutorial/BattleMode/BattlePlayerController.cpp index 508ee1a..aa67c9f 100644 --- a/Source/TurnBasedTutorial/MyPlayerController.cpp +++ b/Source/TurnBasedTutorial/BattleMode/BattlePlayerController.cpp @@ -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( 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(UGameplayStatics::GetGameState(GetWorld())); +auto ABattlePlayerController::GetMyGameState() const { + return Cast(UGameplayStatics::GetGameState(GetWorld())); } -auto AMyPlayerController::GetMyPlayerState() const { - return GetPlayerState(); +auto ABattlePlayerController::GetMyPlayerState() const { + return GetPlayerState(); } -auto AMyPlayerController::GetMyGameMode() const { - return Cast( +auto ABattlePlayerController::GetMyGameMode() const { + return Cast( 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 &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; } diff --git a/Source/TurnBasedTutorial/MyPlayerController.h b/Source/TurnBasedTutorial/BattleMode/BattlePlayerController.h similarity index 91% rename from Source/TurnBasedTutorial/MyPlayerController.h rename to Source/TurnBasedTutorial/BattleMode/BattlePlayerController.h index 9b962e7..c5e090d 100644 --- a/Source/TurnBasedTutorial/MyPlayerController.h +++ b/Source/TurnBasedTutorial/BattleMode/BattlePlayerController.h @@ -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 &Troopers) const; - + private: UPROPERTY(EditAnywhere) TSubclassOf WidgetClass; - + // UPROPERTY(Replicated) // bool bIsMyTurn; // diff --git a/Source/TurnBasedTutorial/MyPlayerStart.cpp b/Source/TurnBasedTutorial/BattleMode/BattlePlayerStart.cpp similarity index 56% rename from Source/TurnBasedTutorial/MyPlayerStart.cpp rename to Source/TurnBasedTutorial/BattleMode/BattlePlayerStart.cpp index fd44adc..bf290d5 100644 --- a/Source/TurnBasedTutorial/MyPlayerStart.cpp +++ b/Source/TurnBasedTutorial/BattleMode/BattlePlayerStart.cpp @@ -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; +} diff --git a/Source/TurnBasedTutorial/MyPlayerStart.h b/Source/TurnBasedTutorial/BattleMode/BattlePlayerStart.h similarity index 73% rename from Source/TurnBasedTutorial/MyPlayerStart.h rename to Source/TurnBasedTutorial/BattleMode/BattlePlayerStart.h index c28a149..3c43457 100644 --- a/Source/TurnBasedTutorial/MyPlayerStart.h +++ b/Source/TurnBasedTutorial/BattleMode/BattlePlayerStart.h @@ -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; +}; diff --git a/Source/TurnBasedTutorial/MyPlayerState.cpp b/Source/TurnBasedTutorial/BattleMode/BattlePlayerState.cpp similarity index 83% rename from Source/TurnBasedTutorial/MyPlayerState.cpp rename to Source/TurnBasedTutorial/BattleMode/BattlePlayerState.cpp index 240e267..6c0928c 100644 --- a/Source/TurnBasedTutorial/MyPlayerState.cpp +++ b/Source/TurnBasedTutorial/BattleMode/BattlePlayerState.cpp @@ -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(GetWorld()->GetGameState()); +auto ABattlePlayerState::GetMyGameState() const { + return Cast(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( GetWorld(), GameOverWidgetClass); CreatedWidget->AddToViewport(); CreatedWidget->SetWidgetText(PlayerLoseIndex != PlayerIndex); } -void AMyPlayerState::SetEnemySelection_Implementation( +void ABattlePlayerState::SetEnemySelection_Implementation( /*const TArray &Troopers*/) const { TArray 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( 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 &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); } diff --git a/Source/TurnBasedTutorial/MyPlayerState.h b/Source/TurnBasedTutorial/BattleMode/BattlePlayerState.h similarity index 91% rename from Source/TurnBasedTutorial/MyPlayerState.h rename to Source/TurnBasedTutorial/BattleMode/BattlePlayerState.h index 84c4aa2..a68163b 100644 --- a/Source/TurnBasedTutorial/MyPlayerState.h +++ b/Source/TurnBasedTutorial/BattleMode/BattlePlayerState.h @@ -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 GameOverWidgetClass; - + UPROPERTY(Replicated) bool bIsSelectionInitialized = false; - + UPROPERTY(Replicated) uint8 PlayerIndex; diff --git a/Source/TurnBasedTutorial/BattleMode/GameOverWidget.cpp b/Source/TurnBasedTutorial/BattleMode/GameOverWidget.cpp new file mode 100644 index 0000000..e6c1180 --- /dev/null +++ b/Source/TurnBasedTutorial/BattleMode/GameOverWidget.cpp @@ -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 + (); + GameInstanceSubsystem->QuitCurrentSession(); +} + + +void UGameOverWidget::SetWidgetText_Implementation(bool HasWon) { + if (HasWon) { + GameOverText->SetText(FText::FromString("You won!")); + } else { + GameOverText->SetText(FText::FromString("You lose!")); + } +} diff --git a/Source/TurnBasedTutorial/GameOverWidget.h b/Source/TurnBasedTutorial/BattleMode/GameOverWidget.h similarity index 94% rename from Source/TurnBasedTutorial/GameOverWidget.h rename to Source/TurnBasedTutorial/BattleMode/GameOverWidget.h index 113402b..2a28630 100644 --- a/Source/TurnBasedTutorial/GameOverWidget.h +++ b/Source/TurnBasedTutorial/BattleMode/GameOverWidget.h @@ -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: diff --git a/Source/TurnBasedTutorial/EnemyAIController.cpp b/Source/TurnBasedTutorial/BattleMode/Singleplayer/EnemyAIController.cpp similarity index 100% rename from Source/TurnBasedTutorial/EnemyAIController.cpp rename to Source/TurnBasedTutorial/BattleMode/Singleplayer/EnemyAIController.cpp diff --git a/Source/TurnBasedTutorial/EnemyAIController.h b/Source/TurnBasedTutorial/BattleMode/Singleplayer/EnemyAIController.h similarity index 98% rename from Source/TurnBasedTutorial/EnemyAIController.h rename to Source/TurnBasedTutorial/BattleMode/Singleplayer/EnemyAIController.h index 5f8ed75..01d9a5d 100644 --- a/Source/TurnBasedTutorial/EnemyAIController.h +++ b/Source/TurnBasedTutorial/BattleMode/Singleplayer/EnemyAIController.h @@ -28,7 +28,7 @@ public: void InitializeTroopers(const TArray &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; diff --git a/Source/TurnBasedTutorial/SinglePlayerGM.cpp b/Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGM.cpp similarity index 91% rename from Source/TurnBasedTutorial/SinglePlayerGM.cpp rename to Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGM.cpp index e2372c9..64d327a 100644 --- a/Source/TurnBasedTutorial/SinglePlayerGM.cpp +++ b/Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGM.cpp @@ -3,7 +3,8 @@ #include "SinglePlayerGM.h" #include "SinglePlayerGS.h" -ASinglePlayerGM::ASinglePlayerGM() : Super() { +ASinglePlayerGM::ASinglePlayerGM() + : Super() { GameStateClass = ASinglePlayerGS::StaticClass(); bIsMultiplayer = false; } diff --git a/Source/TurnBasedTutorial/SinglePlayerGM.h b/Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGM.h similarity index 76% rename from Source/TurnBasedTutorial/SinglePlayerGM.h rename to Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGM.h index f304336..08d73ab 100644 --- a/Source/TurnBasedTutorial/SinglePlayerGM.h +++ b/Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGM.h @@ -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; - }; diff --git a/Source/TurnBasedTutorial/SinglePlayerGS.cpp b/Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGS.cpp similarity index 93% rename from Source/TurnBasedTutorial/SinglePlayerGS.cpp rename to Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGS.cpp index 3b5e1d0..e272f81 100644 --- a/Source/TurnBasedTutorial/SinglePlayerGS.cpp +++ b/Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGS.cpp @@ -50,11 +50,11 @@ void ASinglePlayerGS::Tick(float DeltaSeconds) { } } -AEnemyAIController * ASinglePlayerGS::GetEnemyAIController() const { +AEnemyAIController *ASinglePlayerGS::GetEnemyAIController() const { return EnemyAiManager; } -const TArray> & ASinglePlayerGS:: +const TArray> &ASinglePlayerGS:: GetTroopersAssets() const { return TrooperBpAssets; } diff --git a/Source/TurnBasedTutorial/SinglePlayerGS.h b/Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGS.h similarity index 87% rename from Source/TurnBasedTutorial/SinglePlayerGS.h rename to Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGS.h index ba86e8b..1ca3171 100644 --- a/Source/TurnBasedTutorial/SinglePlayerGS.h +++ b/Source/TurnBasedTutorial/BattleMode/Singleplayer/SinglePlayerGS.h @@ -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(); diff --git a/Source/TurnBasedTutorial/Ability.cpp b/Source/TurnBasedTutorial/BattleMode/Trooper/Ability.cpp similarity index 99% rename from Source/TurnBasedTutorial/Ability.cpp rename to Source/TurnBasedTutorial/BattleMode/Trooper/Ability.cpp index 9d83356..d35f5df 100644 --- a/Source/TurnBasedTutorial/Ability.cpp +++ b/Source/TurnBasedTutorial/BattleMode/Trooper/Ability.cpp @@ -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, diff --git a/Source/TurnBasedTutorial/Ability.h b/Source/TurnBasedTutorial/BattleMode/Trooper/Ability.h similarity index 99% rename from Source/TurnBasedTutorial/Ability.h rename to Source/TurnBasedTutorial/BattleMode/Trooper/Ability.h index 315c4b8..079f2b6 100644 --- a/Source/TurnBasedTutorial/Ability.h +++ b/Source/TurnBasedTutorial/BattleMode/Trooper/Ability.h @@ -35,7 +35,7 @@ public: UPROPERTY(EditAnywhere) float Speed = 1500.0f; - + // Called every frame // virtual void TickComponent(float DeltaTime, // ELevelTick TickType, diff --git a/Source/TurnBasedTutorial/MyExplosion.cpp b/Source/TurnBasedTutorial/BattleMode/Trooper/Explosion.cpp similarity index 83% rename from Source/TurnBasedTutorial/MyExplosion.cpp rename to Source/TurnBasedTutorial/BattleMode/Trooper/Explosion.cpp index 0398377..fa3484f 100644 --- a/Source/TurnBasedTutorial/MyExplosion.cpp +++ b/Source/TurnBasedTutorial/BattleMode/Trooper/Explosion.cpp @@ -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( // 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(OtherActor); if (OtherTrooper) { @@ -57,11 +56,11 @@ void AMyExplosion::NotifyActorBeginOverlap(AActor *OtherActor) { } } -void AMyExplosion::GetLifetimeReplicatedProps( +void AExplosion::GetLifetimeReplicatedProps( TArray &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); } diff --git a/Source/TurnBasedTutorial/MyExplosion.h b/Source/TurnBasedTutorial/BattleMode/Trooper/Explosion.h similarity index 85% rename from Source/TurnBasedTutorial/MyExplosion.h rename to Source/TurnBasedTutorial/BattleMode/Trooper/Explosion.h index 38f45a5..e72f780 100644 --- a/Source/TurnBasedTutorial/MyExplosion.h +++ b/Source/TurnBasedTutorial/BattleMode/Trooper/Explosion.h @@ -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; diff --git a/Source/TurnBasedTutorial/HealthBar.cpp b/Source/TurnBasedTutorial/BattleMode/Trooper/HealthBar.cpp similarity index 80% rename from Source/TurnBasedTutorial/HealthBar.cpp rename to Source/TurnBasedTutorial/BattleMode/Trooper/HealthBar.cpp index aea4196..9a7256e 100644 --- a/Source/TurnBasedTutorial/HealthBar.cpp +++ b/Source/TurnBasedTutorial/BattleMode/Trooper/HealthBar.cpp @@ -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()); } diff --git a/Source/TurnBasedTutorial/HealthBar.h b/Source/TurnBasedTutorial/BattleMode/Trooper/HealthBar.h similarity index 83% rename from Source/TurnBasedTutorial/HealthBar.h rename to Source/TurnBasedTutorial/BattleMode/Trooper/HealthBar.h index fa22426..af06f73 100644 --- a/Source/TurnBasedTutorial/HealthBar.h +++ b/Source/TurnBasedTutorial/BattleMode/Trooper/HealthBar.h @@ -13,14 +13,16 @@ UCLASS(Abstract) class TURNBASEDTUTORIAL_API UHealthBar : public UUserWidget { GENERATED_BODY() + public: void SetOwnerTrooper(ATrooper *Trooper); - + protected: TWeakObjectPtr 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; }; diff --git a/Source/TurnBasedTutorial/MyProjectile.cpp b/Source/TurnBasedTutorial/BattleMode/Trooper/Projectile.cpp similarity index 86% rename from Source/TurnBasedTutorial/MyProjectile.cpp rename to Source/TurnBasedTutorial/BattleMode/Trooper/Projectile.cpp index 5e15645..f05d525 100644 --- a/Source/TurnBasedTutorial/MyProjectile.cpp +++ b/Source/TurnBasedTutorial/BattleMode/Trooper/Projectile.cpp @@ -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( // 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(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( + AExplosion *Explosion = GetWorld()->SpawnActor( ExplosionSubclass, SpawnTransform, SpawnParameters); Explosion->Initialize(Damage, SplashRadius, PlayerIndex); Explosion->SetActorLocation(GetActorLocation()); } -void AMyProjectile::GetLifetimeReplicatedProps( +void AProjectile::GetLifetimeReplicatedProps( TArray &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); } diff --git a/Source/TurnBasedTutorial/MyProjectile.h b/Source/TurnBasedTutorial/BattleMode/Trooper/Projectile.h similarity index 89% rename from Source/TurnBasedTutorial/MyProjectile.h rename to Source/TurnBasedTutorial/BattleMode/Trooper/Projectile.h index bfcc820..9c1a9d2 100644 --- a/Source/TurnBasedTutorial/MyProjectile.h +++ b/Source/TurnBasedTutorial/BattleMode/Trooper/Projectile.h @@ -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 ExplosionSubclass; + TSubclassOf ExplosionSubclass; // virtual void NotifyHit(UPrimitiveComponent *MyComp, // AActor *Other, diff --git a/Source/TurnBasedTutorial/Trooper.cpp b/Source/TurnBasedTutorial/BattleMode/Trooper/Trooper.cpp similarity index 97% rename from Source/TurnBasedTutorial/Trooper.cpp rename to Source/TurnBasedTutorial/BattleMode/Trooper/Trooper.cpp index 9c1b4ed..d0f1809 100644 --- a/Source/TurnBasedTutorial/Trooper.cpp +++ b/Source/TurnBasedTutorial/BattleMode/Trooper/Trooper.cpp @@ -2,8 +2,8 @@ #include #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()->DecreaseLivingTroopers(PlayerIndex); + GetWorld()->GetGameState()->DecreaseLivingTroopers( + PlayerIndex); } else { // bIsTakingDamage = true; SetIsTakingDamage(true); } } -TSubclassOf ATrooper::GetProjectileClass( +TSubclassOf ATrooper::GetProjectileClass( uint8 AbilityIndex) const { switch (AbilityIndex) { case 1: @@ -327,7 +328,7 @@ TSubclassOf 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( + AProjectile *Projectile = GetWorld()->SpawnActor( GetProjectileClass(CurrentAbilityIndex), SpawnTransform, SpawnParameters); Projectile->SetActorLocation(SpawnLocation); diff --git a/Source/TurnBasedTutorial/Trooper.h b/Source/TurnBasedTutorial/BattleMode/Trooper/Trooper.h similarity index 92% rename from Source/TurnBasedTutorial/Trooper.h rename to Source/TurnBasedTutorial/BattleMode/Trooper/Trooper.h index 64b13d2..f3de3bc 100644 --- a/Source/TurnBasedTutorial/Trooper.h +++ b/Source/TurnBasedTutorial/BattleMode/Trooper/Trooper.h @@ -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 AttackProjectileClass; + TSubclassOf AttackProjectileClass; UPROPERTY(EditAnywhere, BlueprintReadWrite) - TSubclassOf SpecialProjectileClass; + TSubclassOf SpecialProjectileClass; UFUNCTION() - TSubclassOf GetProjectileClass(uint8 AbilityIndex) const; + TSubclassOf 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; diff --git a/Source/TurnBasedTutorial/GameOverWidget.cpp b/Source/TurnBasedTutorial/GameOverWidget.cpp deleted file mode 100644 index c1110ed..0000000 --- a/Source/TurnBasedTutorial/GameOverWidget.cpp +++ /dev/null @@ -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(); - GameInstanceSubsystem->QuitCurrentSession(); -} - - -void UGameOverWidget::SetWidgetText_Implementation(bool HasWon) -{ - if (HasWon) - { - GameOverText->SetText(FText::FromString("You won!")); - } - else - { - GameOverText->SetText(FText::FromString("You lose!")); - } -} diff --git a/Source/TurnBasedTutorial/MainMenuPlayerController.cpp b/Source/TurnBasedTutorial/MainMenu/MainMenuPlayerController.cpp similarity index 100% rename from Source/TurnBasedTutorial/MainMenuPlayerController.cpp rename to Source/TurnBasedTutorial/MainMenu/MainMenuPlayerController.cpp diff --git a/Source/TurnBasedTutorial/MainMenuPlayerController.h b/Source/TurnBasedTutorial/MainMenu/MainMenuPlayerController.h similarity index 100% rename from Source/TurnBasedTutorial/MainMenuPlayerController.h rename to Source/TurnBasedTutorial/MainMenu/MainMenuPlayerController.h diff --git a/Source/TurnBasedTutorial/MainMenu/MainMenuWidget.cpp b/Source/TurnBasedTutorial/MainMenu/MainMenuWidget.cpp new file mode 100644 index 0000000..3a13569 --- /dev/null +++ b/Source/TurnBasedTutorial/MainMenu/MainMenuWidget.cpp @@ -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(); + return GameInstanceSubsystem; +} diff --git a/Source/TurnBasedTutorial/MainMenu/MainMenuWidget.h b/Source/TurnBasedTutorial/MainMenu/MainMenuWidget.h new file mode 100644 index 0000000..992d040 --- /dev/null +++ b/Source/TurnBasedTutorial/MainMenu/MainMenuWidget.h @@ -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; +}; diff --git a/Source/TurnBasedTutorial/MainMenu/SessionListEntryWidget.cpp b/Source/TurnBasedTutorial/MainMenu/SessionListEntryWidget.cpp new file mode 100644 index 0000000..849328b --- /dev/null +++ b/Source/TurnBasedTutorial/MainMenu/SessionListEntryWidget.cpp @@ -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)); +} diff --git a/Source/TurnBasedTutorial/MainMenu/SessionListEntryWidget.h b/Source/TurnBasedTutorial/MainMenu/SessionListEntryWidget.h new file mode 100644 index 0000000..8c74028 --- /dev/null +++ b/Source/TurnBasedTutorial/MainMenu/SessionListEntryWidget.h @@ -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; +}; diff --git a/Source/TurnBasedTutorial/MainMenu/SessionListWidget.cpp b/Source/TurnBasedTutorial/MainMenu/SessionListWidget.cpp new file mode 100644 index 0000000..a6794f9 --- /dev/null +++ b/Source/TurnBasedTutorial/MainMenu/SessionListWidget.cpp @@ -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 &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( + 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(); + return GameInstanceSubsystem; +} diff --git a/Source/TurnBasedTutorial/MainMenu/SessionListWidget.h b/Source/TurnBasedTutorial/MainMenu/SessionListWidget.h new file mode 100644 index 0000000..e0b43ef --- /dev/null +++ b/Source/TurnBasedTutorial/MainMenu/SessionListWidget.h @@ -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 EntryClass; + + void RefreshList(const TArray &SessionResults, + bool bSuccessful); + + void OnJoinSessionSuccess(EOnJoinSessionCompleteResult::Type Result); + +private: + USessionsGameInstanceSubsystem *GetMyGameSubsystem() const; + + UFUNCTION() + void OnRefreshListButtonClicked(); + + UFUNCTION() + void ConnectToFirstSession(); +}; diff --git a/Source/TurnBasedTutorial/ManageSquadGameMode.cpp b/Source/TurnBasedTutorial/ManageSquad/ManageSquadGameMode.cpp similarity index 100% rename from Source/TurnBasedTutorial/ManageSquadGameMode.cpp rename to Source/TurnBasedTutorial/ManageSquad/ManageSquadGameMode.cpp diff --git a/Source/TurnBasedTutorial/ManageSquadGameMode.h b/Source/TurnBasedTutorial/ManageSquad/ManageSquadGameMode.h similarity index 100% rename from Source/TurnBasedTutorial/ManageSquadGameMode.h rename to Source/TurnBasedTutorial/ManageSquad/ManageSquadGameMode.h diff --git a/Source/TurnBasedTutorial/ManageSquadGameState.cpp b/Source/TurnBasedTutorial/ManageSquad/ManageSquadGameState.cpp similarity index 100% rename from Source/TurnBasedTutorial/ManageSquadGameState.cpp rename to Source/TurnBasedTutorial/ManageSquad/ManageSquadGameState.cpp diff --git a/Source/TurnBasedTutorial/ManageSquadGameState.h b/Source/TurnBasedTutorial/ManageSquad/ManageSquadGameState.h similarity index 100% rename from Source/TurnBasedTutorial/ManageSquadGameState.h rename to Source/TurnBasedTutorial/ManageSquad/ManageSquadGameState.h diff --git a/Source/TurnBasedTutorial/ManageSquadPawn.cpp b/Source/TurnBasedTutorial/ManageSquad/ManageSquadPawn.cpp similarity index 100% rename from Source/TurnBasedTutorial/ManageSquadPawn.cpp rename to Source/TurnBasedTutorial/ManageSquad/ManageSquadPawn.cpp diff --git a/Source/TurnBasedTutorial/ManageSquadPawn.h b/Source/TurnBasedTutorial/ManageSquad/ManageSquadPawn.h similarity index 100% rename from Source/TurnBasedTutorial/ManageSquadPawn.h rename to Source/TurnBasedTutorial/ManageSquad/ManageSquadPawn.h diff --git a/Source/TurnBasedTutorial/ManageSquadPlayerController.cpp b/Source/TurnBasedTutorial/ManageSquad/ManageSquadPlayerController.cpp similarity index 100% rename from Source/TurnBasedTutorial/ManageSquadPlayerController.cpp rename to Source/TurnBasedTutorial/ManageSquad/ManageSquadPlayerController.cpp diff --git a/Source/TurnBasedTutorial/ManageSquadPlayerController.h b/Source/TurnBasedTutorial/ManageSquad/ManageSquadPlayerController.h similarity index 98% rename from Source/TurnBasedTutorial/ManageSquadPlayerController.h rename to Source/TurnBasedTutorial/ManageSquad/ManageSquadPlayerController.h index 5fe2a53..12749f0 100644 --- a/Source/TurnBasedTutorial/ManageSquadPlayerController.h +++ b/Source/TurnBasedTutorial/ManageSquad/ManageSquadPlayerController.h @@ -17,9 +17,9 @@ class TURNBASEDTUTORIAL_API AManageSquadPlayerController public: AManageSquadPlayerController(); - + virtual void SetupInputComponent() override; - + private: UPROPERTY() AManageSquadTrooper *SelectedTrooper; diff --git a/Source/TurnBasedTutorial/ManageSquadTrooper.cpp b/Source/TurnBasedTutorial/ManageSquad/ManageSquadTrooper.cpp similarity index 79% rename from Source/TurnBasedTutorial/ManageSquadTrooper.cpp rename to Source/TurnBasedTutorial/ManageSquad/ManageSquadTrooper.cpp index 3019c63..3e140f4 100644 --- a/Source/TurnBasedTutorial/ManageSquadTrooper.cpp +++ b/Source/TurnBasedTutorial/ManageSquad/ManageSquadTrooper.cpp @@ -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); } diff --git a/Source/TurnBasedTutorial/ManageSquadTrooper.h b/Source/TurnBasedTutorial/ManageSquad/ManageSquadTrooper.h similarity index 98% rename from Source/TurnBasedTutorial/ManageSquadTrooper.h rename to Source/TurnBasedTutorial/ManageSquad/ManageSquadTrooper.h index 5e49790..2da243b 100644 --- a/Source/TurnBasedTutorial/ManageSquadTrooper.h +++ b/Source/TurnBasedTutorial/ManageSquad/ManageSquadTrooper.h @@ -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; diff --git a/Source/TurnBasedTutorial/MyGameInstanceSubsystem.cpp b/Source/TurnBasedTutorial/MyGameInstanceSubsystem.cpp deleted file mode 100644 index 15a858e..0000000 --- a/Source/TurnBasedTutorial/MyGameInstanceSubsystem.cpp +++ /dev/null @@ -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 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(), 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(), 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(), 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(); -} diff --git a/Source/TurnBasedTutorial/MyGameInstanceSubsystem.h b/Source/TurnBasedTutorial/MyGameInstanceSubsystem.h deleted file mode 100644 index 7a08655..0000000 --- a/Source/TurnBasedTutorial/MyGameInstanceSubsystem.h +++ /dev/null @@ -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& 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 LastSessionSettings; - - FOnUpdateSessionCompleteDelegate UpdateSessionCompleteDelegate; - FDelegateHandle UpdateSessionCompleteDelegateHandle; - - FOnStartSessionCompleteDelegate StartSessionCompleteDelegate; - FDelegateHandle StartSessionCompleteDelegateHandle; - - FOnEndSessionCompleteDelegate EndSessionCompleteDelegate; - FDelegateHandle EndSessionCompleteDelegateHandle; - - FOnDestroySessionCompleteDelegate DestroySessionCompleteDelegate; - FDelegateHandle DestroySessionCompleteDelegateHandle; - - FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate; - FDelegateHandle FindSessionsCompleteDelegateHandle; - TSharedPtr LastSessionSearch; - - FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate; - FDelegateHandle JoinSessionCompleteDelegateHandle; -}; diff --git a/Source/TurnBasedTutorial/MyMainMenu.cpp b/Source/TurnBasedTutorial/MyMainMenu.cpp deleted file mode 100644 index 3b0d757..0000000 --- a/Source/TurnBasedTutorial/MyMainMenu.cpp +++ /dev/null @@ -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(); - return GameInstanceSubsystem; -} - diff --git a/Source/TurnBasedTutorial/MyMainMenu.h b/Source/TurnBasedTutorial/MyMainMenu.h deleted file mode 100644 index f316b9f..0000000 --- a/Source/TurnBasedTutorial/MyMainMenu.h +++ /dev/null @@ -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; -}; diff --git a/Source/TurnBasedTutorial/MySessionListEntryWidget.cpp b/Source/TurnBasedTutorial/MySessionListEntryWidget.cpp deleted file mode 100644 index 67c5200..0000000 --- a/Source/TurnBasedTutorial/MySessionListEntryWidget.cpp +++ /dev/null @@ -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)); -} diff --git a/Source/TurnBasedTutorial/MySessionListEntryWidget.h b/Source/TurnBasedTutorial/MySessionListEntryWidget.h deleted file mode 100644 index d6c3b31..0000000 --- a/Source/TurnBasedTutorial/MySessionListEntryWidget.h +++ /dev/null @@ -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; -}; diff --git a/Source/TurnBasedTutorial/MySessionListWidget.cpp b/Source/TurnBasedTutorial/MySessionListWidget.cpp deleted file mode 100644 index 4c69dc5..0000000 --- a/Source/TurnBasedTutorial/MySessionListWidget.cpp +++ /dev/null @@ -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& 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(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(); - return GameInstanceSubsystem; -} diff --git a/Source/TurnBasedTutorial/MySessionListWidget.h b/Source/TurnBasedTutorial/MySessionListWidget.h deleted file mode 100644 index e305a8d..0000000 --- a/Source/TurnBasedTutorial/MySessionListWidget.h +++ /dev/null @@ -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 EntryClass; - - void RefreshList(const TArray& SessionResults, bool bSuccessful); - - void OnJoinSessionSuccess(EOnJoinSessionCompleteResult::Type Result); - -private: - UMyGameInstanceSubsystem* GetMyGameSubsystem() const; - - UFUNCTION() - void OnRefreshListButtonClicked(); - - UFUNCTION() - void ConnectToFirstSession(); -}; diff --git a/Source/TurnBasedTutorial/SessionsGameInstanceSubsystem.cpp b/Source/TurnBasedTutorial/SessionsGameInstanceSubsystem.cpp new file mode 100644 index 0000000..8f1de33 --- /dev/null +++ b/Source/TurnBasedTutorial/SessionsGameInstanceSubsystem.cpp @@ -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 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(), 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(), 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(), 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(); +} diff --git a/Source/TurnBasedTutorial/SessionsGameInstanceSubsystem.h b/Source/TurnBasedTutorial/SessionsGameInstanceSubsystem.h new file mode 100644 index 0000000..fd7d84d --- /dev/null +++ b/Source/TurnBasedTutorial/SessionsGameInstanceSubsystem.h @@ -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& + 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 LastSessionSettings; + + FOnUpdateSessionCompleteDelegate UpdateSessionCompleteDelegate; + FDelegateHandle UpdateSessionCompleteDelegateHandle; + + FOnStartSessionCompleteDelegate StartSessionCompleteDelegate; + FDelegateHandle StartSessionCompleteDelegateHandle; + + FOnEndSessionCompleteDelegate EndSessionCompleteDelegate; + FDelegateHandle EndSessionCompleteDelegateHandle; + + FOnDestroySessionCompleteDelegate DestroySessionCompleteDelegate; + FDelegateHandle DestroySessionCompleteDelegateHandle; + + FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate; + FDelegateHandle FindSessionsCompleteDelegateHandle; + TSharedPtr LastSessionSearch; + + FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate; + FDelegateHandle JoinSessionCompleteDelegateHandle; +}; diff --git a/Source/TurnBasedTutorial/TurnBasedTutorial.cpp b/Source/TurnBasedTutorial/TurnBasedTutorial.cpp index 967bcf2..dad6184 100644 --- a/Source/TurnBasedTutorial/TurnBasedTutorial.cpp +++ b/Source/TurnBasedTutorial/TurnBasedTutorial.cpp @@ -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"); diff --git a/Source/TurnBasedTutorial/TurnBasedTutorial.h b/Source/TurnBasedTutorial/TurnBasedTutorial.h index 4dd4c4f..018672a 100644 --- a/Source/TurnBasedTutorial/TurnBasedTutorial.h +++ b/Source/TurnBasedTutorial/TurnBasedTutorial.h @@ -3,4 +3,3 @@ #pragma once #include "Core.h" -