190 lines
5.1 KiB
C++
190 lines
5.1 KiB
C++
// Project Lab - NHTV Igad
|
|
|
|
#include "UnrealProject.h"
|
|
#include "SpawnerBase.h"
|
|
#include "EnemyBase.h"
|
|
#include "AbilityInfo.h"
|
|
#include "NetworkPlayer.h"
|
|
#include "GeneralEnemy.h"
|
|
#include "BehaviorTree/EnemyAIController.h"
|
|
#include "BehaviorTree/BehaviorTree.h"
|
|
#include "MinionAnimInstance.h"
|
|
|
|
AEnemyBase::AEnemyBase()
|
|
{
|
|
PrimaryActorTick.bCanEverTick = true;
|
|
finnishedAttack = false;
|
|
informGeneralTime = 2.0f;
|
|
m_tempTarget = nullptr;
|
|
// AIControllerClass = AEnemyAIController::StaticClass();
|
|
}
|
|
void AEnemyBase::BeginPlay()
|
|
{
|
|
Super::BeginPlay();
|
|
|
|
specialAbilityChance = m_ReCalcChance(specialAbilityChance);
|
|
enemycontroller = Cast<AEnemyAIController>(GetController());
|
|
if (enemycontroller && m_spawn)
|
|
{
|
|
enemycontroller->SetBool(true, FName("ClimbKey"));
|
|
enemycontroller->SetVector(FVector(0, 0, 1), FName("ClimbDirection"));
|
|
enemycontroller->SetVector(m_spawn->GetActorLocation() + FVector(0, 0, 100), FName("ClimbLocation"));
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
FActorSpawnParameters SpawnInfo;
|
|
SpawnInfo.Instigator = Instigator;
|
|
SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
|
SpawnInfo.OverrideLevel = GetLevel();
|
|
SpawnInfo.ObjectFlags |= RF_Transient; // We never want to save AI controllers into a map
|
|
AController* NewController = GetWorld()->SpawnActor<AController>(AEnemyAIController::StaticClass(), GetActorLocation(), GetActorRotation(), SpawnInfo);
|
|
if (NewController != NULL)
|
|
{
|
|
// if successful will result in setting this->Controller
|
|
// as part of possession mechanics
|
|
NewController->Possess(this);
|
|
}
|
|
enemycontroller = Cast<AEnemyAIController>(GetController());
|
|
if (enemycontroller && m_spawn)
|
|
{
|
|
if (m_spawn->SpawnLocation.Num() > 0)
|
|
{
|
|
PlayClimbingAnimation();
|
|
enemycontroller->SetBool(true, FName("ClimbKey"));
|
|
enemycontroller->SetVector(FVector(0, 0, 1), FName("ClimbDirection"));
|
|
enemycontroller->SetVector(m_spawn->GetActorLocation() + FVector(0, 0, 100), FName("ClimbLocation"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// RERROR("There is no valid controller on this enemy");
|
|
}
|
|
}
|
|
hasSpawned = false;
|
|
|
|
}
|
|
void AEnemyBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
|
{
|
|
Super::EndPlay(EndPlayReason);
|
|
general = nullptr;
|
|
if (m_spawn)
|
|
{
|
|
|
|
if (m_spawn->hasGeneral)
|
|
{
|
|
m_spawn->formationEnemies.Remove(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
void AEnemyBase::Tick(float deltaTime)
|
|
{
|
|
Super::Tick(deltaTime);
|
|
if (Role != ROLE_Authority)
|
|
{
|
|
return;
|
|
}
|
|
m_confusionTimer -= deltaTime;
|
|
if (!IsA(AGeneralEnemy::StaticClass()))
|
|
m_hasGeneral = hasGeneral;
|
|
if (!hasGeneral && enemycontroller && enemycontroller->IsA(AEnemyAIController::StaticClass()))
|
|
{
|
|
|
|
enemycontroller->SetBool(false, FName("EnableTree"));
|
|
}
|
|
|
|
if (IsValid(target))
|
|
{
|
|
if (hasGeneral)
|
|
{
|
|
m_informGeneralTimer -= deltaTime;
|
|
if (m_informGeneralTimer < 0.0f&&IsValid(general))
|
|
InformGeneral();
|
|
}
|
|
else
|
|
{
|
|
SwitchAgro();
|
|
}
|
|
}
|
|
else if(!hasGeneral)
|
|
{
|
|
FVector randpos = FMath::VRand();
|
|
randpos.Z = 0.0f;
|
|
float randomRange = FMath::FRandRange(m_spawn->aggroRadius / 4, m_spawn->aggroRadius);
|
|
|
|
randpos = randpos*randomRange;
|
|
|
|
MoveToPointSlow(randpos + m_spawn->GetActorLocation(), 50.0f);
|
|
}
|
|
}
|
|
void AEnemyBase::InformGeneral()
|
|
{
|
|
if (!IsValid(general) || !IsValid(target))
|
|
return;
|
|
if (FVector::DistSquared(m_spawn->GetActorLocation(), target->GetActorLocation()) > m_spawn->deaggroRadius*m_spawn->deaggroRadius)
|
|
return;
|
|
if( !IsValid(general->target))
|
|
{
|
|
general->target = m_tempTarget;
|
|
ChangeNPCAnimation((uint8)EMinionAnimState::MAS_Pointing);
|
|
//CHANGEANIMATION(EMinionAnimState::MAS_Pointing);
|
|
|
|
m_informGeneralTimer = informGeneralTime;
|
|
m_tempTarget = nullptr;
|
|
}
|
|
}
|
|
void AEnemyBase::SwitchAgro()
|
|
{
|
|
if (m_spawn->GetNearbyPlayers().Num() <= 1)
|
|
return;
|
|
float mostDamage =0.0f;
|
|
ANetworkCharacter* character = nullptr;
|
|
for (int i = 0; i < m_spawn->GetNearbyPlayers().Num(); i++)
|
|
{
|
|
if (m_spawn->GetNearbyPlayers()[i]->GetTotalDamage()>mostDamage)
|
|
{
|
|
mostDamage = m_spawn->GetNearbyPlayers()[i]->GetTotalDamage();
|
|
character = m_spawn->GetNearbyPlayers()[i];
|
|
}
|
|
}
|
|
if(IsValid(character))
|
|
this->target = character;
|
|
}
|
|
void AEnemyBase::ConfusionBehavior()
|
|
{
|
|
FVector randpos = FMath::VRand();
|
|
randpos.Z = 0.0f;
|
|
float randomRange = FMath::FRandRange(m_spawn->aggroRadius / 4, m_spawn->aggroRadius);
|
|
|
|
randpos = randpos*randomRange;
|
|
|
|
MoveToPointSlow(randpos + m_spawn->GetActorLocation(), 50.0f);
|
|
}
|
|
void AEnemyBase::ChargeBehavior()
|
|
{
|
|
|
|
}
|
|
void AEnemyBase::OffensiveBehavior()
|
|
{
|
|
|
|
|
|
}
|
|
void AEnemyBase::RangedBehavior()
|
|
{
|
|
}
|
|
void AEnemyBase::ResetConfusionTimer(float confusionTime)
|
|
{
|
|
m_confusionTimer = confusionTime;
|
|
}
|
|
float AEnemyBase::m_ReCalcChance(float chance)
|
|
{
|
|
return (1000 - (chance * 10));
|
|
}
|
|
int32 AEnemyBase::NativeDealDamage(class ANetworkCharacter* dealer, int32 damage, float armorPercentageIgnore, class UAbilityInfo* ability)
|
|
{
|
|
m_tempTarget = dealer;
|
|
m_informGeneralTimer = informGeneralTime;
|
|
return Super::NativeDealDamage(dealer, damage, armorPercentageIgnore, ability);
|
|
} |