vampires/Source/vampires/Projectile.cpp

139 lines
4.7 KiB
C++
Raw Normal View History

2025-02-05 23:12:03 +00:00
// Louis Hobbs | 2024-2025
2024-07-31 01:58:09 +01:00
#include "Projectile.h"
#include "EnemyCharacter.h"
2025-01-24 21:51:01 +00:00
#include "HealthComponent.h"
2025-07-22 22:57:43 +01:00
#include "NiagaraComponent.h"
#include "ObjectPoolManager.h"
#include "ProjectileDataAsset.h"
#include "Components/SphereComponent.h"
#include "GameFramework/GameModeBase.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "Interfaces/Pools.h"
#include "Kismet/GameplayStatics.h"
2024-07-31 14:19:50 +01:00
#include "Weapons/ProjectileWeapon.h"
2024-07-31 01:58:09 +01:00
// Sets default values
AProjectile::AProjectile()
{
SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("Sphere Component"));
2024-07-31 14:19:50 +01:00
SetRootComponent(SphereComponent);
2024-07-31 01:58:09 +01:00
SphereComponent->SetSphereRadius(50.0f);
2025-04-02 23:48:25 +01:00
SphereComponent->SetCollisionProfileName(TEXT("Weapon"));
ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("Projectile Movement"));
ProjectileMovement->ProjectileGravityScale = 0.0f;
ProjectileMovement->Friction = 0.0f;
ProjectileMovement->bIsSliding = true;
ProjectileMovement->InitialSpeed = 0;
ProjectileMovement->MaxSpeed = 0;
StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Static Mesh Component"));
StaticMeshComponent->AttachToComponent(SphereComponent, FAttachmentTransformRules::KeepRelativeTransform);
StaticMeshComponent->SetEnableGravity(false);
StaticMeshComponent->SetGenerateOverlapEvents(false);
StaticMeshComponent->SetCollisionProfileName(TEXT("NoCollision"));
2025-07-22 22:57:43 +01:00
NiagaraRibbonComponent = CreateDefaultSubobject<UNiagaraComponent>(TEXT("Niagara Ribbon Component"));
NiagaraRibbonComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
NiagaraRibbonComponent->DeactivateImmediate();
2024-07-31 01:58:09 +01:00
}
// Called when the game starts or when spawned
void AProjectile::BeginPlay()
{
Super::BeginPlay();
SphereComponent->OnComponentBeginOverlap.AddDynamic(this, &AProjectile::OnProjectileBeginOverlap);
2024-07-31 01:58:09 +01:00
}
void AProjectile::SetActorHiddenInGame(bool bNewHidden)
2024-07-31 01:58:09 +01:00
{
Super::SetActorHiddenInGame(bNewHidden);
if (bNewHidden)
{
ResetData_Implementation();
GetWorldTimerManager().ClearTimer(ProjectileLifetimeTimerHandle);
}
else
{
2025-07-29 22:06:42 +01:00
GetWorldTimerManager().SetTimer(ProjectileLifetimeTimerHandle, this, &AProjectile::ReturnProjectileToPool,
ProjectileLifespan, true);
}
}
2025-07-25 23:45:12 +01:00
void AProjectile::SetTargetDirection_Implementation(FVector Direction)
{
SetActorLocation(UGameplayStatics::GetPlayerController(GetWorld(), 0)->GetCharacter()->GetActorLocation());
SetActorRotation(FRotator(0, 0, 0));
2025-07-25 23:45:12 +01:00
TargetDirection = Direction;
ProjectileMovement->SetVelocityInLocalSpace(TargetDirection * ProjectileSpeed);
2024-07-31 01:58:09 +01:00
}
2025-07-25 23:45:12 +01:00
void AProjectile::LoadDataFromDataAsset_Implementation(UProjectileDataAsset* ProjectileDataAsset)
{
2025-07-25 23:45:12 +01:00
ProjectileSpeed = ProjectileDataAsset->ProjectileSpeed;
StaticMeshComponent->SetStaticMesh(ProjectileDataAsset->StaticMesh);
ProjectileSpeed = ProjectileDataAsset->ProjectileSpeed;
ProjectileMovement->InitialSpeed = ProjectileSpeed;
ProjectileMovement->MaxSpeed = ProjectileSpeed;
2025-07-25 23:45:12 +01:00
RemainingDamageableEnemies = ProjectileDataAsset->DamageableEnemies;
NiagaraRibbonComponent->SetAsset(ProjectileDataAsset->NiagaraRibbonSystem);
2025-07-22 22:57:43 +01:00
NiagaraRibbonComponent->ActivateSystem();
}
void AProjectile::ResetData_Implementation()
{
ProjectileSpeed = NULL;
StaticMeshComponent->SetStaticMesh(nullptr);
2025-07-25 23:45:12 +01:00
RemainingDamageableEnemies = 1;
2025-07-22 22:57:43 +01:00
NiagaraRibbonComponent->DeactivateImmediate();
NiagaraRibbonComponent->SetAsset(nullptr);
}
void AProjectile::OnProjectileBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep,
const FHitResult& SweepResult)
{
if (AEnemyCharacter* Enemy = Cast<AEnemyCharacter>(OtherActor))
{
UHealthComponent* EnemyHealthComponent = Enemy->GetHealthComponent();
if (!EnemyHealthComponent->GetIsDead())
{
2025-07-29 22:06:42 +01:00
AController* OwnerController = nullptr;
if (AVampireCharacter* Character = Cast<AVampireCharacter>(GetOwner()))
{
2025-07-29 22:06:42 +01:00
OwnerController = Character->GetController();
}
2025-07-29 22:06:42 +01:00
AProjectileWeapon* OwnerWeapon = Cast<AProjectileWeapon>(GetOwner());
EnemyHealthComponent->TakeDamage(Enemy, OwnerWeapon->GetDamage(), nullptr, OwnerController, this);
2025-07-25 23:45:12 +01:00
RemainingDamageableEnemies--;
2025-07-25 23:45:12 +01:00
if (RemainingDamageableEnemies == 0)
{
ReturnProjectileToPool();
}
}
}
}
void AProjectile::ReturnProjectileToPool()
{
2025-07-29 22:06:42 +01:00
AGameModeBase* Gamemode = UGameplayStatics::GetGameMode(GetWorld());
2025-07-29 22:06:42 +01:00
if (UKismetSystemLibrary::DoesImplementInterface(Gamemode, UPools::StaticClass()))
{
2025-07-29 22:06:42 +01:00
if (AObjectPoolManager* ObjectPoolManager =
IPools::Execute_GetProjectileObjectPoolManager(Gamemode))
{
2025-07-29 22:06:42 +01:00
ObjectPoolManager->ReturnObject(this);
}
}
}