haxis/Source/UnrealProject/Creatures/MiniBossCreature.cpp

113 lines
2.9 KiB
C++

// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "MiniBossCreature.h"
#include "NetworkPlayer.h"
#include "CreatureSpawn.h"
#include "AbilityInfo.h"
#include "Effect.h"
AMiniBossCreature::AMiniBossCreature()
{
PrimaryActorTick.bCanEverTick = true;
m_usesMana = false;
target = nullptr;
m_spawn = nullptr;
m_castTimer = 0;
keyDropped = PlayerKeyType::None;
}
void AMiniBossCreature::BeginPlay()
{
Super::BeginPlay();
if (Role != ROLE_Authority)
return;
// Select two random abilities to cast
if (IsValid(inheritAbilities) && IsValid(inheritAbilities.GetDefaultObject()))
{
TArray<class UAbilityInfo*>& bossAbilities = inheritAbilities.GetDefaultObject()->abilities;
if (bossAbilities.Num() > 1)
{
TArray<int32> abilityIndices;
for (int32 i = 0; i < bossAbilities.Num(); i++)
abilityIndices.Add(i);
while (m_bossAbilityPattern.Num() < 2)
{
const int32 index = FMath::Rand() % abilityIndices.Num();
const int32 ability = abilityIndices[index];
abilityIndices.RemoveAt(index);
m_bossAbilityPattern.Add(ability);
}
}
else if (bossAbilities.Num() == 1)
m_bossAbilityPattern.Add(0);
}
}
void AMiniBossCreature::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
if (Role != ROLE_Authority)
return;
// Drop a key
if (m_health <= 0)
{
ANetworkPlayer* const killedBy = Cast<ANetworkPlayer>(GetLastPlayerDamage());
if (IsValid(killedBy) && keyDropped != PlayerKeyType::None && IsValid(m_spawn) && !m_spawn->hasDroppedKey)
{
killedBy->AssignKey(keyDropped, m_spawn);
}
}
}
void AMiniBossCreature::Tick(float deltaTime)
{
Super::Tick(deltaTime);
if (Role != ROLE_Authority)
return;
// If the distance of the target to the spawn is greater than the aggro range of the spawner,
// then lose the target.
if (IsValid(target))
{
float targetDistSqr = FVector::DistSquared(target->GetActorLocation(), m_spawn->SpawnResetPosition());
float aggroSqr = m_spawn->deaggroRadius * m_spawn->deaggroRadius;
if (aggroSqr < targetDistSqr)
{
// Reset
target = nullptr;
m_castTimer = 0;
}
}
if (!IsValid(target))
return;
// Boss casting logic
MoveToPoint(target->GetActorLocation());
m_castTimer += deltaTime;
if (m_castTimer > 2.5f && IsValid(inheritAbilities) && IsValid(inheritAbilities.GetDefaultObject()))
{
TArray<class UAbilityInfo*>& bossAbilities = inheritAbilities.GetDefaultObject()->abilities;
if (bossAbilities.Num() > 0 && m_bossAbilityPattern.Num() > 0)
{
// Cast a random ability
UAbilityInfo* ability = bossAbilities[m_bossAbilityPattern[FMath::Rand() % m_bossAbilityPattern.Num()]];
if (IsValid(ability)&& ability->AICastRange*ability->AICastRange>FVector::DistSquared(GetActorLocation(),target->GetActorLocation()))
CastAbility(ability);
}
m_castTimer = 0;
}
}