haxis/Source/UnrealProject/Creatures/GeneralEnemy.cpp

237 lines
7.4 KiB
C++

// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "GeneralEnemy.h"
#include "SpawnerBase.h"
#include "BehaviorTree/EnemyAIController.h"
#include "NetworkPlayer.h"
#include "OffensiveEnemy.h"
#include "MinionAnimInstance.h"
AGeneralEnemy::AGeneralEnemy()
{
PrimaryActorTick.bCanEverTick = true;
}
void AGeneralEnemy::BeginPlay()
{
Super::BeginPlay();
if (Role != ROLE_Authority)
return;
if (m_spawn)
{
m_spawn->hasGeneral = true;
FVector addVector;
for (int i = 0; i < 4; i++)
{
addVector = m_spawn->GetActorForwardVector().RotateAngleAxis(i * 90, FVector::UpVector);
patrolLocations.Add(addVector);
}
}
if (distance == 0)
{
distance = 100.0f;
}
/* for (int i = 0; i < formationEnemies.Num(); i++)
{
formationEnemies[i]->general = this;
}*/
}
void AGeneralEnemy::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
if (Role != ROLE_Authority)
return;
for (int i = 0; i < formationEnemies.Num(); i++)
{
formationEnemies[i]->ResetConfusionTimer(3.0f);
formationEnemies[i]->general = nullptr;
}
if (m_spawn != nullptr)
m_spawn->hasGeneral = false;
//formationEnemies.Empty();
}
void AGeneralEnemy::Tick(float deltaTime)
{
Super::Tick(deltaTime);
if (Role != ROLE_Authority)
return;
if (!IsValid(m_spawn))
{
RERROR("There is no spawn for the general enemy");
return;
}
for (int i = 0; i < formationEnemies.Num(); i++)
{
if (IsValid(formationEnemies[i]->general))
continue;
formationEnemies[i]->general = this;
}
if (IsValid(target))
{
FVector2D locationVec = FVector2D(target->GetActorLocation()) - FVector2D(GetActorLocation());
locationVec.Normalize();
if (FVector::DistSquaredXY(GetActorLocation(), target->GetActorLocation()) > m_spawn->formationDistance* m_spawn->formationDistance)
{
MoveToPoint((target->GetActorLocation()));// +(FVector(locationVec, 0))* m_spawn->formationDistance));
DefaultFormation();
}
else
{
GetCharacterMovement()->Velocity = FVector::ZeroVector;
MoveToPoint(GetActorLocation());
GetCharacterMovement()->Velocity = FVector::ZeroVector;
SetActorRotation(FVector(target->GetActorLocation() - GetActorLocation()).Rotation());
ChargeFormation();
}
}
else
{
IdleFormation(deltaTime);
}
}
void AGeneralEnemy::SingleTargetFormation(int enemyNum)
{
if ((formationEnemies[enemyNum]->enemycontroller)->IsA(AEnemyAIController::StaticClass()))
{
formationEnemies[enemyNum]->target = target;
formationEnemies[enemyNum]->enemycontroller->SetBool(true, FName("EnableTree"));
formationEnemies[enemyNum]->SetActorRotation(FVector(target->GetActorLocation() - formationEnemies[enemyNum]->GetActorLocation()).Rotation());
if (count < 3)
{
formationEnemies[enemyNum]->enemycontroller->SetBool(false, FName("GuardKey"));
formationEnemies[enemyNum]->enemycontroller->SetVector(target->GetActorLocation() + target->GetActorForwardVector() * 200, FName("FrontLoc"));
formationEnemies[enemyNum]->enemycontroller->SetVector(target->GetActorLocation() + target->GetActorForwardVector() * -200, FName("BacktLoc"));
formationEnemies[enemyNum]->enemycontroller->SetVector(target->GetActorLocation() + target->GetActorRightVector() *-200, FName("LeftLoc"));
formationEnemies[enemyNum]->enemycontroller->SetVector(target->GetActorLocation() + target->GetActorRightVector() * 200, FName("RightLoc"));
}
else
{
formationEnemies[enemyNum]->enemycontroller->SetBool(true, FName("GuardKey"));
formationEnemies[enemyNum]->enemycontroller->SetVector(GetActorLocation() + GetActorForwardVector() * 100, FName("HomeLocation"));
}
count++;
}
}
void AGeneralEnemy::ChargeFormation()
{
if (!IsValid(target))
return;
count = 0;
TArray<ANetworkPlayer*> targetArray = m_spawn->GetNearbyPlayers();
if (targetArray.Num() == 0)
return;
for (int i = 0; i < formationEnemies.Num(); i++)
{
if (targetArray.Num() == 1)
{
SingleTargetFormation(i);
continue;
}
if (Cast<AOffensiveEnemy>(formationEnemies[i]))
{
formationEnemies[i]->target = m_spawn->GetClosestPlayer();
formationEnemies[i]->MoveToPoint(target->GetActorLocation());
}
else
{
ANetworkPlayer* newTarget = nullptr;
for (int j = 0; j < targetArray.Num(); j++)
{
if(targetArray[j]==m_spawn->GetClosestPlayer())
continue;
newTarget = targetArray[j];
continue;
}
formationEnemies[i]->target = newTarget;
}
}
}
void AGeneralEnemy::DefaultFormation()
{
FVector rotatedFormation;
for (int i = 0; i < formationEnemies.Num(); i++)
{
if (!IsValid(formationEnemies[i]) || !IsValid(m_spawn) || (m_spawn->formationPoints.Num() + 1) < formationEnemies.Num())
{
continue;
}
formationEnemies[i]->target = target;
rotatedFormation = GetActorRotation().RotateVector(FVector(m_spawn->formationPoints[i + 1].X - m_spawn->formationPoints[0].X, m_spawn->formationPoints[i + 1].Y - m_spawn->formationPoints[0].Y, 0));
formationEnemies[i]->MoveToPoint(GetActorLocation() + rotatedFormation);
formationEnemies[i]->SetActorRotation(FRotator(0, m_spawn->formationRotation[i + 1], 0) + (GetActorRotation()));
formationEnemies[i]->enemycontroller->SetBool(false, FName("EnableTree"));
formationEnemies[i]->enemycontroller->SetVector(formationEnemies[i]->GetActorLocation(), FName("HomeLocation"));
}
}
int AGeneralEnemy::NativeDealDamage(class ANetworkCharacter* dealer, int32 damage, float armorPercentageIgnore, class UAbilityInfo* ability)
{
//CHANGEANIMATION(EMinionAnimState::MAS_Pointing);
ChangeNPCAnimation((uint8)EMinionAnimState::MAS_Pointing);
return Super::NativeDealDamage(dealer, damage, armorPercentageIgnore, ability);
}
void AGeneralEnemy::NativeOnKilled(class ANetworkCharacter* killer, class UAbilityInfo* ability)
{
Super::NativeOnKilled(killer, ability);
if (Role != ROLE_Authority)
return;
if (m_spawn &&m_spawn->possesable)
{
int32 team = killer->GetTeam();
m_spawn->CaptureCamp(team);
}
}
void AGeneralEnemy::IdleFormation(float deltaTime)
{
// Move to a random point near the spawn point;
//controll enemies in the formation
int counter = 0;
for (int i = 0; i < formationEnemies.Num(); i++)
{
if (!IsValid(formationEnemies[i]) || !IsValid(m_spawn) || (m_spawn->formationPoints.Num() + 1) < formationEnemies.Num())
{
continue;
}
if (!formationEnemies[i]->m_tempTarget)
{
if (Cast<AOffensiveEnemy>(formationEnemies[i])&&counter<4)
{
formationEnemies[i]->PatrolBetweenLocations (patrolLocations[counter].RotateAngleAxis( 90, FVector::UpVector)*500+ patrolLocations[counter]* 500 + m_spawn->GetActorLocation(), patrolLocations[counter].RotateAngleAxis( 270, FVector::UpVector) * 500 + patrolLocations[counter] * 500 + m_spawn->GetActorLocation(), deltaTime);
counter++;
continue;
}
formationEnemies[i]->MoveToPoint(FVector(m_spawn->formationPoints[i + 1],0)+m_spawn->GetActorLocation());
//formationEnemies[i]->MoveToPointSlow(randpos + m_spawn->GetActorLocation(), 50.0f);
}
else
{
if(formationEnemies[i]->IsA(AOffensiveEnemy::StaticClass()))
Cast<AOffensiveEnemy>(formationEnemies[i])->BasicBehavior();
if(formationEnemies[i]->IsA(ARangedEnemy::StaticClass()))
Cast<ARangedEnemy>(formationEnemies[i])->BasicBehavior();
}
formationEnemies[i]->target = nullptr;
}
}