113 lines
2.9 KiB
C++
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;
|
|
}
|
|
} |