Created
May 21, 2022 12:54
-
-
Save KaosSpectrum/444c5d689278d5f01423f112820e2a7d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // (C)2022 InterKaos Games. | |
| #include "AbilitySystem/Tasks/AbilityTask_InputDirection.h" | |
| #include "EngineGlobals.h" | |
| #include "Engine/Engine.h" | |
| #include "AbilitySystemComponent.h" | |
| #include "AbilitySystem/Abilities/KaosGameplayAbility.h" | |
| #include "Pawn/KaosPawn.h" | |
| #include "Player/Controller/KaosPlayerController.h" | |
| UAbilityTask_InputDirection::UAbilityTask_InputDirection(const FObjectInitializer& ObjectInitializer) | |
| : Super(ObjectInitializer) | |
| { | |
| } | |
| UAbilityTask_InputDirection* UAbilityTask_InputDirection::GetInputDirection(UGameplayAbility* OwningAbility, FName TaskInstanceName) | |
| { | |
| UAbilityTask_InputDirection* MyObj = NewAbilityTask<UAbilityTask_InputDirection>(OwningAbility, TaskInstanceName); //Register for task list here, providing a given FName as a key | |
| return MyObj; | |
| } | |
| void UAbilityTask_InputDirection::Activate() | |
| { | |
| if (Ability) | |
| { | |
| RegisterTargetDataCallbacks(); | |
| ProduceDirection(); | |
| } | |
| else | |
| { | |
| EndTask(); | |
| } | |
| } | |
| void UAbilityTask_InputDirection::RegisterTargetDataCallbacks() | |
| { | |
| if (!ensure(IsValid(this))) | |
| { | |
| return; | |
| } | |
| check(Ability); | |
| const bool bIsLocallyControlled = Ability->GetCurrentActorInfo()->IsLocallyControlled(); | |
| // If not locally controlled (server for remote client), see if TargetData was already sent | |
| // else register callback for when it does get here. | |
| if (!bIsLocallyControlled) | |
| { | |
| // Register with the TargetData callbacks if we are expecting client to send them | |
| FGameplayAbilitySpecHandle SpecHandle = GetAbilitySpecHandle(); | |
| FPredictionKey ActivationPredictionKey = GetActivationPredictionKey(); | |
| //Since multifire is supported, we still need to hook up the callbacks | |
| AbilitySystemComponent->AbilityTargetDataSetDelegate(SpecHandle, ActivationPredictionKey).AddUObject(this, &UAbilityTask_InputDirection::OnTargetDataReplicatedCallback); | |
| AbilitySystemComponent->AbilityTargetDataCancelledDelegate(SpecHandle, ActivationPredictionKey).AddUObject(this, &UAbilityTask_InputDirection::OnTargetDataReplicatedCancelledCallback); | |
| AbilitySystemComponent->CallReplicatedTargetDataDelegatesIfSet(SpecHandle, ActivationPredictionKey); | |
| SetWaitingOnRemotePlayerData(); | |
| } | |
| } | |
| /** Valid TargetData was replicated to use (we are server, was sent from client) */ | |
| void UAbilityTask_InputDirection::OnTargetDataReplicatedCallback(const FGameplayAbilityTargetDataHandle& Data, FGameplayTag ActivationTag) | |
| { | |
| check(AbilitySystemComponent); | |
| FGameplayAbilityTargetDataHandle MutableData = Data; | |
| AbilitySystemComponent->ConsumeClientReplicatedTargetData(GetAbilitySpecHandle(), GetActivationPredictionKey()); | |
| if (ShouldBroadcastAbilityTaskDelegates()) | |
| { | |
| ValidData.Broadcast(MutableData); | |
| } | |
| EndTask(); | |
| } | |
| void UAbilityTask_InputDirection::OnTargetDataReplicatedCancelledCallback() | |
| { | |
| check(AbilitySystemComponent); | |
| if (ShouldBroadcastAbilityTaskDelegates()) | |
| { | |
| Cancelled.Broadcast(FGameplayAbilityTargetDataHandle()); | |
| } | |
| EndTask(); | |
| } | |
| void UAbilityTask_InputDirection::ProduceDirection() | |
| { | |
| check(AbilitySystemComponent); | |
| if (!Ability) | |
| { | |
| if (ShouldBroadcastAbilityTaskDelegates()) | |
| { | |
| Cancelled.Broadcast(FGameplayAbilityTargetDataHandle()); | |
| } | |
| EndTask(); | |
| return; | |
| } | |
| if (IsPredictingClient()) | |
| { | |
| FGameplayAbilityTargetDataHandle Data; | |
| FGameplayAbilityTargetData_LocationInfo* LocInfo = new FGameplayAbilityTargetData_LocationInfo(); | |
| UKaosGameplayAbility* KaosAbility = Cast<UKaosGameplayAbility>(Ability); | |
| AKaosPawn* KaosPawn = KaosAbility->GetKaosPawnFromActorInfo(); | |
| AKaosPlayerController* KaosPC = KaosAbility->GetKaosPlayerControllerFromActorInfo(KaosAbility->GetCurrentAbilitySpecHandle(), KaosAbility->GetCurrentActorInfo()); | |
| if (!KaosPC || !KaosPawn) | |
| { | |
| if (ShouldBroadcastAbilityTaskDelegates()) | |
| { | |
| Cancelled.Broadcast(FGameplayAbilityTargetDataHandle()); | |
| } | |
| EndTask(); | |
| return; | |
| } | |
| LocInfo->SourceLocation.LiteralTransform = FTransform(FRotator::ZeroRotator, KaosPawn->GetLastMovementInputVector(), KaosPC->PlayerCameraManager->GetActorForwardVector()); | |
| Data.Add(LocInfo); | |
| FScopedPredictionWindow ScopedPrediction(AbilitySystemComponent, true); | |
| const FGameplayAbilityActorInfo* Info = Ability->GetCurrentActorInfo(); | |
| FGameplayTag ApplicationTag; | |
| AbilitySystemComponent->CallServerSetReplicatedTargetData(GetAbilitySpecHandle(), GetActivationPredictionKey(), Data, ApplicationTag, AbilitySystemComponent->ScopedPredictionKey); | |
| if (ShouldBroadcastAbilityTaskDelegates()) | |
| { | |
| ValidData.Broadcast(Data); | |
| } | |
| EndTask(); | |
| } | |
| } | |
| /** Called when the ability is asked to confirm from an outside node. What this means depends on the individual task. By default, this does nothing other than ending if bEndTask is true. */ | |
| void UAbilityTask_InputDirection::ExternalConfirm(bool bEndTask) | |
| { | |
| check(AbilitySystemComponent); | |
| ProduceDirection(); | |
| Super::ExternalConfirm(bEndTask); | |
| } | |
| /** Called when the ability is asked to confirm from an outside node. What this means depends on the individual task. By default, this does nothing other than ending if bEndTask is true. */ | |
| void UAbilityTask_InputDirection::ExternalCancel() | |
| { | |
| check(AbilitySystemComponent); | |
| if (ShouldBroadcastAbilityTaskDelegates()) | |
| { | |
| Cancelled.Broadcast(FGameplayAbilityTargetDataHandle()); | |
| } | |
| Super::ExternalCancel(); | |
| } | |
| void UAbilityTask_InputDirection::OnDestroy(bool AbilityEnded) | |
| { | |
| Super::OnDestroy(AbilityEnded); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // (C)2022 InterKaos Games. | |
| #pragma once | |
| #include "CoreMinimal.h" | |
| #include "AbilitySystemComponent.h" | |
| #include "Abilities/Tasks/AbilityTask.h" | |
| #include "AbilityTask_InputDirection.generated.h" | |
| DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FKaosInputDirectionTargetDataDelegate, const FGameplayAbilityTargetDataHandle&, Data); | |
| /** | |
| * Gets the current input from the local player and its camera forward vector and spits out the location. | |
| * This is then replicated to server who waits for said data before continuing the ability. | |
| */ | |
| UCLASS() | |
| class KAOSGAME_API UAbilityTask_InputDirection : public UAbilityTask | |
| { | |
| GENERATED_UCLASS_BODY() | |
| UPROPERTY(BlueprintAssignable) | |
| FKaosInputDirectionTargetDataDelegate ValidData; | |
| UPROPERTY(BlueprintAssignable) | |
| FKaosInputDirectionTargetDataDelegate Cancelled; | |
| UFUNCTION() | |
| void OnTargetDataReplicatedCallback(const FGameplayAbilityTargetDataHandle& Data, FGameplayTag ActivationTag); | |
| UFUNCTION() | |
| void OnTargetDataReplicatedCancelledCallback(); | |
| void ProduceDirection(); | |
| /** Spawns target actor and waits for it to return valid data or to be canceled. */ | |
| UFUNCTION(BlueprintCallable, meta = (HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "true", HideSpawnParms = "Instigator"), Category = "Ability|Tasks") | |
| static UAbilityTask_InputDirection* GetInputDirection(UGameplayAbility* OwningAbility, FName TaskInstanceName); | |
| virtual void Activate() override; | |
| /** Called when the ability is asked to confirm from an outside node. What this means depends on the individual task. By default, this does nothing other than ending if bEndTask is true. */ | |
| virtual void ExternalConfirm(bool bEndTask) override; | |
| /** Called when the ability is asked to cancel from an outside node. What this means depends on the individual task. By default, this does nothing other than ending the task. */ | |
| virtual void ExternalCancel() override; | |
| protected: | |
| void RegisterTargetDataCallbacks(); | |
| virtual void OnDestroy(bool AbilityEnded) override; | |
| protected: | |
| FDelegateHandle OnTargetDataReplicatedCallbackDelegateHandle; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment