Not logged in - Login

Reflection Ability

Created By: Ikthaleon

In our game we have the concept of casting a "reflection" ability. This ability lasts for a few seconds and causes a set amount of damage to the attacker each time they hit the caster.

To do this, we set a Gameplay Effect on the casting character, and each time they are attacked, we check to see if the Gameplay Effect is there, and if so to damage to the attacker.

/* This is where the effect is called (we call it from within the GameplayAbility itself). 

For context this is called from our PreGameplayEffectExecute - we process damage and healing effects here. */

ApplyReflect(FName(TEXT("GE_ReflectShield")), Data, attackingCharacter, receiverCharacter);
/*
    Apply the Reflect effect on the attackingCharacter (that is the caster). 
    Having this effect for the lifetime of the effect means that whenever the attackingCharacter is hit, we check for the reflection, and cause damage back to the attacker.

    The attackingCharacter has a GameplayEffect ability called "BaneShieldReflect" in BP (allowing different reflection choices for the designer).
*/
void UAttributeSetBase::ApplyReflect(FName reflectTagName, struct FGameplayEffectModCallbackData &Data, ACharacterBase* attackingCharacter, ACharacterBase* receiverCharacter)
{
    if ((receiverCharacter) && (attackingCharacter))
    {
        /* Cause Effect on the Attacker */
        UGameplayEffect* effect = NewObject<UGameplayEffect>(GetTransientPackage(), reflectTagName);
        if (effect)It 
        {
            FGameplayEffectSpecHandle geReflect = attackingCharacter->GetAbilitySystemComponent()->MakeOutgoingSpec(
                attackingCharacter->BaneShieldReflect,
                1,
                attackingCharacter->GetAbilitySystemComponent()->MakeEffectContext());

            attackingCharacter->GetAbilitySystemComponent()->ApplyGameplayEffectSpecToSelf(*geReflect.Data.Get());

            UE_LOG(LogAttributes,
                Warning,
                TEXT("Applying Reflect effect to %s"), *attackingCharacter->CharacterName);
        }
        else
        {
            UE_LOG(LogAttributes,
                Warning,
                TEXT("Reflect effect not found"));
        }
    }
    else
    {
        UE_LOG(LogAttributes,
            Warning,
            TEXT("receiverCharacter / attackingCharacter not found"));
    }
}
/* Determine if Reflect shield is active 
    Params : 
        receiverCharacter - character that is being inspected
        tagName - tag on the receiverCharacter that indicates the reflect shield is active

*/
bool UAttributeSetBase::IsReflectShieldActive(ACharacterBase* receiverCharacter, FName tagName)
{
    FGameplayTag ReflectShieldTag = UGameplayTagsManager::Get().RequestGameplayTag(tagName, false);

    // If we get nothing back from the UGameplayTagsManager indicates the shield is not active
    if (ReflectShieldTag.EmptyTag == ReflectShieldTag)
    {
        UE_LOG(LogAttributes,
            Warning,
            TEXT("Reflect Shield Tag not present"));

        return false;
    }
    // Logging for debugging :) If the receiverCharacter has the reflect shield tag, log all their tags
    if (receiverCharacter && receiverCharacter->GetAbilitySystemComponent()->HasAllMatchingGameplayTags(FGameplayTagContainer(ReflectShieldTag)))
    {
        receiverCharacter->LogOwnedTags();

        UE_LOG(LogAttributes,
            Warning,
            TEXT("Reflect Shield is active for %s"), *receiverCharacter->CharacterName);

        return true;
    }

    return false;
}
// Display list of currently owned tags for this actor
void ACharacterBase::LogOwnedTags()
{
    TArray<FGameplayTag> tagArray;
    FGameplayTagContainer OwnerTags;
    OwnerTags.Reset();
    GetAbilitySystemComponent()->GetOwnedGameplayTags(OwnerTags);
    OwnerTags.GetGameplayTagArray(tagArray);

    for (FGameplayTag gameTag : tagArray)
    {
        UE_LOG(LogAttributes,
            Warning,
            TEXT("[%s] has tag : %s"), *CharacterName, *gameTag.GetTagName().ToString());
    }
}