// Copyright Epic Games, Inc. All Rights Reserved. #include "LyraPlayerStart.h" #include "Delegates/Delegate.h" #include "Engine/World.h" #include "GameFramework/Controller.h" #include "GameFramework/GameModeBase.h" #include "GameFramework/Pawn.h" #include "Math/MathFwd.h" #include "Math/Rotator.h" #include "Math/Vector.h" #include "Templates/SubclassOf.h" #include "TimerManager.h" #include "UObject/Class.h" ALyraPlayerStart::ALyraPlayerStart(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { } ELyraPlayerStartLocationOccupancy ALyraPlayerStart::GetLocationOccupancy(AController* const ControllerPawnToFit) const { UWorld* const World = GetWorld(); if (HasAuthority() && World) { if (AGameModeBase* AuthGameMode = World->GetAuthGameMode()) { TSubclassOf PawnClass = AuthGameMode->GetDefaultPawnClassForController(ControllerPawnToFit); const APawn* const PawnToFit = PawnClass ? GetDefault(PawnClass) : nullptr; FVector ActorLocation = GetActorLocation(); const FRotator ActorRotation = GetActorRotation(); if (!World->EncroachingBlockingGeometry(PawnToFit, ActorLocation, ActorRotation, nullptr)) { return ELyraPlayerStartLocationOccupancy::Empty; } else if (World->FindTeleportSpot(PawnToFit, ActorLocation, ActorRotation)) { return ELyraPlayerStartLocationOccupancy::Partial; } } } return ELyraPlayerStartLocationOccupancy::Full; } bool ALyraPlayerStart::IsClaimed() const { return ClaimingController != nullptr; } bool ALyraPlayerStart::TryClaim(AController* OccupyingController) { if (OccupyingController != nullptr && !IsClaimed()) { ClaimingController = OccupyingController; if (UWorld* World = GetWorld()) { World->GetTimerManager().SetTimer(ExpirationTimerHandle, FTimerDelegate::CreateUObject(this, &ALyraPlayerStart::CheckUnclaimed), ExpirationCheckInterval, true); } return true; } return false; } void ALyraPlayerStart::CheckUnclaimed() { if (ClaimingController != nullptr && ClaimingController->GetPawn() != nullptr && GetLocationOccupancy(ClaimingController) == ELyraPlayerStartLocationOccupancy::Empty) { ClaimingController = nullptr; if (UWorld* World = GetWorld()) { World->GetTimerManager().ClearTimer(ExpirationTimerHandle); } } }