Minor refactor to base weapon class

This commit is contained in:
baz 2025-07-25 23:03:58 +01:00
parent 274ae9fc27
commit e0dd825be9
12 changed files with 92 additions and 83 deletions

View File

@ -110,7 +110,7 @@ void AProjectile::OnProjectileBeginOverlap(UPrimitiveComponent* OverlappedCompon
}
AProjectileWeapon* ownerWeapon = Cast<AProjectileWeapon>(GetOwner());
EnemyHealthComponent->TakeDamage(Enemy, ownerWeapon->Damage, nullptr, ownerController, this);
EnemyHealthComponent->TakeDamage(Enemy, ownerWeapon->GetDamage(), nullptr, ownerController, this);
RemainingDamagableEnemies--;

View File

@ -12,7 +12,7 @@
// Sets default values
AWeapon::AWeapon()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
BoxComponent = CreateDefaultSubobject<UBoxComponent>(TEXT("Box Component"));
@ -30,9 +30,9 @@ void AWeapon::BeginPlay()
BoxComponent->OnComponentEndOverlap.AddDynamic(this, &AWeapon::OnWeaponEndOverlap);
FViewport::ViewportResizedEvent.AddUObject(this, &AWeapon::ResizeBoxComponent);
ResizeBoxComponent(GEngine->GameViewport->Viewport, -2);
GetWorldTimerManager().SetTimer(WeaponTimerHandle, this, &AWeapon::FireWeaponAction, WeaponCooldown, true);
}
@ -59,12 +59,13 @@ bool AWeapon::UpgradeWeapon_Implementation()
CurrentLevel++;
return true;
}
return false;
}
void AWeapon::OnWeaponBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep,
const FHitResult& SweepResult)
{
if (AEnemyCharacter* Enemy = Cast<AEnemyCharacter>(OtherActor))
{
@ -73,7 +74,7 @@ void AWeapon::OnWeaponBeginOverlap(UPrimitiveComponent* OverlappedComponent, AAc
}
void AWeapon::OnWeaponEndOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
if (AEnemyCharacter* Enemy = Cast<AEnemyCharacter>(OtherActor))
{
@ -81,11 +82,13 @@ void AWeapon::OnWeaponEndOverlap(UPrimitiveComponent* OverlappedComp, AActor* Ot
}
}
void AWeapon::ResizeBoxComponent(FViewport* Viewport, uint32 unused)
void AWeapon::ResizeBoxComponent(FViewport* Viewport, const uint32 Unused)
{
if (!GEngine->GameViewport)
{
return;
}
if (!GEngine->GameViewport) return;
FVector TopLeft, TopLeftDir;
FVector TopRight, TopRightDir;
FVector BottomLeft, BottomLeftDir;
@ -108,11 +111,11 @@ void AWeapon::ResizeBoxComponent(FViewport* Viewport, uint32 unused)
// I am using the unused flag to work around a bug where the DeprojectScreenPositionToWorld doesn't match the
// values that I am expecting, in that they are way too small, for any other resize event we can skip this nonsense.
if (unused == -2)
if (Unused == -2)
{
width *= 266.666;
height *= 266.666;
}
BoxComponent->SetBoxExtent(FVector(height, width, 200.0f));
}

View File

@ -16,78 +16,86 @@ class VAMPIRES_API AWeapon : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Properties")
protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon | Information")
FText Name;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Properties")
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon | Information")
FText Description;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Properties")
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon | Information")
TObjectPtr<UTexture2D> Icon;
UPROPERTY(EditDefaultsOnly, Category = "Weapon Properties")
UPROPERTY(EditDefaultsOnly, Category = "Weapon | Properties")
TObjectPtr<USoundBase> WeaponActivatedSoundBase = nullptr;
UPROPERTY(EditDefaultsOnly, Category = "Weapon Properties")
TObjectPtr<UPaperSprite> WeaponSprite = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Properties")
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon | Properties")
float WeaponCooldown = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Properties")
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon | Properties")
float Damage;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Properties")
TArray<FText> UpgradeDescriptions;
int CurrentLevel = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Properties")
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon | Properties")
bool FollowPlayer = true;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon | Upgrades")
TArray<FText> UpgradeDescriptions;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon | Upgrades")
int MaxLevel = 0;
protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
UPROPERTY()
TObjectPtr<UBoxComponent> BoxComponent = nullptr;
TArray<TObjectPtr<AActor>> OverlappedEnemies = TArray<TObjectPtr<AActor>>();
int CurrentLevel = 0;
private:
FTimerHandle WeaponTimerHandle;
public:
// Sets default values for this actor's properties
// Sets default values for this actor's
AWeapon();
UFUNCTION(BlueprintNativeEvent)
bool UpgradeWeapon();
virtual bool UpgradeWeapon_Implementation();
FText GetWeaponName() const { return Name; }
FText GetDescription() const { return Description; }
TObjectPtr<UTexture2D> GetIcon() const { return Icon; }
float GetDamage() const { return Damage; }
bool GetFollowPlayer() const { return FollowPlayer; }
TArray<FText> GetUpgradeDescriptions() const { return UpgradeDescriptions; }
int GetWeaponLevel() const { return CurrentLevel; }
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
void ResetWeaponTimer();
public:
UFUNCTION(BlueprintNativeEvent)
void FireWeaponAction();
virtual void FireWeaponAction_Implementation();
UFUNCTION(BlueprintNativeEvent)
bool UpgradeWeapon();
virtual bool UpgradeWeapon_Implementation();
UFUNCTION()
virtual void OnWeaponBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep,
const FHitResult& SweepResult);
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep,
const FHitResult& SweepResult);
UFUNCTION()
virtual void OnWeaponEndOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex);
virtual void OnWeaponEndOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor,
UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex);
private:
void ResizeBoxComponent(FViewport* Viewport, uint32 unused);
void ResizeBoxComponent(FViewport* Viewport, uint32 Unused);
};

View File

@ -42,7 +42,7 @@ void UWeaponInventoryComponent::AddWeaponToInventory(TSubclassOf<AWeapon> Weapon
SpawnParameters.Owner = GetOwner();
AWeapon* weapon = GetWorld()->SpawnActor<AWeapon>(Weapon, SpawnParameters.Owner->GetTransform(), SpawnParameters);
if (weapon->FollowPlayer)
if (weapon->GetFollowPlayer())
{
weapon->AttachToActor(GetOwner(), FAttachmentTransformRules::KeepWorldTransform);
}

View File

@ -28,12 +28,12 @@ class VAMPIRES_API AGarlicWeapon : public AWeapon
{
GENERATED_BODY()
public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"), Category = "Weapon | Garlic")
TObjectPtr<USphereComponent> SphereComponent;
TArray<FOverlappedEnemy> GarlicOverlappedEnemies;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"), Category = "Weapon | Garlic")
TObjectPtr<UStaticMeshComponent> VisualEffectMeshComponent;
private:

View File

@ -18,13 +18,13 @@ class VAMPIRES_API ALightningRingWeapon : public AWeapon
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon | Lightning Ring")
int LightningBolts = 1;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon | Lightning Ring")
float LightingBoltRadius = 200.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon | Lightning Ring")
TObjectPtr<UNiagaraSystem> LightningEffectSystem;
public:

View File

@ -18,13 +18,13 @@ class VAMPIRES_API AProjectileWeapon : public AWeapon
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, Category = "Weapon Properties")
UPROPERTY(EditAnywhere, Category = "Weapon | Projectiles")
TObjectPtr<UProjectileDataAsset> ProjectileTemplate = nullptr;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon | Projectiles")
int ProjectilesPerActivation = 1;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon | Projectiles")
float ProjectileSpawningDelay = 0.25f;
protected:

View File

@ -52,7 +52,7 @@ void ASwarmAgent::OnSwarmAgentBeginOverlap(UPrimitiveComponent* OverlappedCompon
if (AVampireCharacter* character = Cast<AVampireCharacter>(ownerWeapon->GetOwner()))
{
AController* ownerController = character->GetController();
EnemyHealthComponent->TakeDamage(Enemy, ownerWeapon->Damage, nullptr, ownerController, this);
EnemyHealthComponent->TakeDamage(Enemy, ownerWeapon->GetDamage(), nullptr, ownerController, this);
}
}
}

View File

@ -15,19 +15,19 @@ class VAMPIRES_API ASwarmWeapon : public AWeapon
GENERATED_BODY()
public:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Timeline")
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon | Swarm")
TObjectPtr<UTimelineComponent> TimelineComponent = nullptr;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon | Swarm")
TObjectPtr<UCurveFloat> SwarmCurve;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon | Swarm")
float TimelinePlayRate = 1;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon | Swarm")
TSubclassOf<ASwarmAgent> SwarmActor;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon | Swarm")
float Distance = 250.0f;
private:

View File

@ -43,7 +43,7 @@ void ULevelUpWidget::NativeConstruct()
TArray<UUpgradeButtonDataObject*> upgradeItems;
for (AWeapon* weapon : Inventory)
{
if (weapon->CurrentLevel < weapon->UpgradeDescriptions.Num())
if (weapon->GetWeaponLevel() < weapon->GetUpgradeDescriptions().Num())
{
UUpgradeButtonDataObject* Temp = NewObject<UUpgradeButtonDataObject>(this);
Temp->SetData(weapon, this);

View File

@ -7,23 +7,22 @@
void UStarterWeaponButtonDataObject::SetData(AWeapon* Weapon, UUserWidget* parent)
{
WeaponName = Weapon->Name;
Description = Weapon->UpgradeDescriptions[Weapon->CurrentLevel];
WeaponIcon = Weapon->Icon;
WeaponName = Weapon->GetWeaponName();
WeaponIcon = Weapon->GetIcon();
WeaponInstance = Weapon;
Parent = parent;
if (Weapon->GetUpgradeDescriptions().Num() > Weapon->GetWeaponLevel())
{
Description = Weapon->GetUpgradeDescriptions()[Weapon->GetWeaponLevel()];
}
}
void UStarterWeaponButtonDataObject::SetData(TSubclassOf<AWeapon> Weapon, UUserWidget* parent)
{
AWeapon* temp = NewObject<AWeapon>(this, Weapon);
if (temp)
if (AWeapon* tempWeapon = NewObject<AWeapon>(this, Weapon))
{
WeaponName = temp->Name;
Description = temp->Description;
WeaponIcon = temp->Icon;
WeaponTemplate = Weapon;
Parent = parent;
SetData(tempWeapon, parent);
}
}

View File

@ -7,23 +7,22 @@
void UUpgradeButtonDataObject::SetData(AWeapon* Weapon, UUserWidget* parent)
{
WeaponName = Weapon->Name;
Description = Weapon->UpgradeDescriptions[Weapon->CurrentLevel];
WeaponIcon = Weapon->Icon;
WeaponName = Weapon->GetWeaponName();
WeaponIcon = Weapon->GetIcon();
WeaponInstance = Weapon;
Parent = parent;
if (Weapon->GetUpgradeDescriptions().Num() > Weapon->GetWeaponLevel())
{
Description = Weapon->GetUpgradeDescriptions()[Weapon->GetWeaponLevel()];
}
}
void UUpgradeButtonDataObject::SetData(TSubclassOf<AWeapon> Weapon, UUserWidget* parent)
{
AWeapon* temp = NewObject<AWeapon>(this, Weapon);
if (temp)
if (AWeapon* tempWeapon = NewObject<AWeapon>(this, Weapon))
{
WeaponName = temp->Name;
Description = temp->Description;
WeaponIcon = temp->Icon;
WeaponTemplate = Weapon;
Parent = parent;
SetData(tempWeapon, parent);
}
}