221 lines
5.0 KiB
C++
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);
|
|
} |