// Project Lab - NHTV Igad

#include "UnrealProject.h"
#include "OffensiveEnemy.h"
#include "AbilityInfo.h"
#include "SpawnerBase.h"
#include "NetworkPlayer.h"
#include "MinionAnimInstance.h"
#include "BehaviorTree/EnemyAIController.h"


AOffensiveEnemy::AOffensiveEnemy()
{
	PrimaryActorTick.bCanEverTick = true;
}
void AOffensiveEnemy::BeginPlay()
{
	Super::BeginPlay();
	if (Role != ROLE_Authority)
		return;

}
void AOffensiveEnemy::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);
	if (Role != ROLE_Authority)
		return;
}
void AOffensiveEnemy::Tick(float deltaTime)
{
	Super::Tick(deltaTime);
	if (Role != ROLE_Authority)
		return;

	if (IsValid(target))
	{
		if (hasGeneral)
		{
			GeneralBehavior();
		}
		else
		{
			if (m_confusionTimer > 0.0f)
			{
				ConfusionBehavior();
				return;
			}
			BasicBehavior();
		}
		// Move to target

	}

}

void AOffensiveEnemy::GeneralBehavior()
{
	if (!meleeAbility || !specialAbility)
	{
		//RERROR("there is no abilities");
		return;
	}

	const FVector2D actorLocation = FVector2D(GetActorLocation().X, GetActorLocation().Y);
	const FVector2D targetLocation = FVector2D(target->GetActorLocation().X, target->GetActorLocation().Y);
	const float targetDistSqr = FVector2D::DistSquared(targetLocation, actorLocation);
	m_tempAbility = meleeAbility;
	if (((m_tempAbility->AICastRange + 150)*(m_tempAbility->AICastRange + 150)) < targetDistSqr)
		return;
	if (GetAbilityState(m_tempAbility)->onCooldownTimer <= 0)
	{
		CastAbility(m_tempAbility);

		UMinionAnimInstance* animInstance = Cast<UMinionAnimInstance>(GetMesh()->GetAnimInstance());
		if (IsValid(animInstance))
		{
			animInstance->ChangeAnimationStateTo(EMinionAnimState::MAS_Attacking);
		}

		//m_rotateToPlayer = m_tempAbility->rotateTowardsPlayer;
	}
}
void AOffensiveEnemy::BasicBehavior()
{
	if (!IsValid(target))
		return;
	if (FVector::DistSquared(target->GetActorLocation(), GetActorLocation()) > 200 * 200)
	{
		MoveToPoint(target->GetActorLocation());
	}
	else
	{
		FVector addvec = GetActorLocation() - target->GetActorLocation();
		addvec.Normalize();
		MoveToPoint(target->GetActorLocation()+addvec*200.0f);
		GetCharacterMovement()->Velocity = FVector::ZeroVector;
	}
	SetActorRotation(FVector(target->GetActorLocation() - GetActorLocation()).Rotation());
	if (!meleeAbility || !specialAbility)
	{
		//RERROR("there is no abilities");
		return;
	}
	const FVector2D actorLocation = FVector2D(GetActorLocation().X, GetActorLocation().Y);
	const FVector2D targetLocation = FVector2D(target->GetActorLocation().X, target->GetActorLocation().Y);
	const float targetDistSqr = FVector2D::DistSquared(targetLocation, actorLocation);
	m_tempAbility = meleeAbility;
	if ((rand() % 1000) > specialAbilityChance&&!m_isPulled)
	{
		m_tempAbility = specialAbility;
	}
	m_isPulled = true;
	if (((m_tempAbility->AICastRange + 150)*(m_tempAbility->AICastRange + 150)) < targetDistSqr)
		return;
	if (GetAbilityState(m_tempAbility)->onCooldownTimer <= 0)
	{
		CastAbility(m_tempAbility);

		UMinionAnimInstance* animInstance = Cast<UMinionAnimInstance>(GetMesh()->GetAnimInstance());
		if (IsValid(animInstance))
		{
			animInstance->ChangeAnimationStateTo(EMinionAnimState::MAS_Attacking);
		}

		
	}

} 
int32 AOffensiveEnemy::NativeDealDamage(class ANetworkCharacter* dealer, int32 damage, float armorPercentageIgnore, class UAbilityInfo* ability)
{
	if (hasGeneral)
	{
		float damageMultiplier = FVector::DotProduct(dealer->GetActorForwardVector(), GetActorForwardVector());
		damageMultiplier += 1.0f;
		damageMultiplier *= 0.5f;
		damageMultiplier += 0.5f;
		return Super::NativeDealDamage(dealer, damage*damageMultiplier, armorPercentageIgnore, ability);
	}
	else return Super::NativeDealDamage(dealer, damage, armorPercentageIgnore, ability);
}