// 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("PSys"); m_followActor = nullptr; m_duration = 0.0f; deactivateParticlesBefore = 0; bReplicates = true; } void AEffect::GetLifetimeReplicatedProps(TArray& 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(RootComponent); m_rootAudio = Cast(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 audioComponents = GetComponentsByClass(UAudioComponent::StaticClass()); float volume = Cast(GetGameInstance())->GetPrefs()->sfxVolume; for (int32 i = 0; i < audioComponents.Num(); i++) { Cast(audioComponents[i])->SetVolumeMultiplier(volume); } if (IsValid(m_followActor)) { ANetworkCharacter* networkcharacter = Cast(m_followActor); if(networkcharacter) networkcharacter->RegisterEffect(this); } } void AEffect::EndPlay(const EEndPlayReason::Type EndPlayReason) { if (IsValid(m_followActor)) { ANetworkCharacter* networkcharacter = Cast(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(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& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(ATargetedEffect, target); }