AActor* AGameModeBase::ChoosePlayerStart_Implementation(AController* Player)
{
	// Choose a player start
	APlayerStart* FoundPlayerStart = nullptr;
	UClass* PawnClass = GetDefaultPawnClassForController(Player);
	APawn* PawnToFit = PawnClass ? PawnClass->GetDefaultObject<APawn>() : nullptr;
	TArray<APlayerStart*> UnOccupiedStartPoints;
	TArray<APlayerStart*> OccupiedStartPoints;
	for (TActorIterator<APlayerStart> It(GetWorld()); It; ++It)
	{
		APlayerStart* PlayerStart = *It;

		if (PlayerStart->IsA<APlayerStartPIE>())
		{
			// Always prefer the first "Play from Here" PlayerStart, if we find one while in PIE mode
			FoundPlayerStart = PlayerStart;
			break;
		}
		else
		{
			FVector ActorLocation = PlayerStart->GetActorLocation();
			const FRotator ActorRotation = PlayerStart->GetActorRotation();
			if (!GetWorld()->EncroachingBlockingGeometry(PawnToFit, ActorLocation, ActorRotation))
			{
				UnOccupiedStartPoints.Add(PlayerStart);
			}
			else if (GetWorld()->FindTeleportSpot(PawnToFit, ActorLocation, ActorRotation))
			{
				OccupiedStartPoints.Add(PlayerStart);
			}
		}
	}
	if (FoundPlayerStart == nullptr)
	{
		if (UnOccupiedStartPoints.Num() > 0)
		{
			FoundPlayerStart = UnOccupiedStartPoints[FMath::RandRange(0, UnOccupiedStartPoints.Num() - 1)];
		}
		else if (OccupiedStartPoints.Num() > 0)
		{
			FoundPlayerStart = OccupiedStartPoints[FMath::RandRange(0, OccupiedStartPoints.Num() - 1)];
		}
	}
	return FoundPlayerStart;
}
Exemple #2
0
AActor* AGunLockGameMode::ChoosePlayerStart(AController* Player)
{
	// Find a player start that is furthest from other players
	APawn* PawnToFit = DefaultPawnClass ? DefaultPawnClass->GetDefaultObject<APawn>() : NULL;
	APlayerStart* BestPlayerStart = NULL;
	float MaxPlayerDistance = 0.0f;

	for (int32 PlayerStartIndex = 0; PlayerStartIndex < PlayerStarts.Num(); ++PlayerStartIndex)
	{
		APlayerStart* PlayerStart = PlayerStarts[PlayerStartIndex];
		if (PlayerStart != NULL)
		{
			// Always prefer the first "Play from Here" PlayerStart, if we find one while in PIE mode
			if (Cast<APlayerStartPIE>(PlayerStart) != NULL)
				return PlayerStart;

			// Find the minimum distance to other players
			float MinPlayerDistance = HALF_WORLD_MAX;
			FVector SpawnLocation = PlayerStart->GetActorLocation();
			const FRotator SpawnRotation = PlayerStart->GetActorRotation();
			for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
			{
				APlayerController* PlayerController = *Iterator;
				if (Player != PlayerController && PlayerController->GetPawn())
				{
					MinPlayerDistance = FMath::Min(MinPlayerDistance, (SpawnLocation - PlayerController->GetPawn()->GetActorLocation()).Size());
				}
			}

			// Choose the spawn that is furtherest from all other players, to give them a fighting chance!
			if (MinPlayerDistance > MaxPlayerDistance)
			{
				MaxPlayerDistance = MinPlayerDistance;
				BestPlayerStart = PlayerStart;
			}
		}
	}
	//If we couldn't find any suitable spawns, pick a random one!
	if (BestPlayerStart == NULL && PlayerStarts.Num() > 0)
	{
		return PlayerStarts[FMath::RandRange(0, PlayerStarts.Num() - 1)];
	}
	return BestPlayerStart;
}
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);
						}
					}

				}
				
			}
		}
	}
}