haxis/Source/UnrealProject/Effects/Effect.cpp

167 lines
4.5 KiB
C++

// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "NetworkCharacter.h"
#include "Effect.h"
#include "DefaultGameInstance.h"
#include "Prefs.h"
AEffect::AEffect()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//RootComponent = m_particleComponent = CreateDefaultSubobject<UParticleSystemComponent>("PSys");
m_followActor = nullptr;
m_duration = 0.0f;
deactivateParticlesBefore = 0;
bReplicates = true;
}
void AEffect::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(AEffect, m_followActor, COND_InitialOnly);
DOREPLIFETIME_CONDITION(AEffect, m_duration, COND_InitialOnly);
}
void AEffect::BeginPlay()
{
m_particleSystems = GetComponentsByClass(UParticleSystemComponent::StaticClass());
m_rootParticleSystem = Cast<UParticleSystemComponent>(RootComponent);
m_rootAudio = Cast<UAudioComponent>(RootComponent);
// Bind root component finished actions
if(m_rootParticleSystem)
{
if(m_duration == 0.0f)
m_rootParticleSystem->bAutoDestroy = true;
float WarmupTimeRemember = m_rootParticleSystem->Template->WarmupTime;
m_rootParticleSystem->Template->WarmupTime = m_lifeTime;
m_rootParticleSystem->ActivateSystem();
m_rootParticleSystem->Template->WarmupTime = WarmupTimeRemember;
m_rootParticleSystem->OnSystemFinished.AddDynamic(this, &AEffect::OnRootParticleSystemFinished);
}
else if(m_rootAudio)
{
m_rootAudio->OnAudioFinished.AddDynamic(this, &AEffect::OnRootAudioFinished);
}
else
{
GWWARNING(L"Effect root is not a particles system or an audio component [" + GetName() + L"]");
}
Super::BeginPlay();
TArray<UActorComponent*> audioComponents = GetComponentsByClass(UAudioComponent::StaticClass());
float volume = Cast<UDefaultGameInstance>(GetGameInstance())->GetPrefs()->sfxVolume;
for (int32 i = 0; i < audioComponents.Num(); i++)
{
Cast<UAudioComponent>(audioComponents[i])->SetVolumeMultiplier(volume);
}
if (IsValid(m_followActor))
{
ANetworkCharacter* networkcharacter = Cast<ANetworkCharacter>(m_followActor);
if(networkcharacter)
networkcharacter->RegisterEffect(this);
}
}
void AEffect::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
if (IsValid(m_followActor))
{
ANetworkCharacter* networkcharacter = Cast<ANetworkCharacter>(m_followActor);
if (networkcharacter)
networkcharacter->UnRegisterEffect(this);
}
}
void AEffect::OnRootParticleSystemFinished(UParticleSystemComponent*)
{
if(m_duration == 0.0f) // Only auto-destroy if duration was not set
Destroy();
}
void AEffect::OnRootAudioFinished()
{
if(m_duration == 0.0f) // Only auto-destroy if duration was not set
Destroy();
}
AActor* AEffect::GetFollower() const
{
return m_followActor;
}
void AEffect::DeactivateParticles()
{
for(int32 i = 0; i < m_particleSystems.Num(); i++)
{
Cast<UParticleSystemComponent>(m_particleSystems[i])->DeactivateSystem();
}
deactivateParticlesBefore = 0.0f;
}
void AEffect::CalculatePosition_Implementation()
{
if (m_followActor)
{
SetActorLocation(m_followActor->GetActorLocation());
SetActorRotation(m_followActor->GetActorRotation());
}
}
void AEffect::BeginEffect_Implementation()
{
}
void AEffect::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
CalculatePosition();
m_lifeTime += DeltaTime;
if(m_duration > 0.0f) // Only use timer if duration was set
{
if(deactivateParticlesBefore > 0.0f)
{
if((m_lifeTime + deactivateParticlesBefore) >= m_duration)
{
DeactivateParticles();
}
}
if(m_lifeTime >= m_duration)
{
Destroy();
}
}
if (m_follow && !IsValid(m_followActor))
DeactivateParticles();
}
void AEffect::Init(float duration, AActor* followActor, bool clientSideOnly)
{
if(clientSideOnly)
bReplicates = false;
m_duration = duration;
m_followActor = followActor;
BeginEffect();
m_follow = IsValid(followActor);
}
void AEffect::End_Implementation()
{
//check(Role == ROLE_Authority);
if(deactivateParticlesBefore > 0.0f)
{
m_duration = deactivateParticlesBefore;
m_lifeTime = 0.0f;
DeactivateParticles();
check(m_duration > 0.0f);
}
else
{
Destroy();
}
}
void ATargetedEffect::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ATargetedEffect, target);
}