Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added destroyable balls grid #193

Merged
merged 2 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Content/Blueprints/Character/Ball/BP_Ball.uasset
Binary file not shown.
Binary file modified Content/Maps/warmup.umap
Binary file not shown.
3 changes: 0 additions & 3 deletions Source/Cloud9/Character/Cloud9Character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ ACloud9Character::ACloud9Character(const FObjectInitializer& ObjectInitializer)

Score = 1; // TODO: Set score to 0 after implementation

OnTakePointDamage.AddDynamic(HealthComponent, &UCloud9CharacterHealthComponent::OnTakePointDamage);
OnTakeRadialDamage.AddDynamic(HealthComponent, &UCloud9CharacterHealthComponent::OnTakeRadialDamage);

// Activate ticking in order to update the cursor every frame.
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ bool UCloud9CharacterHealthComponent::ChangeHealth(float NewHealth)
return false;
}

Owner->MarkPendingKill();
Owner->Destroy();
}

return true;
Expand All @@ -71,6 +71,24 @@ bool UCloud9CharacterHealthComponent::ChangeArmor(float NewArmor)
return false;
}

void UCloud9CharacterHealthComponent::OnRegister()
{
Super::OnRegister();

let MyOwner = GetOwner();

if (not IsValid(MyOwner))
{
log(Error, "HealthComponent isn't valid");
return;
}

log(Display, "Register HealthComponent for '%s'", *MyOwner->GetName());
// Register twice or delegate add twice (?)
MyOwner->OnTakePointDamage.AddUniqueDynamic(this, &UCloud9CharacterHealthComponent::OnTakePointDamage);
MyOwner->OnTakeRadialDamage.AddUniqueDynamic(this, &UCloud9CharacterHealthComponent::OnTakeRadialDamage);
}

bool UCloud9CharacterHealthComponent::ChangeHasHelmet(bool NewState)
{
if (bHasHelmet != NewState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnHelmetChange, bool, State);

class ACloud9Character;

UCLASS(Blueprintable)
UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent))
class CLOUD9_API UCloud9CharacterHealthComponent
: public UActorComponent
, public ICloud9CharacterComponent
Expand Down Expand Up @@ -88,6 +88,8 @@ class CLOUD9_API UCloud9CharacterHealthComponent
bool ChangeHealth(float NewHealth);
bool ChangeArmor(float NewArmor);

virtual void OnRegister() override;

protected:
UPROPERTY(BlueprintAssignable, meta=(AllowPrivateAccess), Category=Events)
FOnHealthChange OnHealthChange;
Expand All @@ -99,14 +101,14 @@ class CLOUD9_API UCloud9CharacterHealthComponent
FOnHelmetChange OnHelmetChange;

/** Current percentage health of character */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess))
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess))
float Health;

/** Current percentage armor of character */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess))
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess))
float Armor;

/** Current percentage armor of character */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess))
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess))
bool bHasHelmet;
};
69 changes: 69 additions & 0 deletions Source/Cloud9/Environment/Cloud9ShootingRange.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (c) 2024 Alexei Gladkikh

#include "Cloud9ShootingRange.h"

#include "Cloud9/Tools/Extensions/FVector.h"
#include "Cloud9/Tools/Extensions/TContainer.h"
#include "Components/BoxComponent.h"

FName ACloud9ShootingRange::ZoneComponentName = "ZoneComponentName";

ACloud9ShootingRange::ACloud9ShootingRange()
{
PrimaryActorTick.bCanEverTick = true;
ZoneComponent = CreateDefaultSubobject<UBoxComponent>(ZoneComponentName);
RootComponent = ZoneComponent;
ZoneSize = {100.0f, 100.0f, 100.0f};
Count = 1;
GridSize = FVector::OneVector;
}

void ACloud9ShootingRange::OnConstruction(const FTransform& Transform)
{
Super::OnConstruction(Transform);
ZoneComponent->SetBoxExtent(ZoneSize);
}

void ACloud9ShootingRange::BeginPlay()
{
Super::BeginPlay();
}

void ACloud9ShootingRange::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
SpawnShootingActors();
}

bool ACloud9ShootingRange::SpawnShootingActors()
{
int Retries = 0;
FVector Origin;
FVector BoxExtent;
GetActorBounds(false, Origin, BoxExtent);
while (Actors.Num() != Count)
{
// GridSize items can be zero (GridSnap should handle it)
let Location = EFVector::Random(BoxExtent - Origin, BoxExtent + Origin, GridSize);
let Actor = GetWorld()->SpawnActor(Class.Get(), &Location);
if (Actors | ETContainer::AnyByPredicate{[Actor](let It) { return It->IsOverlappingActor(Actor); }})
{
if (constexpr int MaxRetries = 10; Retries++ == MaxRetries)
{
log(
Error,
"[Range=%s] parameters seems to be invalid can't spawn specified count of Actors = %d",
*GetName(), Count
);
SetActorTickEnabled(false);
return false;
}

continue;
}

Actors.Add(Actor);
}

return true;
}
48 changes: 48 additions & 0 deletions Source/Cloud9/Environment/Cloud9ShootingRange.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2024 Alexei Gladkikh

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Cloud9ShootingRange.generated.h"

class UBoxComponent;

UCLASS()
class CLOUD9_API ACloud9ShootingRange : public AActor
{
GENERATED_BODY()

public:
static FName ZoneComponentName;

ACloud9ShootingRange();

protected:
virtual void OnConstruction(const FTransform& Transform) override;

virtual void BeginPlay() override;

virtual void Tick(float DeltaTime) override;

UPROPERTY(BlueprintReadOnly, Category=Implementation)
UBoxComponent* ZoneComponent;

UPROPERTY(BlueprintReadOnly, Category=Implementation)
TArray<AActor*> Actors;

UPROPERTY(EditAnywhere, Category=Config)
int Count;

UPROPERTY(EditAnywhere, Category=Config)
TSoftClassPtr<AActor> Class;

UPROPERTY(EditAnywhere, Category=Config)
FVector ZoneSize;

UPROPERTY(EditAnywhere, Category=Config)
FVector GridSize;

private:
bool SpawnShootingActors();
};
20 changes: 20 additions & 0 deletions Source/Cloud9/Tools/Extensions/FVector.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#pragma once

#include "Cloud9/Tools/Macro/Operator.h"
#include "Cloud9/Tools/Macro/Common.h"
#include "Cloud9/Tools/Concepts.h"

namespace EFVector
Expand All @@ -40,4 +41,23 @@ namespace EFVector

OPERATOR_BODY(Normalize)
};

inline FVector Random(FVector Min, FVector Max)
{
return {
FMath::RandRange(Min.X, Max.X),
FMath::RandRange(Min.Y, Max.Y),
FMath::RandRange(Min.Z, Max.Z),
};
}

inline FVector Random(FVector Min, FVector Max, FVector Grid)
{
let Vector = Random(Min, Max);
return {
FMath::GridSnap(Vector.X, Grid.X),
FMath::GridSnap(Vector.Y, Grid.Y),
FMath::GridSnap(Vector.Z, Grid.Z),
};
}
}
21 changes: 18 additions & 3 deletions Source/Cloud9/Weapon/Classes/Cloud9WeaponGrenade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "Cloud9/Contollers/Cloud9PlayerController.h"
#include "Cloud9/Weapon/Sounds/Cloud9SoundPlayer.h"
#include "Cloud9/Weapon/Tables/WeaponTableGrenade.h"
#include "Kismet/GameplayStatics.h"

const FName ACloud9WeaponGrenade::ExplosionComponentName = TEXT("ExplosionComponent");
const FName ACloud9WeaponGrenade::DetonationEffectComponentName = TEXT("DetonationEffectComponent");
Expand Down Expand Up @@ -253,8 +254,6 @@ bool ACloud9WeaponGrenade::OnGrenadeActionLoop()
UCloud9SoundPlayer::PlaySingleSound(LoopSound, GetActorLocation(), Settings->Volume);
}

log(Display, "OnGrenadeActionLoop()")

if (GetWeaponInfo()->bIsDestroyedOnDetonation)
{
GetWeaponMesh()->SetHiddenInGame(true);
Expand All @@ -266,11 +265,27 @@ bool ACloud9WeaponGrenade::OnGrenadeActionLoop()
DetonationEffect->Activate();
}

let Location = GetActorLocation();

let IgnoredActors = TArray<AActor*>{};

// TODO: Handle other types of nades if required
UGameplayStatics::ApplyRadialDamage(
GetWorld(),
GetWeaponInfo()->Damage,
GetActorLocation(),
Explosion->Radius,
UDamageType::StaticClass(),
IgnoredActors,
this,
nullptr,
false,
ECC_Visibility);
Explosion->FireImpulse();

if (let ExplodeSounds = GetWeaponInfo()->Sounds.ExplodeSounds; ExplodeSounds.Num() > 0)
{
UCloud9SoundPlayer::PlayRandomSound(ExplodeSounds, GetActorLocation(), Settings->Volume);
UCloud9SoundPlayer::PlayRandomSound(ExplodeSounds, Location, Settings->Volume);
}

if (Settings->bIsDrawExplosionSpheres)
Expand Down