haxis/Source/UnrealProject/Creatures/RangedEnemy.cpp

136 lines
3.8 KiB
C++

// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "RangedEnemy.h"
#include "AbilityInfo.h"
#include "SpawnerBase.h"
#include "NetworkPlayer.h"
#include "MinionAnimInstance.h"
ARangedEnemy::ARangedEnemy()
{
PrimaryActorTick.bCanEverTick = true;
}
void ARangedEnemy::BeginPlay()
{
Super::BeginPlay();
if (Role != ROLE_Authority)
return;
}
void ARangedEnemy::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
if (Role != ROLE_Authority)
return;
}
void ARangedEnemy::Tick(float deltaTime)
{
Super::Tick(deltaTime);
if (Role != ROLE_Authority)
return;
if (IsValid(target))
{
if (!hasGeneral)
{
if (m_confusionTimer > 0.0f)
{
ConfusionBehavior();
return;
}
BasicBehavior();
}
else
{
GeneralBehavior();
}
// Move to target
}
}
void ARangedEnemy::BasicBehavior()
{
if (!IsValid(target))
return;
const FVector2D actorLocation = FVector2D(GetActorLocation().X, GetActorLocation().Y);
const FVector2D targetLocation = FVector2D(target->GetActorLocation().X, target->GetActorLocation().Y);
const FVector2D spawnLocation = FVector2D(m_spawn->GetActorLocation());
const float targetDistSqr = FVector2D::DistSquared(targetLocation, actorLocation);
const float spawnTargetDistSqr = FVector2D::DistSquared(targetLocation, spawnLocation);
if (!meleeAbility || !specialAbility)
{
RERROR("there is no abilities");
return;
}
if (!rangedAbility)
{
RERROR("Ranged enemy does not have a ranged ability");
}
float castRange = rangedAbility->AICastRange;
// walking code
float testPercentage = (spawnTargetDistSqr) / ((m_spawn->aggroRadius + castRange)*(m_spawn->aggroRadius + castRange));
FVector newLocation = (target->GetActorLocation() - m_spawn->GetActorLocation());
newLocation.Normalize();
newLocation *= m_spawn->aggroRadius*testPercentage;
FVector walkLocation = newLocation + m_spawn->GetActorLocation();
if (m_lastPercentage < testPercentage)
MoveToPoint(walkLocation);
m_lastPercentage = testPercentage;
m_tempAbility = rangedAbility;
if (targetDistSqr < (200 * 200))
{
m_tempAbility = meleeAbility;
if ((rand() % 1000) > specialAbilityChance)
{
m_tempAbility = specialAbility;
}
}
if (((m_tempAbility->AICastRange + 100)*(m_tempAbility->AICastRange + 100)) < targetDistSqr)
return;
if (GetAbilityState(m_tempAbility)->onCooldownTimer <= 0)
{
ChangeNPCAnimation((uint8)EMinionAnimState::MAS_Casting);
CastAbility(m_tempAbility);
}
SetActorRotation(FVector(target->GetActorLocation() - GetActorLocation()).Rotation());
}
void ARangedEnemy::GeneralBehavior()
{
const FVector2D actorLocation = FVector2D(GetActorLocation().X, GetActorLocation().Y);
const FVector2D targetLocation = FVector2D(target->GetActorLocation().X, target->GetActorLocation().Y);
const FVector2D spawnLocation = FVector2D(m_spawn->GetActorLocation());
const float targetDistSqr = FVector2D::DistSquared(targetLocation, actorLocation);
const float spawnTargetDistSqr = FVector2D::DistSquared(targetLocation, spawnLocation);
if (!meleeAbility || !specialAbility)
{
RERROR("there is no abilities");
return;
}
if (!rangedAbility)
{
RERROR("Ranged enemy does not have a ranged ability");
}
float castRange = rangedAbility->AICastRange;
// walking code
m_tempAbility = rangedAbility;
if (targetDistSqr < (200 * 200))
{
m_tempAbility = meleeAbility;
}
if (((m_tempAbility->AICastRange + 100)*(m_tempAbility->AICastRange + 100)) < targetDistSqr)
return;
if (GetAbilityState(m_tempAbility)->onCooldownTimer <= 0)
{
ChangeNPCAnimation((uint8)EMinionAnimState::MAS_Casting);
CastAbility(m_tempAbility);
m_rotateToPlayer = m_tempAbility->rotateTowardsPlayer;
}
SetActorRotation(FVector(target->GetActorLocation() - GetActorLocation()).Rotation());
}