haxis/Source/UnrealProject/Creatures/EnemyBase.cpp

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);
}