haxis/Source/UnrealProject/Abilities/AbilityTriggerBase.cpp

221 lines
5.0 KiB
C++

// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "NetworkCharacter.h"
#include "AbilityTriggerBase.h"
#include "BlueprintAbilityLibrary.h"
AAbilityTriggerBase::AAbilityTriggerBase()
{
PrimaryActorTick.bCanEverTick = true;
filter = EAbilityFilter::EnemyAll;
autoDestroy = true;
bReplicateMovement = true;
bReplicates = true;
duration = 1.0f;
ticksPerSecond = 0.0f;
m_lifeTime = 0.0f;
}
void AAbilityTriggerBase::BeginPlay()
{
if (Role == ROLE_Authority)
{
if (!character)
{
GWERROR(L"No owner assigned to trigger " + GetName());
this->SetActorEnableCollision(false);
Destroy();
}
if (ticksPerSecond > 0)
{
m_tickTime = 1.0f / ticksPerSecond;
}
else
{
m_tickTime = 0.0f;
}
}
//make sure the collision delegates are working
UShapeComponent* root = Cast<UShapeComponent>(RootComponent);
if (root != nullptr && !delegatesSet)
{
root->OnComponentBeginOverlap.AddDynamic(this, &AAbilityTriggerBase::OnOverlapBegin);
root->OnComponentEndOverlap.AddDynamic(this, &AAbilityTriggerBase::OnOverlapEnd);
delegatesSet = true;
}
else
FWARNING("rootComponent is not a UShapeComponent");
Super::BeginPlay();
if (Role == ROLE_Authority)
UpdateOverlaps();
}
void AAbilityTriggerBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
if (Role == ROLE_Authority)
{
while (m_actorsInside.Num()>0)
{
if (IsValid(m_actorsInside.GetData()[0]))
{
LeaveEvent(Cast<ANetworkCharacter>(m_actorsInside.GetData()[0]));
}
}
}
Super::EndPlay(EndPlayReason);
}
void AAbilityTriggerBase::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(AAbilityTriggerBase, duration, COND_InitialOnly);
}
void AAbilityTriggerBase::Tick(float DeltaTime)
{
m_lifeTime += DeltaTime;
Super::Tick(DeltaTime);
if(Role != ROLE_Authority || !IsValid(this))
return;
UpdateOverlaps();
if(autoDestroy && m_lifeTime >= duration)
{
Destroy();
return;
}
if(m_tickTime > 0)
{
m_tickTimer += DeltaTime;
while(m_tickTimer > m_tickTime)
{
m_tickTimer -= m_tickTime;
for(AActor* actorInside : m_actorsInside)
{
if (CollisionCheck(Cast<ANetworkCharacter>(actorInside)))
{
OnTriggerTick(Cast<ANetworkCharacter>(actorInside));
NativeOnLocalTriggerTick(Cast<ANetworkCharacter>(actorInside));
}
}
}
}
}
void AAbilityTriggerBase::OnOverlapBegin(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if(Role != ROLE_Authority)
return;
if(OtherActor == NULL)
{
FWPRINT(L"Error - wrong otherunit on OnOverlapBegin ");
return;
}
if(character == NULL)
{
FWPRINT(L"Error - m_character NULL on OnOverlapBegin ");
return;
}
ANetworkCharacter* otherUnit = Cast<ANetworkCharacter>(OtherActor);
if(!otherUnit->GetHitable())
return;
if(!ULib::CheckAbilityFilter(filter, character, otherUnit))
return;
if(hitOnce && m_CheckActorsHit(otherUnit))
return;
m_actorsInside.Add(OtherActor);
if (CollisionCheck(Cast<ANetworkCharacter>(OtherActor)))
{
HitEvent(otherUnit);
}
}
void AAbilityTriggerBase::OnOverlapEnd(class AActor * OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
if(Role == ROLE_Authority)
LeaveEvent(Cast<ANetworkCharacter>(OtherActor));
}
void AAbilityTriggerBase::HitEvent(class ANetworkCharacter* otherUnit)
{
if (hitOnce)
m_actorsHit.Add(otherUnit);
OnTriggerHit(otherUnit);
}
void AAbilityTriggerBase::LeaveEvent(class ANetworkCharacter* otherActor)
{
if (Role == ROLE_Authority)
{
for (auto it = (m_actorsInside.CreateIterator()); it; it++)
{
if (*it == otherActor)
{
m_actorsInside.Remove(otherActor);
break;
}
}
if (!ULib::CheckAbilityFilter(filter, character, otherActor))
return;
OnTriggerLeave(otherActor);
}
}
float AAbilityTriggerBase::GetLifeTime() const
{
return m_lifeTime;
}
float AAbilityTriggerBase::GetLifeTimeRate() const
{
return FMath::Clamp(m_lifeTime / duration, 0.0f, 1.0f);
}
bool AAbilityTriggerBase::m_CheckActorsHit(class ANetworkCharacter* otherUnit)
{
for (ANetworkCharacter* character : m_actorsHit)
{
if (character == otherUnit)
return true;
}
return false;
}
bool AAbilityTriggerBase::CollisionCheck(ANetworkCharacter* otheractor)
{
return IsValid(otheractor);
}
void AAbilityTriggerBase::OnTriggerHit_Implementation(ANetworkCharacter* actor)
{
}
void AAbilityTriggerBase::OnTriggerTick_Implementation(ANetworkCharacter* actor)
{
}
void AAbilityTriggerBase::OnTriggerLeave_Implementation(ANetworkCharacter* actor)
{
}
void AAbilityTriggerBase::OnLocalTriggerTick_Implementation(ANetworkCharacter* actor)
{
}
void AAbilityTriggerBase::NativeOnLocalTriggerTick_Implementation(ANetworkCharacter* actor)
{
OnLocalTriggerTick(actor);
}