void ANinjaGameModeBase::BeginRound() { UWorld* World = GetWorld(); if (World) { ClearPlayerStartTags(); for (APlayerState* CurrState : GameState->PlayerArray) { ANinjaPlayerState* State = (ANinjaPlayerState*)CurrState; if (State) { APlayerController* Cont = (APlayerController*) State->GetOwner(); GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::Blue, FString::Printf(TEXT("%s"), *Cont->GetName())); if (State->GetChosenCharacter()) { GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::Red, FString::Printf(TEXT("%s - %s"), *Cont->GetName(), *State->GetChosenCharacter()->GetName())); } if (Cont) { ACharacter* Character = Cont->GetCharacter(); APlayerStart* PS = (APlayerStart*)ChoosePlayerStart(Cont); if (PS) { PS->PlayerStartTag = FName(TEXT("Taken")); if (Character) { Character->Destroy(); } FActorSpawnParameters Params; Params.Owner = Cont; ANinjaCharacter* SpawnedChar = World->SpawnActor<ANinjaCharacter>(State->GetChosenCharacter(), PS->GetActorLocation(), PS->GetActorRotation(), Params); if (SpawnedChar) { Cont->Possess(SpawnedChar); } } } } } } }
void ANUTActor::Tick(float DeltaSeconds) { Super::Tick(DeltaSeconds); UWorld* CurWorld = GetWorld(); if (CurWorld != NULL) { ENetMode CurNetMode = GEngine != NULL ? GEngine->GetNetMode(CurWorld) : NM_Standalone; bool bClientTimedOut = CurNetMode != NM_Standalone && (CurWorld->RealTimeSeconds - LastAliveTime) > (CurNetMode == NM_Client ? 5.0f : 10.0f); // Have the client tell the server they are still alive if (CurNetMode == NM_Client && bClientTimedOut) { ServerClientStillAlive(); LastAliveTime = CurWorld->RealTimeSeconds; } // Have the server set the owner, when appropriate if ((Cast<APlayerController>(GetOwner()) == NULL || bClientTimedOut) && GEngine != NULL && CurNetMode != NM_Client) { AGameState* GameState = CurWorld->GameState; if (GameState != NULL) { // @todo #JohnBReview: You want this to only happen if no remote players are present (perhaps give all players control instead, // if this becomes a problem - requires setting things up differently though) if (CurNetMode == NM_ListenServer || CurNetMode == NM_Standalone) { for (FLocalPlayerIterator It(GEngine, CurWorld); It; ++It) { if (It->PlayerController != NULL) { // Reset LastAliveTime, to give client a chance to send initial 'alive' RPC LastAliveTime = CurWorld->RealTimeSeconds; SetOwner(It->PlayerController); break; } } } for (int i=0; i<GameState->PlayerArray.Num(); i++) { APlayerController* PC = Cast<APlayerController>(GameState->PlayerArray[i] != NULL ? GameState->PlayerArray[i]->GetOwner() : NULL); if (PC != NULL && PC != GetOwner() && Cast<UNetConnection>(PC->Player) != NULL) { UE_LOG(LogUnitTest, Log, TEXT("Setting NUTActor owner to: %s (%s)"), *PC->GetName(), *GameState->PlayerArray[i]->PlayerName); // Reset LastAliveTime, to give client a chance to send initial 'alive' RPC LastAliveTime = CurWorld->RealTimeSeconds; SetOwner(PC); break; } } } } // Monitor for the beacon net driver, so it can be hooked if (bMonitorForBeacon) { #if TARGET_UE4_CL < CL_BEACONHOST UNetDriver* BeaconDriver = GEngine->FindNamedNetDriver(CurWorld, NAME_BeaconDriver); #else // Somehow, the beacon driver name got messed up in a subsequent checkin, so now has to be found manually UNetDriver* BeaconDriver = NULL; FWorldContext* CurContext = GEngine->GetWorldContextFromWorld(CurWorld); if (CurContext != NULL) { for (auto CurDriverRef : CurContext->ActiveNetDrivers) { if (CurDriverRef.NetDriverDef->DefName == NAME_BeaconDriver) { BeaconDriver = CurDriverRef.NetDriver; break; } } } #endif // Only hook when a client is connected if (BeaconDriver != NULL && BeaconDriver->ClientConnections.Num() > 0) { HookNetDriver(BeaconDriver); UE_LOG(LogUnitTest, Log, TEXT("Hooked beacon net driver")); // Also switch over replication to the beacon net driver Role = ROLE_None; SetReplicates(false); BeaconDriverName = BeaconDriver->NetDriverName; NetDriverName = BeaconDriverName; Role = ROLE_Authority; SetReplicates(true); // Send an RPC, for force actor channel replication NetMulticastPing(); bMonitorForBeacon = false; } } } }