Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
v1.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
lucoiso authored Feb 20, 2023
2 parents 12319ac + 2aaed92 commit 35111e1
Show file tree
Hide file tree
Showing 15 changed files with 198 additions and 118 deletions.
4 changes: 2 additions & 2 deletions ModularFeatures_ExtraActions.uplugin
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"FileVersion": 3,
"Version": 2,
"VersionName": "1.2.2",
"Version": 3,
"VersionName": "1.2.3",
"FriendlyName": "Modular Features: Extra Actions",
"Description": "Integrates GAS and Enhanced Input to the existing Game Features and Modular plugins.",
"Category": "Game Features",
Expand Down
46 changes: 22 additions & 24 deletions Source/Private/Actions/GameFeatureAction_AddAbilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@
#include <Components/GameFrameworkComponentManager.h>
#include <InputAction.h>

#ifdef UE_INLINE_GENERATED_CPP_BY_NAME
#include UE_INLINE_GENERATED_CPP_BY_NAME(GameFeatureAction_AddAbilities)
#endif

void UGameFeatureAction_AddAbilities::OnGameFeatureActivating(FGameFeatureActivatingContext& Context)
{
if (!ensureAlways(ActiveExtensions.IsEmpty()) || !ensureAlways(ActiveRequests.IsEmpty()))
if (!ensureAlways(ActiveExtensions.IsEmpty()))
{
ResetExtension();
}
Expand All @@ -20,7 +24,6 @@ void UGameFeatureAction_AddAbilities::OnGameFeatureActivating(FGameFeatureActiva
void UGameFeatureAction_AddAbilities::OnGameFeatureDeactivating(FGameFeatureDeactivatingContext& Context)
{
Super::OnGameFeatureDeactivating(Context);

ResetExtension();
}

Expand All @@ -32,16 +35,14 @@ void UGameFeatureAction_AddAbilities::ResetExtension()
RemoveActorAbilities(ExtensionIterator->Key.Get());
}

ActiveRequests.Empty();
Super::ResetExtension();
}

void UGameFeatureAction_AddAbilities::AddToWorld(const FWorldContext& WorldContext)
{
if (UGameFrameworkComponentManager* const ComponentManager = GetGameFrameworkComponentManager(WorldContext);
IsValid(ComponentManager) && !TargetPawnClass.IsNull())
if (UGameFrameworkComponentManager* const ComponentManager = GetGameFrameworkComponentManager(WorldContext); IsValid(ComponentManager) && !TargetPawnClass.IsNull())
{
using FHandlerDelegate = UGameFrameworkComponentManager::FExtensionHandlerDelegate;

const FHandlerDelegate ExtensionHandlerDelegate = FHandlerDelegate::CreateUObject(this, &UGameFeatureAction_AddAbilities::HandleActorExtension);

ActiveRequests.Add(ComponentManager->AddExtensionHandler(TargetPawnClass, ExtensionHandlerDelegate));
Expand All @@ -50,8 +51,6 @@ void UGameFeatureAction_AddAbilities::AddToWorld(const FWorldContext& WorldConte

void UGameFeatureAction_AddAbilities::HandleActorExtension(AActor* Owner, const FName EventName)
{
UE_LOG(LogGameplayFeaturesExtraActions, Display, TEXT("Event %s sent by Actor %s for ability management."), *EventName.ToString(), *Owner->GetName());

if (EventName == UGameFrameworkComponentManager::NAME_ExtensionRemoved || EventName == UGameFrameworkComponentManager::NAME_ReceiverRemoved)
{
RemoveActorAbilities(Owner);
Expand All @@ -74,7 +73,7 @@ void UGameFeatureAction_AddAbilities::HandleActorExtension(AActor* Owner, const
{
if (Entry.AbilityClass.IsNull())
{
UE_LOG(LogGameplayFeaturesExtraActions, Error, TEXT("%s: Ability class is null."), *FString(__func__));
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Error, TEXT("%s: Ability class is null."), *FString(__func__));
}
else
{
Expand All @@ -95,7 +94,7 @@ void UGameFeatureAction_AddAbilities::AddActorAbilities(AActor* TargetActor, con
return;
}

if (UAbilitySystemComponent* const AbilitySystemComponent = ModularFeaturesHelper::GetAbilitySystemComponentByActor(TargetActor))
if (UAbilitySystemComponent* const AbilitySystemComponent = ModularFeaturesHelper::GetAbilitySystemComponentInActor(TargetActor))
{
// If InputID Enumeration using is disabled, assume -1 as value
const int32 InputID = ModularFeaturesHelper::GetInputIDByName(Ability.InputIDValueName, InputIDEnumeration_Ptr.Get());
Expand All @@ -106,14 +105,13 @@ void UGameFeatureAction_AddAbilities::AddActorAbilities(AActor* TargetActor, con
// Load the ability class and store into a const variable
const TSubclassOf<UGameplayAbility> AbilityToAdd = Ability.AbilityClass.LoadSynchronous();

UE_LOG(LogGameplayFeaturesExtraActions, Display, TEXT("%s: Adding ability %s to Actor %s."), *FString(__func__), *AbilityToAdd->GetName(), *TargetActor->GetName());
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Display, TEXT("%s: Adding ability %s to Actor %s."), *FString(__func__), *AbilityToAdd->GetName(), *TargetActor->GetName());

// Create the spec, used to give the ability to target's ability system component
FGameplayAbilitySpec NewAbilitySpec(AbilityToAdd, Ability.AbilityLevel, InputID, TargetActor);

// Try to give the ability to the target and check if the spec handle is valid
if (const FGameplayAbilitySpecHandle NewSpecHandle = AbilitySystemComponent->GiveAbility(NewAbilitySpec);
NewSpecHandle.IsValid())
if (const FGameplayAbilitySpecHandle NewSpecHandle = AbilitySystemComponent->GiveAbility(NewAbilitySpec); NewSpecHandle.IsValid())
{
// Add the spec handle to the ability data
NewAbilityData.SpecHandle.Add(NewSpecHandle);
Expand All @@ -125,8 +123,7 @@ void UGameFeatureAction_AddAbilities::AddActorAbilities(AActor* TargetActor, con
const IMFEA_AbilityInputBinding* const SetupInputInterface = ModularFeaturesHelper::GetAbilityInputBindingInterface(TargetActor, InputBindingOwnerOverride);

// If we can bind the input to the target interface, we must add the input reference to the ability data
if (UInputAction* const AbilityInput = Ability.InputAction.LoadSynchronous();
ModularFeaturesHelper::BindAbilityInputToInterfaceOwner(SetupInputInterface, AbilityInput, NewAbilitySpec))
if (UInputAction* const AbilityInput = Ability.InputAction.LoadSynchronous(); ModularFeaturesHelper::BindAbilityInputToInterfaceOwner(SetupInputInterface, AbilityInput, NewAbilitySpec))
{
NewAbilityData.InputReference.Add(AbilityInput);
}
Expand All @@ -137,7 +134,7 @@ void UGameFeatureAction_AddAbilities::AddActorAbilities(AActor* TargetActor, con
}
else
{
UE_LOG(LogGameplayFeaturesExtraActions, Error, TEXT("%s: Failed to find AbilitySystemComponent on Actor %s."), *FString(__func__), *TargetActor->GetName());
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Error, TEXT("%s: Failed to find AbilitySystemComponent on Actor %s."), *FString(__func__), *TargetActor->GetName());
}
}

Expand All @@ -157,20 +154,21 @@ void UGameFeatureAction_AddAbilities::RemoveActorAbilities(AActor* TargetActor)
}

// Check if we can remove the abilities from this target actor by checking if it is inside the active extensions map
FActiveAbilityData ActiveAbilities = ActiveExtensions.FindRef(TargetActor);
if constexpr (&ActiveAbilities == nullptr)
FActiveAbilityData* const ActiveAbilities = ActiveExtensions.Find(TargetActor);
if (!ActiveAbilities)
{
UE_LOG(LogGameplayFeaturesExtraActions, Warning, TEXT("%s: No active abilities found for Actor %s."), *FString(__func__), *TargetActor->GetName());
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Warning, TEXT("%s: No active abilities found for Actor %s."), *FString(__func__), *TargetActor->GetName());
ActiveExtensions.Remove(TargetActor);

return;
}

if (UAbilitySystemComponent* const AbilitySystemComponent = ModularFeaturesHelper::GetAbilitySystemComponentByActor(TargetActor))
if (UAbilitySystemComponent* const AbilitySystemComponent = ModularFeaturesHelper::GetAbilitySystemComponentInActor(TargetActor))
{
UE_LOG(LogGameplayFeaturesExtraActions, Display, TEXT("%s: Removing associated abilities from Actor %s."), *FString(__func__), *TargetActor->GetName());
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Display, TEXT("%s: Removing associated abilities from Actor %s."), *FString(__func__), *TargetActor->GetName());

// Iterate the active abilities and remove all spec handle associated to this actor
for (const FGameplayAbilitySpecHandle& SpecHandle : ActiveAbilities.SpecHandle)
for (const FGameplayAbilitySpecHandle& SpecHandle : ActiveAbilities->SpecHandle)
{
if (SpecHandle.IsValid())
{
Expand All @@ -183,12 +181,12 @@ void UGameFeatureAction_AddAbilities::RemoveActorAbilities(AActor* TargetActor)
// Get the interface owner and try to remove the input bindings
if (const IMFEA_AbilityInputBinding* const SetupInputInterface = ModularFeaturesHelper::GetAbilityInputBindingInterface(TargetActor, InputBindingOwnerOverride))
{
ModularFeaturesHelper::RemoveAbilityInputInInterfaceOwner(SetupInputInterface->_getUObject(), ActiveAbilities.InputReference);
ModularFeaturesHelper::RemoveAbilityInputInInterfaceOwner(SetupInputInterface->_getUObject(), ActiveAbilities->InputReference);
}
}
else if (IsValid(GetWorld()) && IsValid(GetWorld()->GetGameInstance()))
{
UE_LOG(LogGameplayFeaturesExtraActions, Error, TEXT("%s: Failed to find AbilitySystemComponent on Actor %s."), *FString(__func__), *TargetActor->GetName());
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Error, TEXT("%s: Failed to find AbilitySystemComponent on Actor %s."), *FString(__func__), *TargetActor->GetName());
}

ActiveExtensions.Remove(TargetActor);
Expand Down
46 changes: 22 additions & 24 deletions Source/Private/Actions/GameFeatureAction_AddAttribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@
#include <Components/GameFrameworkComponentManager.h>
#include <Runtime/Launch/Resources/Version.h>

#ifdef UE_INLINE_GENERATED_CPP_BY_NAME
#include UE_INLINE_GENERATED_CPP_BY_NAME(GameFeatureAction_AddAttribute)
#endif

void UGameFeatureAction_AddAttribute::OnGameFeatureActivating(FGameFeatureActivatingContext& Context)
{
if (!ensureAlways(ActiveExtensions.IsEmpty()) || !ensureAlways(ActiveRequests.IsEmpty()))
if (!ensureAlways(ActiveExtensions.IsEmpty()))
{
ResetExtension();
}
Expand All @@ -20,7 +24,6 @@ void UGameFeatureAction_AddAttribute::OnGameFeatureActivating(FGameFeatureActiva
void UGameFeatureAction_AddAttribute::OnGameFeatureDeactivating(FGameFeatureDeactivatingContext& Context)
{
Super::OnGameFeatureDeactivating(Context);

ResetExtension();
}

Expand All @@ -32,16 +35,14 @@ void UGameFeatureAction_AddAttribute::ResetExtension()
RemoveAttribute(ExtensionIterator->Key.Get());
}

ActiveRequests.Empty();
Super::ResetExtension();
}

void UGameFeatureAction_AddAttribute::AddToWorld(const FWorldContext& WorldContext)
{
if (UGameFrameworkComponentManager* const ComponentManager = GetGameFrameworkComponentManager(WorldContext);
IsValid(ComponentManager) && !TargetPawnClass.IsNull())
if (UGameFrameworkComponentManager* const ComponentManager = GetGameFrameworkComponentManager(WorldContext); IsValid(ComponentManager) && !TargetPawnClass.IsNull())
{
using FHandlerDelegate = UGameFrameworkComponentManager::FExtensionHandlerDelegate;

const FHandlerDelegate ExtensionHandlerDelegate = FHandlerDelegate::CreateUObject(this, &UGameFeatureAction_AddAttribute::HandleActorExtension);

ActiveRequests.Add(ComponentManager->AddExtensionHandler(TargetPawnClass, ExtensionHandlerDelegate));
Expand All @@ -50,8 +51,6 @@ void UGameFeatureAction_AddAttribute::AddToWorld(const FWorldContext& WorldConte

void UGameFeatureAction_AddAttribute::HandleActorExtension(AActor* Owner, const FName EventName)
{
UE_LOG(LogGameplayFeaturesExtraActions, Display, TEXT("Event %s sent by Actor %s for attribute management."), *EventName.ToString(), *Owner->GetName());

if (EventName == UGameFrameworkComponentManager::NAME_ExtensionRemoved || EventName == UGameFrameworkComponentManager::NAME_ReceiverRemoved)
{
RemoveAttribute(Owner);
Expand All @@ -67,7 +66,7 @@ void UGameFeatureAction_AddAttribute::HandleActorExtension(AActor* Owner, const

if (Attribute.IsNull())
{
UE_LOG(LogGameplayFeaturesExtraActions, Error, TEXT("%s: Attribute is null."), *FString(__func__));
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Error, TEXT("%s: Attribute is null."), *FString(__func__));
}
else
{
Expand All @@ -85,7 +84,7 @@ void UGameFeatureAction_AddAttribute::AddAttribute(AActor* TargetActor)
}

// Get the ability system component of the target actor
if (UAbilitySystemComponent* const AbilitySystemComponent = ModularFeaturesHelper::GetAbilitySystemComponentByActor(TargetActor))
if (UAbilitySystemComponent* const AbilitySystemComponent = ModularFeaturesHelper::GetAbilitySystemComponentInActor(TargetActor))
{
// Load and store the AttributeSet Class into a const variable
if (const TSubclassOf<UAttributeSet> SetType = Attribute.LoadSynchronous())
Expand All @@ -105,18 +104,18 @@ void UGameFeatureAction_AddAttribute::AddAttribute(AActor* TargetActor)
// Force the ability system component to replicate the attribute addition
AbilitySystemComponent->ForceReplication();

UE_LOG(LogGameplayFeaturesExtraActions, Display, TEXT("%s: Attribute %s added to Actor %s."), *FString(__func__), *SetType->GetName(), *TargetActor->GetName());
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Display, TEXT("%s: Attribute %s added to Actor %s."), *FString(__func__), *SetType->GetName(), *TargetActor->GetName());

ActiveExtensions.Add(TargetActor, NewSet);
}
else
{
UE_LOG(LogGameplayFeaturesExtraActions, Error, TEXT("%s: Attribute is invalid."), *FString(__func__));
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Error, TEXT("%s: Attribute is invalid."), *FString(__func__));
}
}
else
{
UE_LOG(LogGameplayFeaturesExtraActions, Error, TEXT("%s: Failed to find AbilitySystemComponent on Actor %s."), *FString(__func__), *TargetActor->GetName());
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Error, TEXT("%s: Failed to find AbilitySystemComponent on Actor %s."), *FString(__func__), *TargetActor->GetName());
}
}

Expand All @@ -136,30 +135,29 @@ void UGameFeatureAction_AddAttribute::RemoveAttribute(AActor* TargetActor)
}

// Get the ability system component of the target actor
if (UAbilitySystemComponent* const AbilitySystemComponent = ModularFeaturesHelper::GetAbilitySystemComponentByActor(TargetActor))
if (UAbilitySystemComponent* const AbilitySystemComponent = ModularFeaturesHelper::GetAbilitySystemComponentInActor(TargetActor))
{
// Get the added Attribute Set to the target actor by searching inside the Active Extensions, remove it from the Ability System Component and force a replication
#if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1
if (UAttributeSet* const AttributeToRemove = ActiveExtensions.FindRef(TargetActor).Get())
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION == 0
if (UAttributeSet* const AttributeToRemove = ActiveExtensions.FindRef(TargetActor).Get(); AbilitySystemComponent->GetSpawnedAttributes_Mutable().Remove(AttributeToRemove) != 0)
{
UE_LOG(LogGameplayFeaturesExtraActions, Display, TEXT("%s: Removing attribute %s from Actor %s."), *FString(__func__), *AttributeToRemove->GetName(), *TargetActor->GetName());

AbilitySystemComponent->RemoveSpawnedAttribute(AttributeToRemove);
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Display, TEXT("%s: Attribute %s removed from Actor %s."), *FString(__func__), *AttributeToRemove->GetName(), *TargetActor->GetName());
AbilitySystemComponent->ForceReplication();
}
#elif ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION == 0
if (UAttributeSet* const AttributeToRemove = ActiveExtensions.FindRef(TargetActor).Get();
AbilitySystemComponent->GetSpawnedAttributes_Mutable().Remove(AttributeToRemove) != 0)
#else
if (UAttributeSet* const AttributeToRemove = ActiveExtensions.FindRef(TargetActor).Get())
{
UE_LOG(LogGameplayFeaturesExtraActions, Display, TEXT("%s: Attribute %s removed from Actor %s."), *FString(__func__), *AttributeToRemove->GetName(), *TargetActor->GetName());
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Display, TEXT("%s: Removing attribute %s from Actor %s."), *FString(__func__), *AttributeToRemove->GetName(), *TargetActor->GetName());

AbilitySystemComponent->RemoveSpawnedAttribute(AttributeToRemove);
AbilitySystemComponent->ForceReplication();
}
#endif
}
// We don't need to warn the user if there's no valid world or game instance, since this is a common case when the game is shutting down
else if (IsValid(GetWorld()) && IsValid(GetWorld()->GetGameInstance()))
{
UE_LOG(LogGameplayFeaturesExtraActions, Error, TEXT("%s: Failed to find AbilitySystemComponent on Actor %s."), *FString(__func__), *TargetActor->GetName());
UE_LOG(LogGameplayFeaturesExtraActions_Internal, Error, TEXT("%s: Failed to find AbilitySystemComponent on Actor %s."), *FString(__func__), *TargetActor->GetName());
}

ActiveExtensions.Remove(TargetActor);
Expand Down
Loading

0 comments on commit 35111e1

Please sign in to comment.