haxis/Source/UnrealProject/Creatures/TouhouBoss.cpp

175 lines
4.0 KiB
C++

// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "TouhouBoss.h"
#include "CreatureSpawn.h"
#include "AbilityEventGroup.h"
#include "AbilityInfo.h"
#include "Modifier.h"
#include "NativeModifiers.h"
#include "DefaultGameMode.h"
#include "NetworkPlayer.h"
ATouhouBoss::ATouhouBoss()
{
PrimaryActorTick.bCanEverTick = true;
/* AudioComp = CreateDefaultSubobject<UAudioComponent>(TEXT("Boss Audio"));
if (AudioComp)
{
AudioComp->bAutoActivate = false; // with this true the sounds play at spawn (game starts)
}
*/
outOfCombatRegen = 25.0f;
secondPhasePercentage = 0.5f;
rotationSpeed = 1;
cooldown = 2.5f;
}
void ATouhouBoss::BeginPlay()
{
Super::BeginPlay();
if (Role != ROLE_Authority)
return;
m_engaged = false;
}
void ATouhouBoss::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
if (Role != ROLE_Authority)
return;
m_walkTimer = 0.0f;
// Drop a key
if (m_health <= 0)
{
ANetworkPlayer* const killedBy = Cast<ANetworkPlayer>(GetLastPlayerDamage());
if (IsValid(killedBy) && IsValid(m_spawn))
{
killedBy->AssignKey(PlayerKeyType::TreasureRoomKey, m_spawn);
onBossKilled.Broadcast(killedBy->GetTeam());
}
}
}
void ATouhouBoss::m_Engaged()
{
Super::m_Engaged();
m_engaged = true;
ModifierManager* mod = GetModifierManager();
if (mod != nullptr && m_regenModifier != nullptr)
{
// Stop regenerating health.
m_regenModifier->ForceDestroy();
m_regenModifier = nullptr;
SetShield(false);
// Plays a sound indicating that the boss was engaged and start playing the boss music.
//PlayEngageSound();
}
}
void ATouhouBoss::m_Disengaged()
{
Super::m_Disengaged();
ModifierManager* mod = GetModifierManager();
if (mod != nullptr && m_regenModifier == nullptr)
{
m_engaged = false;
// Start regenerating health.
m_regenModifier = mod->AddModifier(ARegenModifier::StaticClass(), 0);
Cast<ARegenModifier>(m_regenModifier)->regenPerTick = outOfCombatRegen;
// Remove invincibility if it's active.
if (m_invincibilityModifier)
{
m_invincibilityModifier->ForceDestroy();
m_invincibilityModifier = nullptr;
SetShield(false);
}
}
}
void ATouhouBoss::Tick(float deltaTime)
{
Super::Tick(deltaTime);
// Only execute boss code on the server.
if (Role != ROLE_Authority)
return;
// Calculate health as percentage for deciding which phase the boss should be in.
float healthPerc = (float)m_health / (float)m_maxHealth;
// 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)
{
target = nullptr;
}
}
//disengage
if (!IsValid(target) && m_regenModifier == nullptr)
{
m_Disengaged();
}
//engage
else if (target && !m_engaged)
{
m_Engaged();
}
if (m_engaged)
{
if (m_invincibilityModifier)
{
m_invincibilityModifier->ForceDestroy();
m_invincibilityModifier = nullptr;
SetShield(false);
}
if (!IsValid(target))
return;
WalkPhase(deltaTime);
}
}
void ATouhouBoss::WalkPhase(float deltaTime)
{
MoveToPoint(target->GetActorLocation());
m_walkTimer += deltaTime;
// After 2.5 seconds, cast a random ability.
if (m_walkTimer > cooldown && abilities.Num() > 0 && target)
{
// Cast a random ability
UAbilityInfo* ability = abilities[FMath::Rand() % abilities.Num()];
if(IsValid(ability))
CastAbility(ability);
m_walkTimer = 0;
}
}
void ATouhouBoss::m_SpawnModifiers()
{
/*ModifierManager* mod = GetModifierManager();
if (mod != nullptr)
{
//m_regenModifier = mod->AddModifier(ARegenModifier::StaticClass(), 0);
}*/
}
void ATouhouBoss::SetShield_Implementation(bool on)
{
FWARNING("shield implemtentation not set in ATouHouBoss");
return;
}