diff --git a/Content/Weapons/MagicWand/BP_MagicWandProjectile.uasset b/Content/Weapons/MagicWand/BP_MagicWandProjectile.uasset new file mode 100644 index 0000000..5ecb3f1 --- /dev/null +++ b/Content/Weapons/MagicWand/BP_MagicWandProjectile.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8bf0a4b64dd9e17e816713784edd2619bb30f3bd8ba2baa25c59591a002dba2f +size 30788 diff --git a/Content/Weapons/MagicWand/BP_MagicWandWeapon.uasset b/Content/Weapons/MagicWand/BP_MagicWandWeapon.uasset new file mode 100644 index 0000000..8647639 --- /dev/null +++ b/Content/Weapons/MagicWand/BP_MagicWandWeapon.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2aa1d6f03f840554b2e7e72789ff417ded652ccf08b8ea188ab965e2b2161f4e +size 24084 diff --git a/Source/vampires/Projectile.cpp b/Source/vampires/Projectile.cpp new file mode 100644 index 0000000..1a1bc56 --- /dev/null +++ b/Source/vampires/Projectile.cpp @@ -0,0 +1,34 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "Projectile.h" + +#include "EnemyCharacter.h" +#include "Weapons/MagicWandWeapon.h" + +// Sets default values +AProjectile::AProjectile() +{ + // 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; + + SphereComponent = CreateDefaultSubobject(TEXT("Sphere Component")); + SphereComponent->SetupAttachment(RootComponent); + SphereComponent->SetSphereRadius(50.0f); +} + +// Called when the game starts or when spawned +void AProjectile::BeginPlay() +{ + Super::BeginPlay(); + AMagicWandWeapon* OwnerWeapon = Cast(GetOwner()); + SphereComponent->OnComponentBeginOverlap.AddDynamic(OwnerWeapon, &AMagicWandWeapon::OnProjectileBeginOverlap); +} + +// Called every frame +void AProjectile::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); + SetActorLocation(GetActorLocation() + (TargetDirection * ProjectileSpeed)); +} + diff --git a/Source/vampires/Projectile.h b/Source/vampires/Projectile.h new file mode 100644 index 0000000..9427d1f --- /dev/null +++ b/Source/vampires/Projectile.h @@ -0,0 +1,35 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Components/SphereComponent.h" +#include "GameFramework/Actor.h" +#include "Projectile.generated.h" + +UCLASS() +class VAMPIRES_API AProjectile : public AActor +{ + GENERATED_BODY() + +public: + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) + USphereComponent* SphereComponent = nullptr; + + FVector TargetDirection = FVector::ZeroVector; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float ProjectileSpeed = 1.0f; + +public: + // Sets default values for this actor's properties + AProjectile(); + +protected: + // Called when the game starts or when spawned + virtual void BeginPlay() override; + +public: + // Called every frame + virtual void Tick(float DeltaTime) override; +}; diff --git a/Source/vampires/Weapon.cpp b/Source/vampires/Weapon.cpp index 9302413..5c10f06 100644 --- a/Source/vampires/Weapon.cpp +++ b/Source/vampires/Weapon.cpp @@ -16,6 +16,8 @@ AWeapon::AWeapon() void AWeapon::BeginPlay() { Super::BeginPlay(); + + TArray example; GetWorldTimerManager().SetTimer(WeaponTimerHandle, this, &AWeapon::FireWeaponAction, WeaponCooldown, true); UEXPComponent* expcomponent = GetOwner()->GetComponentByClass(); diff --git a/Source/vampires/Weapon.h b/Source/vampires/Weapon.h index 43e2a2c..58c8780 100644 --- a/Source/vampires/Weapon.h +++ b/Source/vampires/Weapon.h @@ -12,10 +12,10 @@ class VAMPIRES_API AWeapon : public AActor GENERATED_BODY() public: - UPROPERTY(BlueprintReadWrite) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Properties") float WeaponCooldown = 1.0f; - UPROPERTY(BlueprintReadWrite) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Properties") float Damage; private: diff --git a/Source/vampires/Weapons/MagicWandWeapon.cpp b/Source/vampires/Weapons/MagicWandWeapon.cpp new file mode 100644 index 0000000..6a1d6bb --- /dev/null +++ b/Source/vampires/Weapons/MagicWandWeapon.cpp @@ -0,0 +1,91 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "MagicWandWeapon.h" + +#include "Kismet/GameplayStatics.h" +#include "Kismet/KismetMathLibrary.h" +#include "vampires/EnemyCharacter.h" + +AMagicWandWeapon::AMagicWandWeapon() +{ + SphereComponent = CreateDefaultSubobject(TEXT("Sphere Component")); + SphereComponent->SetupAttachment(RootComponent); + SphereComponent->SetSphereRadius(1000.0f); +} + +void AMagicWandWeapon::BeginPlay() +{ + Super::BeginPlay(); + SphereComponent->OnComponentBeginOverlap.AddDynamic(this, &AMagicWandWeapon::OnWeaponBeginOverlap); + SphereComponent->OnComponentEndOverlap.AddDynamic(this, &AMagicWandWeapon::OnWeaponEndOverlap); +} + +void AMagicWandWeapon::FireWeaponAction_Implementation() +{ + Super::FireWeaponAction_Implementation(); + + if (IsValid(ProjectileTemplate)) + { + float distance = 0.0f; + AActor* nearestActor = UGameplayStatics::FindNearestActor(GetActorLocation(), OverlappedEnemies, distance); + + if (nearestActor) + { + FActorSpawnParameters actorSpawnParameters; + actorSpawnParameters.Owner = this; + actorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; + actorSpawnParameters.TransformScaleMethod = ESpawnActorScaleMethod::MultiplyWithRoot; + + AProjectile* projectile = GetWorld()->SpawnActor(ProjectileTemplate, GetTransform(), + actorSpawnParameters); + FVector direction = UKismetMathLibrary::GetDirectionUnitVector( + GetActorLocation(), nearestActor->GetActorLocation()); + direction.Z = 0.0; + direction.Normalize(); + projectile->TargetDirection = direction; + } + } +} + +void AMagicWandWeapon::OnWeaponBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, + UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, + const FHitResult& SweepResult) +{ + if (AEnemyCharacter* Enemy = Cast(OtherActor)) + { + OverlappedEnemies.Add(Enemy); + } +} + +void AMagicWandWeapon::OnWeaponEndOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, + UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) +{ + if (AEnemyCharacter* Enemy = Cast(OtherActor)) + { + OverlappedEnemies.Remove(Enemy); + } +} + +void AMagicWandWeapon::OnProjectileBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, + UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, + const FHitResult& SweepResult) +{ + if (AEnemyCharacter* Enemy = Cast(OtherActor)) + { + UHealthComponent* EnemyHealthComponent = Enemy->GetHealthComponent(); + + if (!EnemyHealthComponent->GetIsDead()) + { + AController* ownerController = nullptr; + if (AVampireCharacter* character = Cast(GetOwner())) + { + ownerController = character->GetController(); + } + + EnemyHealthComponent->TakeDamage(Enemy, Damage, nullptr, ownerController, this); + + OverlappedComponent->GetAttachmentRootActor()->Destroy(); + } + } +} diff --git a/Source/vampires/Weapons/MagicWandWeapon.h b/Source/vampires/Weapons/MagicWandWeapon.h new file mode 100644 index 0000000..03845e5 --- /dev/null +++ b/Source/vampires/Weapons/MagicWandWeapon.h @@ -0,0 +1,50 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "../Weapon.h" +#include "Components/SphereComponent.h" +#include "vampires/Projectile.h" +#include "MagicWandWeapon.generated.h" + +/** + * + */ +UCLASS() +class VAMPIRES_API AMagicWandWeapon : public AWeapon +{ + GENERATED_BODY() + +public: + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) + USphereComponent* SphereComponent = nullptr; + + UPROPERTY(EditAnywhere, Category = "Weapon Properties") + TSubclassOf ProjectileTemplate = nullptr; + +private: + TArray OverlappedEnemies = TArray(); + +public: + AMagicWandWeapon(); + +protected: + virtual void BeginPlay() override; + +public: + virtual void FireWeaponAction_Implementation() override; + + UFUNCTION() + void OnWeaponBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, + UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, + const FHitResult& SweepResult); + + UFUNCTION() + void OnWeaponEndOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, + int32 OtherBodyIndex); + + UFUNCTION() + void OnProjectileBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, + UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult); +};