text: // Copyright 2019 Dan Kestranek.
  
  #include "GASDocumentationGameMode.h"
  #include "Engine/World.h"
  #include "GDHeroCharacter.h"
  #include "GDPlayerController.h"
  #include "GDPlayerState.h"
  #include "GameFramework/SpectatorPawn.h"
  #include "Kismet/GameplayStatics.h"
  #include "TimerManager.h"
  #include "UObject/ConstructorHelpers.h"
  
  AGASDocumentationGameMode::AGASDocumentationGameMode()
  {
  	RespawnDelay = 5.0f;
  
  	HeroClass = StaticLoadClass(UObject::StaticClass(), nullptr, TEXT("/Game/GASDocumentation/Characters/Hero/BP_HeroCharacter.BP_HeroCharacter_C"));
  	if (!HeroClass)
  	{
  		UE_LOG(LogTemp, Error, TEXT("%s() Failed to find HeroClass. If it was moved, please update the reference location in C++."), TEXT(__FUNCTION__));
  	}
  }
  
  void AGASDocumentationGameMode::HeroDied(AController* Controller)
  {
  	FActorSpawnParameters SpawnParameters;
  	SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
  	ASpectatorPawn* SpectatorPawn = GetWorld()->SpawnActor<ASpectatorPawn>(SpectatorClass, Controller->GetPawn()->GetActorTransform(), SpawnParameters);
  
  	Controller->UnPossess();
  	Controller->Possess(SpectatorPawn);
  
  	FTimerHandle RespawnTimerHandle;
  	FTimerDelegate RespawnDelegate;
  
  	RespawnDelegate = FTimerDelegate::CreateUObject(this, &AGASDocumentationGameMode::RespawnHero, Controller);
  	GetWorldTimerManager().SetTimer(RespawnTimerHandle, RespawnDelegate, RespawnDelay, false);
  
  	AGDPlayerController* PC = Cast<AGDPlayerController>(Controller);
  	if (PC)
  	{
  		PC->SetRespawnCountdown(RespawnDelay);
  	}
  }
  
  void AGASDocumentationGameMode::BeginPlay()
  {
  	Super::BeginPlay();
  
  	// Get the enemy hero spawn point
  	TArray<AActor*> Actors;
  	UGameplayStatics::GetAllActorsOfClass(GetWorld(), AActor::StaticClass(), Actors);
  	for (AActor* Actor : Actors)
  	{
  		if (Actor->GetName() == FString("EnemyHeroSpawn"))
  		{
  			EnemySpawnPoint = Actor;
  			break;
  		}
  	}
  }
  
  void AGASDocumentationGameMode::RespawnHero(AController * Controller)
  {
  	if (Controller->IsPlayerController())
  	{
  		// Respawn player hero
  		AActor* PlayerStart = FindPlayerStart(Controller);
  
  		FActorSpawnParameters SpawnParameters;
  		SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
  
  		AGDHeroCharacter* Hero = GetWorld()->SpawnActor<AGDHeroCharacter>(HeroClass, PlayerStart->GetActorLocation(), PlayerStart->GetActorRotation(), SpawnParameters);
  
  		APawn* OldSpectatorPawn = Controller->GetPawn();
  		Controller->UnPossess();
  		OldSpectatorPawn->Destroy();
  		Controller->Possess(Hero);
  	}
  	else
  	{
  		// Respawn AI hero
  		FActorSpawnParameters SpawnParameters;
  		SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
  
  		AGDHeroCharacter* Hero = GetWorld()->SpawnActor<AGDHeroCharacter>(HeroClass, EnemySpawnPoint->GetActorTransform(), SpawnParameters);
  		
  		APawn* OldSpectatorPawn = Controller->GetPawn();
  		Controller->UnPossess();
  		OldSpectatorPawn->Destroy();
  		Controller->Possess(Hero);
  	}
  }
  