175 lines
4.1 KiB
C++
175 lines
4.1 KiB
C++
// Project Lab - NHTV Igad
|
|
|
|
#include "UnrealProject.h"
|
|
#include "NetworkCharacter.h"
|
|
|
|
#include "ProjectileBase.h"
|
|
#include "BlueprintAbilityLibrary.h"
|
|
|
|
#include "AbilityTriggerBase.h"
|
|
|
|
AProjectileBase::AProjectileBase()
|
|
{
|
|
m_finishTimer = 0.0f;
|
|
m_fixedTimer = 0.0f;
|
|
maxDistance = 1000.0f;
|
|
distanceTraveled = 0.0f;
|
|
keepAliveAfterFinish = 1.0f;
|
|
filter = EAbilityFilter::EnemyAll;
|
|
m_finished = false;
|
|
|
|
//server client replication
|
|
bReplicateMovement = true;
|
|
bReplicates = true;
|
|
bAlwaysRelevant = true;
|
|
PrimaryActorTick.bCanEverTick = true;
|
|
}
|
|
|
|
void AProjectileBase::BeginPlay()
|
|
{
|
|
// Get collider component
|
|
collider = Cast<UPrimitiveComponent>(GetRootComponent());
|
|
if(!collider)
|
|
{
|
|
GWERROR(L"Projectile does not have a collider root!");
|
|
Destroy();
|
|
return;
|
|
}
|
|
|
|
|
|
if(Role != ROLE_Authority)
|
|
{
|
|
collider->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
|
}
|
|
else
|
|
{
|
|
collider->OnComponentHit.AddDynamic(this, &AProjectileBase::m_OnHit);
|
|
collider->OnComponentBeginOverlap.AddDynamic(this, &AProjectileBase::m_OnOverlapBegin);
|
|
// collider->SetCollisionProfileName("Projectiles");
|
|
}
|
|
Super::BeginPlay();
|
|
}
|
|
|
|
void AProjectileBase::NativeFixedProjectileTick(float DeltaTime)
|
|
{
|
|
FixedProjectileTick(DeltaTime);
|
|
}
|
|
|
|
//call this in inherited classes, will call move
|
|
void AProjectileBase::Tick(float DeltaTime)
|
|
{
|
|
Super::Tick(DeltaTime);
|
|
|
|
// Fixed timestep for projectiles
|
|
m_fixedTimer += DeltaTime;
|
|
FVector startPos = GetActorLocation();
|
|
const float delta = 1.0f / 60.0f;
|
|
while(m_fixedTimer >= delta)
|
|
{
|
|
NativeFixedProjectileTick(delta);
|
|
if (autoMove)
|
|
{
|
|
NativeMove(DeltaTime);
|
|
|
|
FVector newLocation = GetActorLocation();
|
|
FVector movedVector = newLocation - startPos;
|
|
startPos = newLocation;
|
|
|
|
distanceTraveled += movedVector.Size();
|
|
}
|
|
if (distanceTraveled > maxDistance)
|
|
{
|
|
Finish();
|
|
break;
|
|
}
|
|
m_fixedTimer -= delta;
|
|
}
|
|
|
|
if(m_finished && autoDestroy)
|
|
{
|
|
if((m_finishTimer -= DeltaTime) <= 0.0f)
|
|
{
|
|
Destroy();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void AProjectileBase::m_OnOverlapBegin(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
|
|
{
|
|
ANetworkCharacter* netChar = Cast<ANetworkCharacter>(OtherActor);
|
|
if(netChar && ULib::CheckAbilityFilter(filter, character, netChar))
|
|
{
|
|
OnProjectileHit(netChar);
|
|
}
|
|
}
|
|
void AProjectileBase::m_OnHit(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
|
|
{
|
|
Finish();
|
|
}
|
|
|
|
void AProjectileBase::Finish_Implementation()
|
|
{
|
|
if(!m_finished)
|
|
{
|
|
if(Role == ROLE_Authority)
|
|
{
|
|
NativeServerOnFinish();
|
|
}
|
|
NativeOnProjectileFinished();
|
|
if(collider)
|
|
collider->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
|
m_finishTimer = keepAliveAfterFinish;
|
|
m_finished = true;
|
|
}
|
|
}
|
|
|
|
void AProjectileBase::FixedProjectileTick_Implementation(float DeltaTime)
|
|
{
|
|
}
|
|
void AProjectileBase::OnProjectileHit_Implementation(ANetworkCharacter* character)
|
|
{
|
|
NativeOnProjectileHit(character);
|
|
}
|
|
|
|
void AProjectileBase::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
|
{
|
|
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
|
|
|
DOREPLIFETIME_CONDITION(AProjectileBase, speed, COND_InitialOnly);
|
|
DOREPLIFETIME_CONDITION(AProjectileBase, filter, COND_InitialOnly);
|
|
DOREPLIFETIME_CONDITION(AProjectileBase, maxDistance, COND_InitialOnly);
|
|
DOREPLIFETIME_CONDITION(AProjectileBase, autoMove, COND_InitialOnly);
|
|
DOREPLIFETIME_CONDITION(AProjectileBase, autoDestroy, COND_InitialOnly);
|
|
}
|
|
|
|
void AProjectileBase::Move(float DeltaTime)
|
|
{
|
|
NativeMove(DeltaTime);
|
|
}
|
|
|
|
void AProjectileBase::NativeMove(float DeltaTime)
|
|
{
|
|
//moves with sweep to get collision
|
|
float distance = speed * DeltaTime;
|
|
AddActorWorldOffset(GetActorForwardVector() * distance,true);
|
|
}
|
|
|
|
void AProjectileBase::OnProjectileFinished_Implementation()
|
|
{
|
|
|
|
}
|
|
void AProjectileBase::NativeOnProjectileFinished()
|
|
{
|
|
OnProjectileFinished();
|
|
}
|
|
|
|
void AProjectileBase::NativeOnProjectileHit(ANetworkCharacter* hitCharacter)
|
|
{
|
|
}
|
|
|
|
void AProjectileBase::NativeServerOnFinish()
|
|
{
|
|
ServerOnFinish();
|
|
}
|