Skip to content

Commit

Permalink
#248 WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
xthebat committed Apr 24, 2024
1 parent f0c2cd8 commit 5341268
Show file tree
Hide file tree
Showing 10 changed files with 293 additions and 73 deletions.
24 changes: 16 additions & 8 deletions Source/Cloud9/Character/Cloud9Character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,21 @@
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/SpringArmComponent.h"
#include "Components/WidgetInteractionComponent.h"
#include "Components/DecalComponent.h"
#include "Components/CapsuleComponent.h"

#include "Cloud9/Tools/Extensions/AActor.h"
#include "Cloud9/Game/Cloud9DeveloperSettings.h"
#include "Cloud9/Contollers//Cloud9PlayerController.h"
#include "Cloud9/Weapon/Classes/Cloud9WeaponBase.h"
#include "Effects/Cloud9CharacterEffectInterface.h"
#include "Components/Cloud9InventoryComponent.h"
#include "Cloud9/Character/Components/Cloud9CharacterMovement.h"
#include "Cloud9/Character/Components/Cloud9SpringArmComponent.h"
#include "Cloud9/Tools/Extensions/AActor.h"
#include "Components/Cloud9CharacterMovement.h"
#include "Components/Cloud9SpringArmComponent.h"
#include "Components/Cloud9HealthComponent.h"
#include "Components/Cloud9AnimationComponent.h"
#include "Components/WidgetInteractionComponent.h"
#include "Components/Cloud9EffectsComponent.h"

const FName ACloud9Character::SpringArmComponentName = TEXT("CameraBoom");
const FName ACloud9Character::CameraComponentName = TEXT("TopDownCamera");
Expand Down Expand Up @@ -274,6 +276,16 @@ UCloud9HealthComponent* ACloud9Character::GetHealthComponent() const { return He

UCloud9AnimationComponent* ACloud9Character::GetAnimationComponent() const { return AnimationComponent; }

bool ACloud9Character::AddCharacterEffect(TSubclassOf<UCloud9CharacterEffectInterface> EffectClass)
{
return EffectsComponent->AddEffect(EffectClass);
}

bool ACloud9Character::RemoveCharacterEffect(UCloud9EffectsComponent* Effect)
{
return EffectsComponent->RemoveEffect(Effect);
}

void ACloud9Character::AddScore()
{
Score += 1;
Expand Down Expand Up @@ -472,8 +484,4 @@ void ACloud9Character::Tick(float DeltaSeconds)
{
InventoryComponent->SelectOtherAvailableWeapon(false);
}

Effects
| ETContainer::Filter{[&](let It) { return It->Elapsed(this, DeltaSeconds); }}
| ETContainer::ForEach{[&](let It) { It->Remove(this); }};
}
15 changes: 9 additions & 6 deletions Source/Cloud9/Character/Cloud9Character.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@

#include "Cloud9Character.generated.h"

class UCloud9CharacterEffect;
class UCloud9EffectsComponent;
class UCloud9CharacterEffectInterface;
class UWidgetInteractionComponent;
class ACloud9PlayerController;
class UCloud9InventoryComponent;
Expand Down Expand Up @@ -68,7 +69,6 @@ class ACloud9Character : public ACharacter
static constexpr let CrosshairRotationPitch = -90.0f;
static constexpr let CanStepUpOn = ECB_Yes;

public:
ACloud9Character(const FObjectInitializer& ObjectInitializer);

virtual void OnConstruction(const FTransform& Transform) override;
Expand Down Expand Up @@ -116,11 +116,14 @@ class ACloud9Character : public ACharacter

UCloud9AnimationComponent* GetAnimationComponent() const;

bool AddCharacterEffect(TSubclassOf<UCloud9CharacterEffectInterface> EffectClass);

bool RemoveCharacterEffect(UCloud9EffectsComponent* Effect);

void AddScore();

void UseObject();

public:
/** Event called when character score changed. */
UPROPERTY(BlueprintAssignable, meta=(AllowPrivateAccess), Category=Events)
FOnScoreChanged OnScoreChanged;
Expand Down Expand Up @@ -189,7 +192,7 @@ class ACloud9Character : public ACharacter
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Inventory, meta=(AllowPrivateAccess))
UCloud9InventoryComponent* InventoryComponent;

/** A state of the character health and armor. */
/** A health and armor state of character. */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess))
UCloud9HealthComponent* HealthComponent;

Expand All @@ -202,8 +205,8 @@ class ACloud9Character : public ACharacter
UWidgetInteractionComponent* WidgetInteractionComponent;

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Effects, meta=(AllowPrivateAccess))
TArray<UCloud9CharacterEffect*> Effects;
UCloud9EffectsComponent* EffectsComponent;

/** Current number of frags made by character */
UPROPERTY(BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess))
int Score;
Expand Down
111 changes: 111 additions & 0 deletions Source/Cloud9/Character/Components/Cloud9EffectsComponent.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright (c) 2024 Alexei Gladkikh

#include "Cloud9EffectsComponent.h"

#include "Cloud9/Tools/Macro/Common.h"
#include "Cloud9/Tools/Macro/Logging.h"

#include "Cloud9/Character/Components/Cloud9HealthComponent.h"
#include "Cloud9/Character/Cloud9Character.h"
#include "Cloud9/Tools/Extensions/TContainer.h"

UCloud9EffectsComponent::UCloud9EffectsComponent()
{
PrimaryComponentTick.bCanEverTick = true;
}

bool UCloud9EffectsComponent::AddEffect(TSubclassOf<UCloud9CharacterEffectInterface> EffectClass)
{
if (let Effect = NewObject<UObject>(this, EffectClass->StaticClass());
ICloud9CharacterEffectInterface::Execute_CanApply(Effect, this))
{
ICloud9CharacterEffectInterface::Execute_OnApply(Effect, this);

Effects.Add(Effect);

if (ICloud9CharacterEffectInterface::Execute_CanTick(Effect))
{
CanTickEffects.Add(Effect);
SetComponentTickEnabled(true);
}
else if (ICloud9CharacterEffectInterface::Execute_CanDamaged(Effect))
{
CanDamagedEffects.Add(Effect);
}

return true;
}

return false;
}

bool UCloud9EffectsComponent::RemoveEffect(UObject* Effect)
{
if (Effects.Remove(Effect) == 0)
{
log(Warning, "[Actor='%s'] Effect '%s' not found", *GetName(), *Effect->GetName());
return false;
}

CanDamagedEffects.Remove(Effect);
CanTickEffects.Remove(Effect);

SetComponentTickEnabled(CanTickEffects.Num() != 0);

ICloud9CharacterEffectInterface::Execute_OnRemove(Effect, this);
return true;
}

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

let Character = GetOwner<ACloud9Character>();
if (not IsValid(Character))
{
log(Error, "[Component='%s'] Owner is invalid", *GetName());
return;
}

let HealthComponent = Character->GetHealthComponent();
if (not IsValid(HealthComponent))
{
log(Error, "[Component='%s'] Owner HealthComponent is invalid", *GetName());
return;
}

HealthComponent->OnHealthChange.AddDynamic(this, &UCloud9EffectsComponent::OnDamageApplied);
}

void UCloud9EffectsComponent::OnDamageApplied(float Damage)
{
let Extinguished = CanDamagedEffects
| ETContainer::Filter{
[this, Damage](let It)
{
ICloud9CharacterEffectInterface::Execute_OnApplyDamage(It, this, Damage);
return ICloud9CharacterEffectInterface::Execute_IsExtinguished(It);
}
} | ETContainer::ToArray{};

// Cache effects to remove
Extinguished | ETContainer::ForEach{[this](let It) { RemoveEffect(It); }};
}

void UCloud9EffectsComponent::TickComponent(
float DeltaTime,
ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction)
{
let Extinguished = CanTickEffects
| ETContainer::Filter{
[this, DeltaTime](let It)
{
ICloud9CharacterEffectInterface::Execute_OnTick(It, this, DeltaTime);
return ICloud9CharacterEffectInterface::Execute_IsExtinguished(It);
}
} | ETContainer::ToArray{};

// Cache effects to remove
Extinguished | ETContainer::ForEach{[this](let It) { RemoveEffect(It); }};
}
51 changes: 51 additions & 0 deletions Source/Cloud9/Character/Components/Cloud9EffectsComponent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2024 Alexei Gladkikh

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"

#include "Cloud9/Character/Effects/Cloud9CharacterEffectInterface.h"

#include "Cloud9EffectsComponent.generated.h"


UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent))
class CLOUD9_API UCloud9EffectsComponent : public UActorComponent
{
GENERATED_BODY()

public:
UCloud9EffectsComponent();

bool AddEffect(TSubclassOf<UCloud9CharacterEffectInterface> EffectClass);

bool RemoveEffect(UObject* Effect);

private:
UPROPERTY(meta=(MustImplement=ICloud9CharacterEffectInterface))
TSet<UObject*> Effects;

/**
* Subset of Effects that may tick
*/
UPROPERTY(meta=(MustImplement=ICloud9CharacterEffectInterface))
TSet<UObject*> CanTickEffects;

/**
* Subset of Effects that can be damaged
*/
UPROPERTY(meta=(MustImplement=ICloud9CharacterEffectInterface))
TSet<UObject*> CanDamagedEffects;

UFUNCTION()
void OnDamageApplied(float Damage);

virtual void OnRegister() override;

virtual void TickComponent(
float DeltaTime,
ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction
) override;
};
4 changes: 0 additions & 4 deletions Source/Cloud9/Character/Effects/Cloud9CharacterEffect.cpp

This file was deleted.

31 changes: 0 additions & 31 deletions Source/Cloud9/Character/Effects/Cloud9CharacterEffect.h

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Copyright (c) 2024 Alexei Gladkikh

#include "Cloud9CharacterEffectInterface.h"
45 changes: 45 additions & 0 deletions Source/Cloud9/Character/Effects/Cloud9CharacterEffectInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2024 Alexei Gladkikh

#pragma once

#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "Cloud9CharacterEffectInterface.generated.h"

class UCloud9EffectsComponent;

UINTERFACE()
class UCloud9CharacterEffectInterface : public UInterface
{
GENERATED_BODY()
};

class CLOUD9_API ICloud9CharacterEffectInterface
{
GENERATED_BODY()

public:
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
bool IsExtinguished() const;

UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
bool OnApply(UCloud9EffectsComponent* Container);

UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
bool OnRemove(UCloud9EffectsComponent* Container);

UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
bool CanApply(const UCloud9EffectsComponent* Container);

UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
bool CanTick();

UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
bool CanDamaged();

UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void OnTick(const UCloud9EffectsComponent* Container, float DeltaSeconds);

UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void OnApplyDamage(const UCloud9EffectsComponent* Container, float Damage);
};
Loading

0 comments on commit 5341268

Please sign in to comment.