void AZombieCharacter::Attack()
{
	//This function is used only when it's permitted by the zombie's animation instance
	//It creates a raycast in a sphere shape and checks for possible hits
	//If the hits contain our player it makes sure it applies damage to him

	//Setting up the start and end location of the raycast
	FVector StartLocation = GetMesh()->GetSocketLocation(FName("MeleeStartSocket"));
	FVector EndLocation = GetMesh()->GetSocketLocation(FName("MeleeEndSocket"));


	//Raycasting in a sphere to detect collisions
	TArray<FHitResult> HitResults;

	//Setting up the shape of the raycast
	FCollisionShape CollisionShape;
	CollisionShape.ShapeType = ECollisionShape::Sphere;
	CollisionShape.SetSphere(AttackRaycastRadius);

	//Object query parameters
	FCollisionObjectQueryParams ObjectQueryParams;
	ObjectQueryParams.AllDynamicObjects;

	//Handling ignored actors
	FCollisionQueryParams QueryParams;
	QueryParams.AddIgnoredActor(this);

	UWorld* World = GetWorld();
	if (World && ZAnimInstance->bEligibleForAttack)
	{
		//Raycasting...
		bool bHit = World->SweepMultiByObjectType(HitResults, StartLocation, EndLocation, FQuat::Identity, ObjectQueryParams, CollisionShape, QueryParams);

		//Raycast visualization
		/*FVector Center = ((EndLocation - StartLocation) / 2) + StartLocation;
		DrawDebugSphere(World, Center, AttackRaycastRadius, 20, FColor::Green, false, 2.f);*/

		//Checking for possible hits
		if (bHit)
		{
			for (auto It = HitResults.CreateIterator(); It; It++)
			{
				ARoguelikeChar* Char = Cast<ARoguelikeChar>(It->GetActor());
				if (Char && ZAnimInstance && GetCharacterMovement())
				{
					//Calling the attack function from character
					Char->TakeDamageFromZombie(Damage);
					
					//Closing the flag which checks for the attack function
					ZAnimInstance->bEligibleForAttack = false;

					//Updating with new movement speed
					GetCharacterMovement()->MaxWalkSpeed = InitialMaxWalkSpeed;
					ZAnimInstance->Speed = InitialMaxWalkSpeed;
					break;
				}
			}
		}
	}

}
AEyeXActorBase* AEyeXPlayerController::FindBySweep(FHitResult& OutHit, const FSceneView* const View, const FVector2D& GazePoint,
	const FCollisionObjectQueryParams& ObjectParams, const FCollisionQueryParams& TraceParams)
{
	if (SweepIntervals <= 1)
	{
		UE_LOG(LogEyeX, Warning, TEXT("Invalid value for SweepIntervals: %i. Must be greater than 0."), SweepIntervals);
		return nullptr;
	}

	UWorld* World = GetWorld();
	if (!World) return nullptr;

	FVector Start, Direction;
	View->DeprojectFVector2D(GazePoint, Start, Direction);

	const float TanFOVScaled = GetTanOfFOVAngleScaled();

	// Perform sweeps
	const float DeltaDistance = MaxDistance / SweepIntervals;
	const FVector DeltaDirection = DeltaDistance * Direction;
	float CurrentDistance = DeltaDistance / 2;
	FCollisionShape Shape;
	AEyeXActorBase* EyeXActor = nullptr;
	for (int i = 0; i < SweepIntervals; ++i)	
	{
		const FVector End = Start + DeltaDirection;
		const float Radius = (i == 0) ? 0.0f : TanFOVScaled * CurrentDistance; // Depends on the view frustrum, size of the screen and the distance.
		Shape.SetSphere(Radius);

		if (World->SweepSingleByObjectType(OutHit, Start, End, FQuat::Identity, ObjectParams, Shape, TraceParams))
		{
			EyeXActor = Cast<AEyeXActorBase>(OutHit.GetActor());
			break;
		}

		Start = End;
		CurrentDistance += DeltaDistance;
	}
	
	VisualizeHit(bVisualizeDetection, World, OutHit, Shape.GetSphereRadius());
	VisualizeGazePoint(bVisualizeDetection, World, Start);

	return EyeXActor;
}
EBTNodeResult::Type UBTTask_Escape::ExecuteTask(UBehaviorTreeComponent& OwnedTree, uint8* Node)
{
	AWolfAIController* Controller = Cast<AWolfAIController>(OwnedTree.GetAIOwner());
	if (!Controller)
	{
		GLog->Log("Controller fail");
		return EBTNodeResult::Failed;
	}


	FName SensedTargetKey = "SensedTarget";
	AMyCharacter_FirstTry* Caveman = Cast<AMyCharacter_FirstTry>(OwnedTree.GetBlackboardComponent()->GetValueAsObject(SensedTargetKey));
	if (Caveman)
	{
		TArray<FHitResult> HitResults;
		//Start and End Location of the capsule
		FVector StartLocation = Caveman->GetActorLocation();
		FVector EndLocation = StartLocation;
		EndLocation.Z += Caveman->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight() / 2;

		//Collision Channel
		ECollisionChannel ECC = ECollisionChannel::ECC_WorldDynamic;

		//Collision Shape
		FCollisionShape CollisionShape;

		//Making Collision in sphere
		CollisionShape.ShapeType = ECollisionShape::Sphere;
		CollisionShape.SetSphere(350);

		//Sweeping for possible escape nodes
		if (Caveman->GetWorld()->SweepMultiByChannel(HitResults, StartLocation, EndLocation, FQuat::FQuat(), ECC, CollisionShape))
		{
			//DrawDebugSphere(Caveman->GetWorld(), ((EndLocation - StartLocation) / 2) + StartLocation, CollisionShape.GetSphereRadius(), 100, FColor::Green, true);
			TArray<AActor*> AllPathNodes;
			UGameplayStatics::GetAllActorsOfClass(Caveman->GetWorld(), APathNode::StaticClass(), AllPathNodes);

			APathNode* NextNode;
			NextNode = Cast<APathNode>(AllPathNodes[FMath::RandRange(0, AllPathNodes.Num() - 1)]);
			//Finding next possible node
			while (NextNode->bIsCurrentlyOccupied && AllPathNodes.Contains(NextNode))
			{
				NextNode = Cast<APathNode>(AllPathNodes[FMath::RandRange(0, AllPathNodes.Num() - 1)]);
				GLog->Log("Fear success");
			}

			//Occupy the node
			NextNode->bIsCurrentlyOccupied = true;
			
			//Set the new node in the blackboard
			OwnedTree.GetBlackboardComponent()->SetValue<UBlackboardKeyType_Object>(BlackboardKey.GetSelectedKeyID(), NextNode);
			//OwnedTree.GetBlackboardComponent()->SetValue<UBlackboardKeyType_Object>(Bl)
			
			GLog->Log("Success after while");
			return EBTNodeResult::Succeeded;

		}

	}

	GLog->Log("General Fail");
	return EBTNodeResult::Failed;
}