haxis/Source/UnrealProject/Creatures/IllusionCharacter.cpp

189 lines
4.6 KiB
C++

// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "Creatures/NetworkCharacter.h"
#include "Creatures/NetworkPlayer.h"
#include "IllusionCharacter.h"
#include "BlueprintAbilityLibrary.h"
#include "AIController.h"
#include "DealDamageProxy.h"
#include "AbilityInfo.h"
#include "NativeModifiers.h"
AIllusionCharacter::AIllusionCharacter()
{
PrimaryActorTick.bCanEverTick = true;
aggroRange = 400;
acceptenceDistance = 200;
lifeTime = 30;
}
void AIllusionCharacter::BeginPlay()
{
Super::BeginPlay();
if (Role != ROLE_Authority)
{
return;
}
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>(AAIController::StaticClass(), GetActorLocation(), GetActorRotation(), SpawnInfo);
if (NewController != NULL)
{
// if successful will result in setting this->Controller
// as part of possession mechanics
NewController->Possess(this);
}
if (IsValid(illOwner))
{
m_maxHealth = illOwner->GetMaxHealth();
m_health = illOwner->GetHealth();
}
else
{
FERROR("NO ILLOWNER IN ILLUSIONCHARACTER");
}
if (illOwner)
{
abilities.Add(illOwner->abilities[0]);
m_attackSpeed =illOwner->m_attackSpeed;
}
m_isdying = false;
}
void AIllusionCharacter::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
}
void AIllusionCharacter::Tick(float deltaTime)
{
Super::Tick(deltaTime);
if (Role != ROLE_Authority)
{
return;
}
lifeTime -= deltaTime;
if (lifeTime <= 0)
{
if(!m_isdying)
Kill();
return;
}
UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
if (!NavSys)
{
RERROR("there is no nav sys");
}
if (!GetController())
{
RERROR("there is no controller");
}
if (!IsValid(illOwner))
{
Kill();
return;
}
if (!IsValid(target))
{
attacking = false;
//targetList = ULib::GetCharacterOverlaps();
target = GetClosestTarget();
if (FVector::DistSquared(illOwner->GetActorLocation(), GetActorLocation()) > acceptenceDistance*acceptenceDistance)
{
MoveTo(illOwner->GetActorLocation());
FPRINT("moving to the illOwner");
}
else MoveTo(GetActorLocation());
return;
}
if (!attacking)
{
attacking = IsAttacking(1.0f);
return;
}
Attack();
}
void AIllusionCharacter::Attack()
{
int randdistance =0;
randdistance += ((int)abilities[0]->AICastRange / 2);
if (FVector::Dist(GetActorLocation(), target->GetActorLocation()) < randdistance)
{
MoveTo(GetActorLocation());
SetActorRotation(FVector(target->GetActorLocation() - GetActorLocation()).Rotation());
}
else MoveTo(target->GetActorLocation());
for (int i = 0; i < abilities.Num(); i++)
{
if ((abilities[i])&&FVector::DistSquared(GetActorLocation(),target->GetActorLocation())<abilities[i]->AICastRange*abilities[i]->AICastRange)
{
CastAbility(abilities[i]);
}
}
}
ANetworkCharacter* AIllusionCharacter::GetClosestTarget()
{
ANetworkCharacter* returnTarget = nullptr;
float distance = 1e34;
for (ANetworkCharacter* character : targetList)
{
if(!IsValid(character)||character==this || character->GetTeam()==GetTeam())
continue;
float tempdistance = FVector::DistSquared(character->GetActorLocation(), GetActorLocation());
if (distance > tempdistance)
{
distance = tempdistance;
returnTarget = character;
}
}
return returnTarget;
}
void AIllusionCharacter::MoveTo(FVector Location)
{
UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
if (IsPendingKill() || IsPendingKillPending())
return;
if (!IsStunned())
{
NavSys->SimpleMoveToLocation(this->Controller, Location);
}
else
{
NavSys->SimpleMoveToLocation(this->Controller, GetActorLocation());
}
}
bool AIllusionCharacter::IsAttacking(float changePercentage)
{
int num = rand() % 100;
if (num > (int)changePercentage)
{
return false;
}
return true;
}
void AIllusionCharacter::Kill()
{
if (IsPendingKill() || IsPendingKillPending())
{
RERROR("the character is pending kill");
return;
}
ADOTModifier* deathMod = GetWorld()->SpawnActor<ADOTModifier>();
deathMod->damagePerTick = 500;
deathMod->lifeTime = 0;
deathMod->target = this;
deathMod->character = this;
deathMod->abilityInfo = abilityInfo;
m_modifierManager->AddModifier(deathMod);
m_isdying = true;
//m_health = 0;
// m_shouldBeDestroyed = true;
}