2022-05-23 18:41:30 +00:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
#include "LyraGameplayAbility_Interact.h"
|
2022-09-13 07:18:28 +00:00
|
|
|
|
|
|
|
#include "Abilities/GameplayAbilityTypes.h"
|
2022-05-23 18:41:30 +00:00
|
|
|
#include "AbilitySystemComponent.h"
|
2022-09-13 07:18:28 +00:00
|
|
|
#include "Containers/EnumAsByte.h"
|
|
|
|
#include "Engine/EngineTypes.h"
|
|
|
|
#include "GameFramework/Actor.h"
|
|
|
|
#include "GameplayTagContainer.h"
|
2022-05-23 18:41:30 +00:00
|
|
|
#include "Interaction/IInteractableTarget.h"
|
|
|
|
#include "Interaction/InteractionStatics.h"
|
|
|
|
#include "Interaction/Tasks/AbilityTask_GrantNearbyInteraction.h"
|
|
|
|
#include "NativeGameplayTags.h"
|
|
|
|
#include "Player/LyraPlayerController.h"
|
|
|
|
#include "UI/IndicatorSystem/IndicatorDescriptor.h"
|
2022-09-13 07:18:28 +00:00
|
|
|
#include "UI/IndicatorSystem/LyraIndicatorManagerComponent.h"
|
|
|
|
#include "UObject/NameTypes.h"
|
|
|
|
#include "UObject/ObjectPtr.h"
|
|
|
|
#include "UObject/ScriptInterface.h"
|
|
|
|
|
|
|
|
class UUserWidget;
|
2022-05-23 18:41:30 +00:00
|
|
|
|
|
|
|
UE_DEFINE_GAMEPLAY_TAG_STATIC(TAG_Ability_Interaction_Activate, "Ability.Interaction.Activate");
|
|
|
|
UE_DEFINE_GAMEPLAY_TAG(TAG_INTERACTION_DURATION_MESSAGE, "Ability.Interaction.Duration.Message");
|
|
|
|
|
|
|
|
ULyraGameplayAbility_Interact::ULyraGameplayAbility_Interact(const FObjectInitializer& ObjectInitializer)
|
|
|
|
: Super(ObjectInitializer)
|
|
|
|
{
|
|
|
|
ActivationPolicy = ELyraAbilityActivationPolicy::OnSpawn;
|
|
|
|
InstancingPolicy = EGameplayAbilityInstancingPolicy::InstancedPerActor;
|
|
|
|
NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::LocalPredicted;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ULyraGameplayAbility_Interact::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
|
|
|
|
{
|
|
|
|
Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
|
|
|
|
|
|
|
|
UAbilitySystemComponent* AbilitySystem = GetAbilitySystemComponentFromActorInfo();
|
|
|
|
if (AbilitySystem && AbilitySystem->GetOwnerRole() == ROLE_Authority)
|
|
|
|
{
|
|
|
|
UAbilityTask_GrantNearbyInteraction* Task = UAbilityTask_GrantNearbyInteraction::GrantAbilitiesForNearbyInteractors(this, InteractionScanRange, InteractionScanRate);
|
|
|
|
Task->ReadyForActivation();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ULyraGameplayAbility_Interact::UpdateInteractions(const TArray<FInteractionOption>& InteractiveOptions)
|
|
|
|
{
|
|
|
|
if (ALyraPlayerController* PC = GetLyraPlayerControllerFromActorInfo())
|
|
|
|
{
|
|
|
|
if (ULyraIndicatorManagerComponent* IndicatorManager = ULyraIndicatorManagerComponent::GetComponent(PC))
|
|
|
|
{
|
|
|
|
for (UIndicatorDescriptor* Indicator : Indicators)
|
|
|
|
{
|
|
|
|
IndicatorManager->RemoveIndicator(Indicator);
|
|
|
|
}
|
|
|
|
Indicators.Reset();
|
|
|
|
|
|
|
|
for (const FInteractionOption& InteractionOption : InteractiveOptions)
|
|
|
|
{
|
|
|
|
AActor* InteractableTargetActor = UInteractionStatics::GetActorFromInteractableTarget(InteractionOption.InteractableTarget);
|
|
|
|
|
|
|
|
TSoftClassPtr<UUserWidget> InteractionWidgetClass =
|
|
|
|
InteractionOption.InteractionWidgetClass.IsNull() ? DefaultInteractionWidgetClass : InteractionOption.InteractionWidgetClass;
|
|
|
|
|
|
|
|
UIndicatorDescriptor* Indicator = NewObject<UIndicatorDescriptor>();
|
|
|
|
Indicator->SetDataObject(InteractableTargetActor);
|
|
|
|
Indicator->SetSceneComponent(InteractableTargetActor->GetRootComponent());
|
|
|
|
Indicator->SetIndicatorClass(InteractionWidgetClass);
|
|
|
|
IndicatorManager->AddIndicator(Indicator);
|
|
|
|
|
|
|
|
Indicators.Add(Indicator);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//TODO This should probably be a noisy warning. Why are we updating interactions on a PC that can never do anything with them?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CurrentOptions = InteractiveOptions;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ULyraGameplayAbility_Interact::TriggerInteraction()
|
|
|
|
{
|
|
|
|
if (CurrentOptions.Num() == 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
UAbilitySystemComponent* AbilitySystem = GetAbilitySystemComponentFromActorInfo();
|
|
|
|
if (AbilitySystem)
|
|
|
|
{
|
|
|
|
const FInteractionOption& InteractionOption = CurrentOptions[0];
|
|
|
|
|
|
|
|
AActor* Instigator = GetAvatarActorFromActorInfo();
|
|
|
|
AActor* InteractableTargetActor = UInteractionStatics::GetActorFromInteractableTarget(InteractionOption.InteractableTarget);
|
|
|
|
|
|
|
|
// Allow the target to customize the event data we're about to pass in, in case the ability needs custom data
|
|
|
|
// that only the actor knows.
|
|
|
|
FGameplayEventData Payload;
|
|
|
|
Payload.EventTag = TAG_Ability_Interaction_Activate;
|
|
|
|
Payload.Instigator = Instigator;
|
|
|
|
Payload.Target = InteractableTargetActor;
|
|
|
|
|
|
|
|
// If needed we allow the interactable target to manipulate the event data so that for example, a button on the wall
|
|
|
|
// may want to specify a door actor to execute the ability on, so it might choose to override Target to be the
|
|
|
|
// door actor.
|
|
|
|
InteractionOption.InteractableTarget->CustomizeInteractionEventData(TAG_Ability_Interaction_Activate, Payload);
|
|
|
|
|
|
|
|
// Grab the target actor off the payload we're going to use it as the 'avatar' for the interaction, and the
|
|
|
|
// source InteractableTarget actor as the owner actor.
|
2022-09-13 07:18:28 +00:00
|
|
|
AActor* TargetActor = const_cast<AActor*>(ToRawPtr(Payload.Target));
|
2022-05-23 18:41:30 +00:00
|
|
|
|
|
|
|
// The actor info needed for the interaction.
|
|
|
|
FGameplayAbilityActorInfo ActorInfo;
|
|
|
|
ActorInfo.InitFromActor(InteractableTargetActor, TargetActor, InteractionOption.TargetAbilitySystem);
|
|
|
|
|
|
|
|
// Trigger the ability using event tag.
|
|
|
|
const bool bSuccess = InteractionOption.TargetAbilitySystem->TriggerAbilityFromGameplayEvent(
|
|
|
|
InteractionOption.TargetInteractionAbilityHandle,
|
|
|
|
&ActorInfo,
|
|
|
|
TAG_Ability_Interaction_Activate,
|
|
|
|
&Payload,
|
|
|
|
*InteractionOption.TargetAbilitySystem
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|