Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Game/Config/DefaultSpatialGDKEditorSettings.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

[/Script/SpatialGDKEditor.SpatialGDKEditorSettings]
bDeleteDynamicEntities=True
bGenerateDefaultLaunchConfig=True
bStopSpatialOnExit=False
SpatialOSSnapshotFile=default.snapshot
LaunchConfigDesc=(Template="small",World=(Dimensions=(X=2000,Y=2000),ChunkEdgeLengthMeters=5,StreamingQueryIntervalSeconds=4,SnapshotWritePeriodSeconds=0,LegacyFlags=(("bridge_qos_max_timeout", "0"),("bridge_soft_handover_enabled", "false"),("enable_chunk_interest", "false")),LegacyJavaParams=()),Workers=((WorkerTypeName="UnrealWorker",Columns=1)))
bGeneratePlaceholderEntitiesInSnapshot=True

Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,7 @@ void AGDKCharacter::RegenerateHealth()

float AGDKCharacter::TakeDamage(float Damage, const FDamageEvent& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{

float ActualDamage = Super::TakeDamage(Damage, DamageEvent, EventInstigator, DamageCauser);

TakeDamageCrossServer(ActualDamage, DamageEvent, EventInstigator, DamageCauser);
TakeDamageCrossServer(Damage, DamageEvent, EventInstigator, DamageCauser);

return Damage;
}
Expand All @@ -210,6 +207,10 @@ void AGDKCharacter::TakeDamageCrossServer_Implementation(float Damage, const FDa
return;
}

check(DamageCauser);

Damage = Super::TakeDamage(Damage, DamageEvent, EventInstigator, DamageCauser);

const AWeapon* DamageSourceWeapon = Cast<AWeapon>(DamageCauser);
const AGDKCharacter* Killer = Cast<AGDKCharacter>(DamageSourceWeapon->GetWeilder());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,11 @@ void AGDKShooterCharacter::EquipWeapon_Implementation(int32 WeaponId)

EquippedWeapon->SetIsActive(false);
EquippedWeapon = AvailableWeapons[WeaponId];
EquippedWeapon->SetIsActive(true);

if (EquippedWeapon != nullptr)
{
EquippedWeapon->SetIsActive(true);
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ void ADeploymentsPlayerController::QueryPIT()
{
Worker_Alpha_PlayerIdentityTokenRequest* PITParams = new Worker_Alpha_PlayerIdentityTokenRequest();
// Replace this string with a dev auth token, see docs for information on how to generate one of these
PITParams->development_authentication_token_id = "REPLACE ME";
PITParams->development_authentication_token = "REPLACE ME";
PITParams->player_id = "Player Id";
PITParams->display_name = "";
PITParams->metadata = "";
Expand Down
42 changes: 29 additions & 13 deletions Game/Source/GDKShooter/Private/Game/GDKSessionGameState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <WorkerSDK/improbable/c_schema.h>
#include <WorkerSDK/improbable/c_worker.h>

void AGDKSessionGameState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Expand Down Expand Up @@ -44,6 +45,7 @@ void AGDKSessionGameState::RemovePlayerState(APlayerState* PlayerState)

void AGDKSessionGameState::OnRep_SessionProgress()
{
SendStateUpdate(SessionProgress);
TimerEvent.Broadcast(SessionProgress, SessionTimer);
}

Expand All @@ -64,47 +66,61 @@ void AGDKSessionGameState::BeginTimer()

void AGDKSessionGameState::TickGameTimer()
{
if (GetNetMode() != NM_Client)
const bool bAuthoritativeOverSessionProgress = HasAuthority();

if (GetNetMode() != NM_Client && bAuthoritativeOverSessionProgress)
{
SessionTimer--;

if (SessionProgress == EGDKSessionProgress::Lobby && SessionTimer <= 0)
{
UE_LOG(LogGDK, Log, TEXT("Advance GameState to Running"));
SessionProgress = EGDKSessionProgress::Running;
SendStateUpdate(2);
SendStateUpdate(SessionProgress);
SessionTimer = GameSessionLength;
}
if (SessionProgress == EGDKSessionProgress::Running && SessionTimer <= 0)
{
UE_LOG(LogGDK, Log, TEXT("Advance GameState to Results"));
SessionProgress = EGDKSessionProgress::Results;
SendStateUpdate(3);
SendStateUpdate(SessionProgress);
SessionTimer = ResultsSessionLength;
}
if (SessionProgress == EGDKSessionProgress::Results && SessionTimer <= 0)
{
UE_LOG(LogGDK, Log, TEXT("Advance GameState to Finished"));
SessionProgress = EGDKSessionProgress::Finished;
SendStateUpdate(4);
SendStateUpdate(SessionProgress);
}
}
}

void AGDKSessionGameState::SendStateUpdate(int NewState)
void AGDKSessionGameState::SendStateUpdate(EGDKSessionProgress SessionProgressState)
{
if (!GetWorld()->GetNetDriver() || !GetWorld()->GetNetDriver()->IsA<USpatialNetDriver>())
// Only send the state update if we're using Spatial networking and if we have authority over the session entity.
UNetDriver* NetDriver = GetWorld()->GetNetDriver();
if (NetDriver == nullptr || !NetDriver->IsA<USpatialNetDriver>())
{
return;
}

Worker_EntityId target_entity_id = 39;
USpatialNetDriver* SpatialNetDriver = Cast<USpatialNetDriver>(NetDriver);
bool bAuthoritativeOverSessionEntity = SpatialNetDriver->StaticComponentView->HasAuthority(SessionEntityId, SessionComponentId);
if (!bAuthoritativeOverSessionEntity)
{
return;
}

// There's an offset of 1 between the corresponding states of session progress and session state.
int SessionState = static_cast<int>(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);
Cast<USpatialNetDriver>(GetWorld()->GetNetDriver())->Connection->SendComponentUpdate(target_entity_id, &component_update);
Schema_AddInt32(fields_object, 1, SessionState);
SpatialNetDriver->Connection->SendComponentUpdate(target_entity_id, &component_update);
}


8 changes: 4 additions & 4 deletions Game/Source/GDKShooter/Private/Weapons/Projectile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void AProjectile::OnRep_MetaData()

void AProjectile::Tick(float DeltaTime)
{
if (GetNetMode() == NM_Client)
if (!HasAuthority())
{
return;
}
Expand All @@ -95,7 +95,7 @@ void AProjectile::Tick(float DeltaTime)

void AProjectile::OnStop(const FHitResult& ImpactResult)
{
if (GetNetMode() == NM_Client)
if (!HasAuthority())
{
return;
}
Expand All @@ -108,7 +108,7 @@ void AProjectile::OnStop(const FHitResult& ImpactResult)

void AProjectile::OnBounce(const FHitResult& ImpactResult, const FVector& ImpactVelocity)
{
if (GetNetMode() == NM_Client)
if (!HasAuthority())
{
return;
}
Expand All @@ -133,7 +133,7 @@ void AProjectile::ExplosionVisuals_Implementation()

void AProjectile::Explode()
{
if (GetNetMode() == NM_Client)
if (!HasAuthority())
{
return;
}
Expand Down
8 changes: 7 additions & 1 deletion Game/Source/GDKShooter/Public/Game/GDKSessionGameState.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#include "GDKLogging.h"
#include "Game/GDKGameState.h"
#include "GDKSessionProgress.h"

#include <WorkerSDK/improbable/c_worker.h>

#include "GDKSessionGameState.generated.h"

DECLARE_EVENT_TwoParams(AGDKGameState, FSessionTimerEvent, EGDKSessionProgress, int);
Expand Down Expand Up @@ -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;

Expand All @@ -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();
Expand Down
2 changes: 2 additions & 0 deletions Game/Source/GDKShooter/Public/Weapons/Projectile.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ class GDKSHOOTER_API AProjectile : public AActor
UFUNCTION(BlueprintNativeEvent)
void ExplosionVisuals();

UPROPERTY(Handover)
AController* InstigatingController;

UPROPERTY(Handover)
AWeapon* InstigatingWeapon;

UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = Projectile)
Expand Down