diff --git a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp index 0ca88a0f..aa13789c 100644 --- a/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp +++ b/Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp @@ -2,13 +2,14 @@ #include "GDKSessionGameState.h" +#include "Interop/SpatialStaticComponentView.h" #include "TimerManager.h" #include "UnrealNetwork.h" #include "SpatialNetDriver.h" #include "SpatialWorkerConnection.h" -#include "c_worker.h" -#include "c_schema.h" +#include +#include void AGDKSessionGameState::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const { @@ -44,6 +45,13 @@ void AGDKSessionGameState::RemovePlayerState(APlayerState* PlayerState) void AGDKSessionGameState::OnRep_SessionProgress() { + USpatialNetDriver* SpatialNetDriver = Cast(GetWorld()->GetNetDriver()); + bool bAuthoritativeOverSessionEntity = SpatialNetDriver->StaticComponentView->HasAuthority(SessionEntityId, SessionComponentId); + + if (bAuthoritativeOverSessionEntity) + { + SendStateUpdate(SessionProgress); + } TimerEvent.Broadcast(SessionProgress, SessionTimer); } @@ -64,46 +72,63 @@ void AGDKSessionGameState::BeginTimer() void AGDKSessionGameState::TickGameTimer() { - if (GetNetMode() != NM_Client) + const bool bAuthoritativeOverSessionProgress = HasAuthority(); + + if (GetNetMode() != NM_Client && bAuthoritativeOverSessionProgress) { SessionTimer--; + USpatialNetDriver* SpatialNetDriver = Cast(GetWorld()->GetNetDriver()); + bool bAuthoritativeOverSessionEntity = SpatialNetDriver->StaticComponentView->HasAuthority(SessionEntityId, SessionComponentId); + if (SessionProgress == EGDKSessionProgress::Lobby && SessionTimer <= 0) { UE_LOG(LogGDK, Log, TEXT("Advance GameState to Running")); SessionProgress = EGDKSessionProgress::Running; - SendStateUpdate(2); + if (bAuthoritativeOverSessionEntity) + { + SendStateUpdate(SessionProgress); + } SessionTimer = GameSessionLength; } if (SessionProgress == EGDKSessionProgress::Running && SessionTimer <= 0) { UE_LOG(LogGDK, Log, TEXT("Advance GameState to Results")); SessionProgress = EGDKSessionProgress::Results; - SendStateUpdate(3); + if (bAuthoritativeOverSessionEntity) + { + SendStateUpdate(SessionProgress); + } SessionTimer = ResultsSessionLength; } if (SessionProgress == EGDKSessionProgress::Results && SessionTimer <= 0) { UE_LOG(LogGDK, Log, TEXT("Advance GameState to Finished")); SessionProgress = EGDKSessionProgress::Finished; - SendStateUpdate(4); + if (bAuthoritativeOverSessionEntity) + { + SendStateUpdate(SessionProgress); + } } } } -void AGDKSessionGameState::SendStateUpdate(int NewState) +void AGDKSessionGameState::SendStateUpdate(EGDKSessionProgress SessionProgressState) { if (!GetWorld()->GetNetDriver() || !GetWorld()->GetNetDriver()->IsA()) { return; } - Worker_EntityId target_entity_id = 39; + // There's an offset of 1 between the corresponding states of session progress and session state. + int SessionState = static_cast(SessionProgressState) + 1; + + Worker_EntityId target_entity_id = SessionEntityId; Worker_ComponentUpdate component_update = {}; - component_update.component_id = 1000; - component_update.schema_type = Schema_CreateComponentUpdate(1000); + component_update.component_id = SessionComponentId; + component_update.schema_type = Schema_CreateComponentUpdate(SessionComponentId); Schema_Object* fields_object = Schema_GetComponentUpdateFields(component_update.schema_type); - Schema_AddInt32(fields_object, 1, NewState); + Schema_AddInt32(fields_object, 1, SessionState); Cast(GetWorld()->GetNetDriver())->Connection->SendComponentUpdate(target_entity_id, &component_update); } diff --git a/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h b/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h index ff8f80e2..990d2ea6 100644 --- a/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h +++ b/Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h @@ -6,6 +6,9 @@ #include "GDKLogging.h" #include "Game/GDKGameState.h" #include "GDKSessionProgress.h" + +#include + #include "GDKSessionGameState.generated.h" DECLARE_EVENT_TwoParams(AGDKGameState, FSessionTimerEvent, EGDKSessionProgress, int); @@ -42,6 +45,9 @@ class GDKSHOOTER_API AGDKSessionGameState : public AGDKGameState UPROPERTY(EditAnywhere, Category = "Timers") int ResultsSessionLength = 60; + + Worker_EntityId SessionEntityId = 39; + Worker_ComponentId SessionComponentId = 1000; FTimerHandle TickTimer; @@ -55,7 +61,7 @@ class GDKSHOOTER_API AGDKSessionGameState : public AGDKGameState void TickGameTimer(); // Send a component update to the session manager entity to be picked up by the deployment manager - void SendStateUpdate(int NewState); + void SendStateUpdate(EGDKSessionProgress SessionProgressState); // Begin progressing through the different stages of game session, if not already started void BeginTimer(); diff --git a/LaunchServer.bat b/LaunchServer.bat index 222bdcc6..702cdb6c 100644 --- a/LaunchServer.bat +++ b/LaunchServer.bat @@ -1,3 +1,3 @@ @echo off call "%~dp0ProjectPaths.bat" -"%UNREAL_HOME%\Engine\Binaries\Win64\UE4Editor.exe" "%~dp0%PROJECT_PATH%\%GAME_NAME%.uproject" ThirdPersonExampleMap -server -log -workerType UnrealWorker -stdout -nowrite -unattended -nologtimes -nopause -noin -messaging -SaveToUserDir -NoVerifyGC -windowed -resX=400 -resY=300 +"%UNREAL_HOME%\Engine\Binaries\Win64\UE4Editor.exe" "%~dp0%PROJECT_PATH%\%GAME_NAME%.uproject" FPS-Start_Medium -server -log -workerType UnrealWorker -stdout -nowrite -unattended -nologtimes -nopause -noin -messaging -SaveToUserDir -NoVerifyGC -windowed -resX=400 -resY=300 diff --git a/README.md b/README.md index da28ce0e..f573b906 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # SpatialOS Unreal GDK Example Project + + - **LICENSE:** Use of the contents of this repository is subject to the [license](LICENSE.md) This project is an example shooter game which uses the [SpatialOS GDK for Unreal](https://github.com/spatialos/unrealGDK). @@ -51,4 +53,4 @@ The GDK and related projects are available on GitHub. We are not currently accepting public contributions. However, we are accepting [issues](https://github.com/spatialos/UnrealGDK/issues) and we do want your feedback. -© 2019 Improbable \ No newline at end of file +© 2019 Improbable