diff --git a/Source/Cloud9/Character/Cloud9Character.cpp b/Source/Cloud9/Character/Cloud9Character.cpp index 604248ec0..55159d0f7 100644 --- a/Source/Cloud9/Character/Cloud9Character.cpp +++ b/Source/Cloud9/Character/Cloud9Character.cpp @@ -40,7 +40,7 @@ #include "Cloud9/Game/Cloud9DeveloperSettings.h" #include "Cloud9/Contollers//Cloud9PlayerController.h" #include "Cloud9/Weapon/Classes/Cloud9WeaponBase.h" -#include "Effects/Cloud9CharacterEffectInterface.h" +#include "Cloud9/Character/Effects/Cloud9CharacterEffectTrait.h" #include "Components/Cloud9InventoryComponent.h" #include "Components/Cloud9CharacterMovement.h" #include "Components/Cloud9SpringArmComponent.h" @@ -276,12 +276,14 @@ UCloud9HealthComponent* ACloud9Character::GetHealthComponent() const { return He UCloud9AnimationComponent* ACloud9Character::GetAnimationComponent() const { return AnimationComponent; } -bool ACloud9Character::AddCharacterEffect(TSubclassOf EffectClass) +// ReSharper disable once CppMemberFunctionMayBeConst +UCloud9CharacterEffectTrait* ACloud9Character::AddCharacterEffect(TSubclassOf EffectClass) { return EffectsComponent->AddEffect(EffectClass); } -bool ACloud9Character::RemoveCharacterEffect(UCloud9EffectsComponent* Effect) +// ReSharper disable once CppMemberFunctionMayBeConst +bool ACloud9Character::RemoveCharacterEffect(UCloud9CharacterEffectTrait* Effect) { return EffectsComponent->RemoveEffect(Effect); } diff --git a/Source/Cloud9/Character/Cloud9Character.h b/Source/Cloud9/Character/Cloud9Character.h index d82be232f..1a4abbc67 100644 --- a/Source/Cloud9/Character/Cloud9Character.h +++ b/Source/Cloud9/Character/Cloud9Character.h @@ -31,8 +31,8 @@ #include "Cloud9Character.generated.h" +class UCloud9CharacterEffectTrait; class UCloud9EffectsComponent; -class UCloud9CharacterEffectInterface; class UWidgetInteractionComponent; class ACloud9PlayerController; class UCloud9InventoryComponent; @@ -116,9 +116,9 @@ class ACloud9Character : public ACharacter UCloud9AnimationComponent* GetAnimationComponent() const; - bool AddCharacterEffect(TSubclassOf EffectClass); + UCloud9CharacterEffectTrait* AddCharacterEffect(TSubclassOf EffectClass); - bool RemoveCharacterEffect(UCloud9EffectsComponent* Effect); + bool RemoveCharacterEffect(UCloud9CharacterEffectTrait* Effect); void AddScore(); diff --git a/Source/Cloud9/Character/Components/Cloud9EffectsComponent.cpp b/Source/Cloud9/Character/Components/Cloud9EffectsComponent.cpp index 437e95fd8..217eaf493 100644 --- a/Source/Cloud9/Character/Components/Cloud9EffectsComponent.cpp +++ b/Source/Cloud9/Character/Components/Cloud9EffectsComponent.cpp @@ -7,6 +7,7 @@ #include "Cloud9/Character/Components/Cloud9HealthComponent.h" #include "Cloud9/Character/Cloud9Character.h" +#include "Cloud9/Character/Effects/Cloud9CharacterEffectTrait.h" #include "Cloud9/Tools/Extensions/TContainer.h" UCloud9EffectsComponent::UCloud9EffectsComponent() @@ -14,32 +15,32 @@ UCloud9EffectsComponent::UCloud9EffectsComponent() PrimaryComponentTick.bCanEverTick = true; } -bool UCloud9EffectsComponent::AddEffect(TSubclassOf EffectClass) +UCloud9CharacterEffectTrait* UCloud9EffectsComponent::AddEffect( + TSubclassOf EffectClass) { - if (let Effect = NewObject(this, EffectClass->StaticClass()); - ICloud9CharacterEffectInterface::Execute_CanApply(Effect, this)) + if (let Effect = NewObject(this, EffectClass->StaticClass()); Effect->CanApply()) { - ICloud9CharacterEffectInterface::Execute_OnApply(Effect, this); + Effect->OnApply(); Effects.Add(Effect); - if (ICloud9CharacterEffectInterface::Execute_CanTick(Effect)) + if (Effect->CanTick()) { CanTickEffects.Add(Effect); SetComponentTickEnabled(true); } - else if (ICloud9CharacterEffectInterface::Execute_CanDamaged(Effect)) + else if (Effect->CanDamaged()) { CanDamagedEffects.Add(Effect); } - return true; + return Effect; } - return false; + return nullptr; } -bool UCloud9EffectsComponent::RemoveEffect(UObject* Effect) +bool UCloud9EffectsComponent::RemoveEffect(UCloud9CharacterEffectTrait* Effect) { if (Effects.Remove(Effect) == 0) { @@ -52,7 +53,7 @@ bool UCloud9EffectsComponent::RemoveEffect(UObject* Effect) SetComponentTickEnabled(CanTickEffects.Num() != 0); - ICloud9CharacterEffectInterface::Execute_OnRemove(Effect, this); + Effect->OnRemove(); return true; } @@ -81,14 +82,14 @@ void UCloud9EffectsComponent::OnDamageApplied(float Damage) { let Extinguished = CanDamagedEffects | ETContainer::Filter{ - [this, Damage](let It) + [Damage](let It) { - ICloud9CharacterEffectInterface::Execute_OnApplyDamage(It, this, Damage); - return ICloud9CharacterEffectInterface::Execute_IsExtinguished(It); + It->OnApplyDamage(Damage); + return It->IsExtinguished(); } } | ETContainer::ToArray{}; - // Cache effects to remove + // Cache effects to remove preventing modification during iteration Extinguished | ETContainer::ForEach{[this](let It) { RemoveEffect(It); }}; } @@ -99,13 +100,13 @@ void UCloud9EffectsComponent::TickComponent( { let Extinguished = CanTickEffects | ETContainer::Filter{ - [this, DeltaTime](let It) + [DeltaTime](let It) { - ICloud9CharacterEffectInterface::Execute_OnTick(It, this, DeltaTime); - return ICloud9CharacterEffectInterface::Execute_IsExtinguished(It); + It->OnTick(DeltaTime); + return It->IsExtinguished(); } } | ETContainer::ToArray{}; - // Cache effects to remove + // Cache effects to remove preventing modification during iteration Extinguished | ETContainer::ForEach{[this](let It) { RemoveEffect(It); }}; } diff --git a/Source/Cloud9/Character/Components/Cloud9EffectsComponent.h b/Source/Cloud9/Character/Components/Cloud9EffectsComponent.h index 31d0f8f16..29f17e07f 100644 --- a/Source/Cloud9/Character/Components/Cloud9EffectsComponent.h +++ b/Source/Cloud9/Character/Components/Cloud9EffectsComponent.h @@ -5,10 +5,9 @@ #include "CoreMinimal.h" #include "Components/ActorComponent.h" -#include "Cloud9/Character/Effects/Cloud9CharacterEffectInterface.h" - #include "Cloud9EffectsComponent.generated.h" +class UCloud9CharacterEffectTrait; UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent)) class CLOUD9_API UCloud9EffectsComponent : public UActorComponent @@ -18,25 +17,25 @@ class CLOUD9_API UCloud9EffectsComponent : public UActorComponent public: UCloud9EffectsComponent(); - bool AddEffect(TSubclassOf EffectClass); + UCloud9CharacterEffectTrait* AddEffect(TSubclassOf EffectClass); - bool RemoveEffect(UObject* Effect); + bool RemoveEffect(UCloud9CharacterEffectTrait* Effect); private: - UPROPERTY(meta=(MustImplement=ICloud9CharacterEffectInterface)) - TSet Effects; + UPROPERTY() + TSet Effects; /** * Subset of Effects that may tick */ - UPROPERTY(meta=(MustImplement=ICloud9CharacterEffectInterface)) - TSet CanTickEffects; + UPROPERTY() + TSet CanTickEffects; /** * Subset of Effects that can be damaged */ - UPROPERTY(meta=(MustImplement=ICloud9CharacterEffectInterface)) - TSet CanDamagedEffects; + UPROPERTY() + TSet CanDamagedEffects; UFUNCTION() void OnDamageApplied(float Damage); diff --git a/Source/Cloud9/Character/Components/Cloud9InventoryComponent.h b/Source/Cloud9/Character/Components/Cloud9InventoryComponent.h index 81aac4f35..7a5079fd7 100644 --- a/Source/Cloud9/Character/Components/Cloud9InventoryComponent.h +++ b/Source/Cloud9/Character/Components/Cloud9InventoryComponent.h @@ -55,11 +55,11 @@ class CLOUD9_API UCloud9InventoryComponent : public UActorComponent bool Initialize(const TArray& WeaponConfigs, EWeaponSlot WeaponSlot); /** - * Function selects weapon in new slot. + * Function selects a weapon in new slot. * * @param Slot New slot weapon slot. * @param Instant If set then no animation will be shown and switching will be instant. - * @param Force If set then other weapon will be selected even if animation playing + * @param Force If set, then another weapon will be selected even if animation playing */ UFUNCTION(BlueprintCallable) bool SelectWeapon(EWeaponSlot Slot, bool Instant = false, bool Force = false); diff --git a/Source/Cloud9/Character/Effects/Cloud9CharacterEffectInterface.cpp b/Source/Cloud9/Character/Effects/Cloud9CharacterEffectInterface.cpp deleted file mode 100644 index 68dbfd19d..000000000 --- a/Source/Cloud9/Character/Effects/Cloud9CharacterEffectInterface.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright (c) 2024 Alexei Gladkikh - -#include "Cloud9CharacterEffectInterface.h" diff --git a/Source/Cloud9/Character/Effects/Cloud9CharacterEffectInterface.h b/Source/Cloud9/Character/Effects/Cloud9CharacterEffectInterface.h deleted file mode 100644 index ebc40c31c..000000000 --- a/Source/Cloud9/Character/Effects/Cloud9CharacterEffectInterface.h +++ /dev/null @@ -1,45 +0,0 @@ -// 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); -}; diff --git a/Source/Cloud9/Character/Effects/Cloud9CharacterEffectTrait.cpp b/Source/Cloud9/Character/Effects/Cloud9CharacterEffectTrait.cpp new file mode 100644 index 000000000..7df2ccd3e --- /dev/null +++ b/Source/Cloud9/Character/Effects/Cloud9CharacterEffectTrait.cpp @@ -0,0 +1,44 @@ +// Copyright (c) 2024 Alexei Gladkikh + +#include "Cloud9CharacterEffectTrait.h" + +#include "Cloud9/Tools/Macro/Common.h" +#include "Cloud9/Tools/Macro/Logging.h" + +#include "Cloud9/Character/Components/Cloud9EffectsComponent.h" + +bool UCloud9CharacterEffectTrait::IsExtinguished_Implementation() const { return true; } + +void UCloud9CharacterEffectTrait::OnApply_Implementation() {} + +void UCloud9CharacterEffectTrait::OnRemove_Implementation() {} + +bool UCloud9CharacterEffectTrait::CanApply_Implementation() const { return true; } + +bool UCloud9CharacterEffectTrait::CanTick_Implementation() const { return false; } + +bool UCloud9CharacterEffectTrait::CanDamaged_Implementation() const { return false; } + +void UCloud9CharacterEffectTrait::OnTick_Implementation(float DeltaSeconds) {} + +void UCloud9CharacterEffectTrait::OnApplyDamage_Implementation(float Damage) {} + +const UCloud9EffectsComponent* UCloud9CharacterEffectTrait::GetContainer() const +{ + let MyOuter = GetOuter(); + + if (not IsValid(MyOuter)) + { + log(Fatal, "Effect outer parent object wasn't specified"); + return nullptr; + } + + let Container = Cast(MyOuter); + if (not IsValid(Container)) + { + log(Fatal, "Effect outer parent object is invalid"); + return nullptr; + } + + return Container; +} diff --git a/Source/Cloud9/Character/Effects/Cloud9CharacterEffectTrait.h b/Source/Cloud9/Character/Effects/Cloud9CharacterEffectTrait.h new file mode 100644 index 000000000..6aa137d29 --- /dev/null +++ b/Source/Cloud9/Character/Effects/Cloud9CharacterEffectTrait.h @@ -0,0 +1,60 @@ +// Copyright (c) 2024 Alexei Gladkikh + +#pragma once + +#include "CoreMinimal.h" +#include "UObject/Object.h" + +#include "Cloud9CharacterEffectTrait.generated.h" + +class UCloud9EffectsComponent; + +UCLASS() +class CLOUD9_API UCloud9CharacterEffectTrait : public UObject +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, BlueprintNativeEvent) + bool IsExtinguished() const; + + UFUNCTION(BlueprintCallable, BlueprintNativeEvent) + void OnApply(); + + UFUNCTION(BlueprintCallable, BlueprintNativeEvent) + void OnRemove(); + + UFUNCTION(BlueprintCallable, BlueprintNativeEvent) + bool CanApply() const; + + UFUNCTION(BlueprintCallable, BlueprintNativeEvent) + bool CanTick() const; + + UFUNCTION(BlueprintCallable, BlueprintNativeEvent) + bool CanDamaged() const; + + UFUNCTION(BlueprintCallable, BlueprintNativeEvent) + void OnTick(float DeltaSeconds); + + UFUNCTION(BlueprintCallable, BlueprintNativeEvent) + void OnApplyDamage(float Damage); + + virtual bool IsExtinguished_Implementation() const; + + virtual void OnApply_Implementation(); + + virtual void OnRemove_Implementation(); + + virtual bool CanApply_Implementation() const; + + virtual bool CanTick_Implementation() const; + + virtual bool CanDamaged_Implementation() const; + + virtual void OnTick_Implementation(float DeltaSeconds); + + virtual void OnApplyDamage_Implementation(float Damage); + +protected: + const UCloud9EffectsComponent* GetContainer() const; +}; diff --git a/Source/Cloud9/Character/Effects/Cloud9CharacterShieldEffect.cpp b/Source/Cloud9/Character/Effects/Cloud9CharacterShieldEffect.cpp index 209632251..b152b46c5 100644 --- a/Source/Cloud9/Character/Effects/Cloud9CharacterShieldEffect.cpp +++ b/Source/Cloud9/Character/Effects/Cloud9CharacterShieldEffect.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Alexei Gladkikh +// Copyright (c) 2024 Alexei Gladkikh #include "Cloud9CharacterShieldEffect.h" @@ -9,14 +9,13 @@ const FName UCloud9CharacterShieldEffect::ShieldEnableName = TEXT("Shield Enabled"); -bool UCloud9CharacterShieldEffect::ToggleEffect(const UCloud9EffectsComponent* Container, bool IsEnabled) const +void UCloud9CharacterShieldEffect::ToggleEffect(bool IsEnabled) const { - let Character = Container->GetOwner(); + let Character = GetContainer()->GetOwner(); if (not IsValid(Character)) { log(Error, "[Effect='%s'] Owner is invalid", *GetName()); - return false; } if (let Mesh = Character->GetMesh(); IsValid(Mesh)) @@ -24,12 +23,8 @@ bool UCloud9CharacterShieldEffect::ToggleEffect(const UCloud9EffectsComponent* C Mesh->GetMaterials() | ETContainer::Transform{[](let It) { return Cast(It); }} | ETContainer::Filter{[](let It) { return IsValid(It); }} - | ETContainer::ForEach{ - [IsEnabled](let It) { It->SetScalarParameterValue(ShieldEnableName, IsEnabled); } - }; + | ETContainer::ForEach{[IsEnabled](let It) { It->SetScalarParameterValue(ShieldEnableName, IsEnabled); }}; } - - return true; } UCloud9CharacterShieldEffect::UCloud9CharacterShieldEffect() @@ -38,35 +33,18 @@ UCloud9CharacterShieldEffect::UCloud9CharacterShieldEffect() ElapsedTime = 0.0f; } -bool UCloud9CharacterShieldEffect::IsExtinguished_Implementation() const -{ - return ElapsedTime >= EffectTime; -} +bool UCloud9CharacterShieldEffect::IsExtinguished_Implementation() const { return ElapsedTime >= EffectTime; } -bool UCloud9CharacterShieldEffect::OnApply_Implementation(UCloud9EffectsComponent* Container) -{ - return ToggleEffect(Container, true); -} +void UCloud9CharacterShieldEffect::OnApply_Implementation() { ToggleEffect(true); } -bool UCloud9CharacterShieldEffect::OnRemove_Implementation(UCloud9EffectsComponent* Container) -{ - return ToggleEffect(Container, false); -} +void UCloud9CharacterShieldEffect::OnRemove_Implementation() { ToggleEffect(false); } -bool UCloud9CharacterShieldEffect::CanApply_Implementation(const UCloud9EffectsComponent* Container) +bool UCloud9CharacterShieldEffect::CanApply_Implementation() const { + // TODO: Check only one shield effect applied return true; } -bool UCloud9CharacterShieldEffect::CanTick_Implementation() { return true; } - -bool UCloud9CharacterShieldEffect::CanDamaged_Implementation() { return false; } - -void UCloud9CharacterShieldEffect::OnTick_Implementation(const UCloud9EffectsComponent* Container, float DeltaSeconds) -{ - ElapsedTime += DeltaSeconds; -} +bool UCloud9CharacterShieldEffect::CanTick_Implementation() const { return true; } -void UCloud9CharacterShieldEffect::OnApplyDamage_Implementation( - const UCloud9EffectsComponent* Container, - float Damage) {} +void UCloud9CharacterShieldEffect::OnTick_Implementation(float DeltaSeconds) { ElapsedTime += DeltaSeconds; } diff --git a/Source/Cloud9/Character/Effects/Cloud9CharacterShieldEffect.h b/Source/Cloud9/Character/Effects/Cloud9CharacterShieldEffect.h index f81f87b4a..af08f2d32 100644 --- a/Source/Cloud9/Character/Effects/Cloud9CharacterShieldEffect.h +++ b/Source/Cloud9/Character/Effects/Cloud9CharacterShieldEffect.h @@ -5,13 +5,13 @@ #include "CoreMinimal.h" #include "Components/ActorComponent.h" -#include "Cloud9CharacterEffectInterface.h" +#include "Cloud9CharacterEffectTrait.h" #include "Cloud9CharacterShieldEffect.generated.h" UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent)) -class CLOUD9_API UCloud9CharacterShieldEffect : public UObject, public ICloud9CharacterEffectInterface +class CLOUD9_API UCloud9CharacterShieldEffect : public UCloud9CharacterEffectTrait { GENERATED_BODY() @@ -29,20 +29,16 @@ class CLOUD9_API UCloud9CharacterShieldEffect : public UObject, public ICloud9Ch virtual bool IsExtinguished_Implementation() const override; - virtual bool OnApply_Implementation(UCloud9EffectsComponent* Container) override; + virtual void OnApply_Implementation() override; - virtual bool OnRemove_Implementation(UCloud9EffectsComponent* Container) override; + virtual void OnRemove_Implementation() override; - virtual bool CanApply_Implementation(const UCloud9EffectsComponent* Container) override; + virtual bool CanApply_Implementation() const override; - virtual bool CanTick_Implementation() override; + virtual bool CanTick_Implementation() const override; - virtual bool CanDamaged_Implementation() override; - - virtual void OnTick_Implementation(const UCloud9EffectsComponent* Container, float DeltaSeconds) override; - - virtual void OnApplyDamage_Implementation(const UCloud9EffectsComponent* Container, float Damage) override; + virtual void OnTick_Implementation(float DeltaSeconds) override; private: - bool ToggleEffect(const UCloud9EffectsComponent* Container, bool IsEnabled) const; + void ToggleEffect(bool IsEnabled) const; }; diff --git a/Source/Cloud9/Structures/CommonGameInfo.cpp b/Source/Cloud9/Structures/CommonGameInfo.cpp new file mode 100644 index 000000000..9e2415601 --- /dev/null +++ b/Source/Cloud9/Structures/CommonGameInfo.cpp @@ -0,0 +1,9 @@ +// Copyright (c) 2024 Alexei Gladkikh + +#include "SavedInfo.h" + +void FSavedInfo::Reset() +{ + bIsLoadRequired = false; + Players.Reset(); +} diff --git a/Source/Cloud9/Structures/CommonGameInfo.h b/Source/Cloud9/Structures/CommonGameInfo.h new file mode 100644 index 000000000..797aa1330 --- /dev/null +++ b/Source/Cloud9/Structures/CommonGameInfo.h @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Alexei Gladkikh + +#pragma once + +#include "PlayerSavedInfo.h" + +#include "SavedInfo.generated.h" + +USTRUCT(BlueprintType) +struct FSavedInfo +{ + GENERATED_BODY() + + UPROPERTY(Category=Base, BlueprintReadOnly) + bool bIsLoadRequired; + + UPROPERTY(Category=Weapon, BlueprintReadOnly) + TMap Players; + + void Reset(); +};