document.write("
// Fill out your copyright notice in the Description page of Project Settings.
#include "IAGA_PlayerMove.h"
#include "Abilities/Tasks/AbilityTask.h"
#include "Dandelion/Sandbox/Abilities/Tasks/AbilityTask_FollowCursor.h"
#include "Dandelion/Sandbox/Abilities/Tasks/AbilityTask_MoveCharacterToCursor.h"
#include "Dandelion/Sandbox/Pawns/DandelionPlayerCharacter.h"
UIAGA_PlayerMove::UIAGA_PlayerMove()
{
ResponseOnInputPressed = EInputActionGameplayAbilityResponse::CancelAbility;
ResponseOnInputReleased = EInputActionGameplayAbilityResponse::Custom;
}
bool UIAGA_PlayerMove::CanRestartAbility(
const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo& ActivationInfo
)
{
const bool FollowCursorAbilityTaskActive = IsValid(FollowCursorAbilityTask) && FollowCursorAbilityTask->IsActive();
const bool MoveToCursorAbilityTaskActive = IsValid(MoveCharacterToCursorAbilityTask) &&
MoveCharacterToCursorAbilityTask->IsActive();
return Super::CanRestartAbility(Handle, ActorInfo, ActivationInfo) &&
!FollowCursorAbilityTaskActive &&
MoveToCursorAbilityTaskActive;
}
void UIAGA_PlayerMove::ActivateAbility(
const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
const FGameplayEventData* TriggerEventData
)
{
AController* PlayerController = DandelionPlayerCharacter->GetController();
if (IsValid(PlayerController)) { PlayerController->StopMovement(); }
FollowCursorAbilityTask = UAbilityTask_FollowCursor::FollowCursor(this, NAME_None);
FollowCursorAbilityTask->OnMoveComplete.AddDynamic(this, &ThisClass::K2_EndAbility);
FollowCursorAbilityTask->ReadyForActivation();
Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
}
void UIAGA_PlayerMove::CancelAbility(
const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
const bool bReplicateCancelAbility
)
{
if (IsValid(FollowCursorAbilityTask) && FollowCursorAbilityTask->IsActive())
{
FollowCursorAbilityTask->ExternalCancel();
FollowCursorAbilityTask = nullptr;
UE_LOG(
LogGameplayAbility,
Verbose,
TEXT("%s: Cleaned up active FollowCursorAbilityTask in CancelAbility."),
*GetFullNameSafe(this)
);
}
if (IsValid(MoveCharacterToCursorAbilityTask) && MoveCharacterToCursorAbilityTask->IsActive())
{
MoveCharacterToCursorAbilityTask->ExternalCancel();
MoveCharacterToCursorAbilityTask = nullptr;
UE_LOG(
LogGameplayAbility,
Verbose,
TEXT("%s: Cleaned up active MoveCharacterToCursorAbilityTask in CancelAbility."),
*GetFullNameSafe(this)
);
}
Super::CancelAbility(Handle, ActorInfo, ActivationInfo, bReplicateCancelAbility);
}
void UIAGA_PlayerMove::EndAbility(
const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
const bool bReplicateEndAbility,
const bool bWasCancelled
)
{
if (IsValid(FollowCursorAbilityTask) && FollowCursorAbilityTask->IsActive())
{
FollowCursorAbilityTask->EndTask();
FollowCursorAbilityTask = nullptr;
UE_LOG(
LogGameplayAbility,
Warning,
TEXT(
"%s: Attempted to EndAbility when FollowCursorAbilityTask was still active. Should have already been cleaned up in CancelAbility or regular execution."
),
*GetFullNameSafe(this)
);
}
if (IsValid(MoveCharacterToCursorAbilityTask) && MoveCharacterToCursorAbilityTask->IsActive())
{
MoveCharacterToCursorAbilityTask->EndTask();
MoveCharacterToCursorAbilityTask = nullptr;
UE_LOG(
LogGameplayAbility,
Warning,
TEXT(
"%s: Attempted to EndAbility when MoveCharacterToCursorAbilityTask was still active. Should have already been cleaned up in CancelAbility or regular execution."
),
*GetFullNameSafe(this)
);
}
Super::EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled);
}
void UIAGA_PlayerMove::HandleInputReleased_Implementation(
const FGameplayAbilitySpecHandle& Handle,
const FGameplayAbilityActorInfo& ActorInfo,
const FGameplayAbilityActivationInfo& ActivationInfo
)
{
if (IsValid(FollowCursorAbilityTask) && FollowCursorAbilityTask->IsActive())
{
FollowCursorAbilityTask->ExternalCancel();
FollowCursorAbilityTask = nullptr;
}
MoveCharacterToCursorAbilityTask = UAbilityTask_MoveCharacterToCursor::MoveCharacterToCursor(this, NAME_None);
MoveCharacterToCursorAbilityTask->OnMoveComplete.AddDynamic(this, &ThisClass::HandleOnMoveComplete);
MoveCharacterToCursorAbilityTask->ReadyForActivation();
if (!MoveVFXCueTag.IsValid())
{
UE_LOG(
LogGameplayAbility,
Warning,
TEXT(
"%s: Attempted to raise an invalid MoveVFX GameplayCue in HandledInputReleased."
),
*GetFullNameSafe(this)
);
return;
}
FGameplayCueParameters MoveVFXCueParams = FGameplayCueParameters();
MoveVFXCueParams.Location = MoveCharacterToCursorAbilityTask->GetTargetLocation();
K2_ExecuteGameplayCueWithParams(MoveVFXCueTag, MoveVFXCueParams);
}
void UIAGA_PlayerMove::HandleOnMoveComplete(const EPathFollowingResult::Type PathingResultType)
{
if (!ensure(IsValid(MoveCharacterToCursorAbilityTask) && MoveCharacterToCursorAbilityTask->IsActive()))
{
UE_LOG(
LogGameplayAbility,
Warning,
TEXT(
"%s: Attempted to HandleOnMoveComplete when not in Phase 2."
),
*GetFullNameSafe(this)
);
K2_CancelAbility();
return;
}
if (PathingResultType != EPathFollowingResult::Type::Success)
{
MoveCharacterToCursorAbilityTask->ExternalCancel();
MoveCharacterToCursorAbilityTask = nullptr;
K2_CancelAbility(); // Using latent version because can't bind params in a lambda.
return;
}
MoveCharacterToCursorAbilityTask->EndTask();
MoveCharacterToCursorAbilityTask = nullptr;
K2_EndAbility(); // Using latent version because can't bind params in a lambda.
}
IAGA_PlayerMove.cpp - Snippet hosted by \"Cacher\"
");