// Project Lab - NHTV Igad

#include "UnrealProject.h"
#include "NetworkGhost.h"
#include "NetworkPlayer.h"
#include "DefaultPlayerState.h"


// Sets default values
ANetworkGhost::ANetworkGhost()
{
	bReplicates = true;

	postProcess = CreateDefaultSubobject<UPostProcessComponent>(TEXT("PostProcess"));
	postProcess->bEnabled = false;
	postProcess->AttachTo(RootComponent);

	m_SetupCamera();

	// Configure character movement
	GetCharacterMovement()->bOrientRotationToMovement = true; // Rotate character to moving direction
	GetCharacterMovement()->RotationRate = FRotator(0.f, 640.f, 0.f);
	GetCharacterMovement()->bConstrainToPlane = true;
	GetCharacterMovement()->bSnapToPlaneAtStart = true;

	shrinesInRange = 0;
	respawnDuration = 15;
	allyRespawnRange = 300;
}

void ANetworkGhost::BeginPlay()
{
	Super::BeginPlay();

	m_respawnTime = respawnDuration;
}

void ANetworkGhost::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	// Update the respawn timer (server only)
	if (Role == ROLE_Authority)
	{
		if (m_respawnTime > 0)
			m_respawnTime -= DeltaTime;
	}

	// Enable the post process on clients
	if (IsValid(GetController()))
		postProcess->bEnabled = GetController()->IsLocalController();
}


bool ANetworkGhost::CanRespawn() const
{
	// Cannot respawn yet
	if (m_respawnTime > 0)
		return false;

	// If we're falling, were unable to respawn
	if (!GetCharacterMovement()->IsMovingOnGround())
		return false;

	// We're at a shrine
	if (shrinesInRange > 0)
		return true;

	// Check if the ally is within the radius, so we can respawn next to him
	ADefaultPlayerState* state = Cast<ADefaultPlayerState>(PlayerState);
	bool inAllyRange = false;
	if (IsValid(state) && IsValid(state->teamMate) && IsValid(state->teamMate->character))
	{
		if (FVector::DistSquared(GetActorLocation(), state->teamMate->character->GetActorLocation()) <= (allyRespawnRange * allyRespawnRange))
			return true;
	}
	return false;
}

float ANetworkGhost::RespawnTime() const
{
	return m_respawnTime;
}


void ANetworkGhost::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	DOREPLIFETIME(ANetworkGhost, m_respawnTime);
}