/** The TargetActor we spawned locally has called back with valid target data */ void UAbilityTask_WaitTargetData::OnTargetDataReadyCallback(FGameplayAbilityTargetDataHandle Data) { check(AbilitySystemComponent); if (!Ability) { return; } FScopedPredictionWindow ScopedPrediction(AbilitySystemComponent, ShouldReplicateDataToServer()); const FGameplayAbilityActorInfo* Info = Ability->GetCurrentActorInfo(); if (IsPredictingClient()) { if (!TargetActor->ShouldProduceTargetDataOnServer) { FGameplayTag ApplicationTag; // Fixme: where would this be useful? AbilitySystemComponent->ServerSetReplicatedTargetData(GetAbilitySpecHandle(), GetActivationPredictionKey(), Data, ApplicationTag, AbilitySystemComponent->ScopedPredictionKey); } else if (ConfirmationType == EGameplayTargetingConfirmation::UserConfirmed) { // We aren't going to send the target data, but we will send a generic confirmed message. AbilitySystemComponent->ServerSetReplicatedEvent(EAbilityGenericReplicatedEvent::GenericConfirm, GetAbilitySpecHandle(), GetActivationPredictionKey(), AbilitySystemComponent->ScopedPredictionKey); } } ValidData.Broadcast(Data); if (ConfirmationType != EGameplayTargetingConfirmation::CustomMulti) { EndTask(); } }
/** Valid TargetData was replicated to use (we are server, was sent from client) */ void UAbilityTask_WaitTargetData::OnTargetDataReplicatedCallback(FGameplayAbilityTargetDataHandle Data) { check(AbilitySystemComponent.IsValid()); FScopedPredictionWindow ScopedPrediction(Ability.Get()); /** * Call into the TargetActor to sanitize/verify the data. If this returns false, we are rejecting * the replicated target data and will treat this as a cancel. * * This can also be used for bandwidth optimizations. OnReplicatedTargetDataReceived could do an actual * trace/check/whatever server side and use that data. So rather than having the client send that data * explicitly, the client is basically just sending a 'confirm' and the server is now going to do the work * in OnReplicatedTargetDataReceived. */ if (MyTargetActor.IsValid() && !MyTargetActor->OnReplicatedTargetDataReceived(Data)) { Cancelled.Broadcast(Data); } else { ValidData.Broadcast(Data); } if (ConfirmationType != EGameplayTargetingConfirmation::CustomMulti) { EndTask(); } }
void UAbilityTask_WaitCancel::OnLocalCancelCallback() { FScopedPredictionWindow ScopedPrediction(AbilitySystemComponent, IsPredictingClient()); if (AbilitySystemComponent && IsPredictingClient()) { AbilitySystemComponent->ServerSetReplicatedEvent(EAbilityGenericReplicatedEvent::GenericCancel, GetAbilitySpecHandle(), GetActivationPredictionKey() ,AbilitySystemComponent->ScopedPredictionKey); } OnCancelCallback(); }
/** The TargetActor we spawned locally has called back with valid target data */ void UAbilityTask_WaitTargetData::OnTargetDataReadyCallback(FGameplayAbilityTargetDataHandle Data) { check(AbilitySystemComponent.IsValid()); FScopedPredictionWindow ScopedPrediction(AbilitySystemComponent.Get(), ShouldReplicateDataToServer()); if (ShouldReplicateDataToServer()) { AbilitySystemComponent->ServerSetReplicatedTargetData(Data, AbilitySystemComponent->ScopedPredictionKey); } ValidData.Broadcast(Data); if (ConfirmationType != EGameplayTargetingConfirmation::CustomMulti) { EndTask(); } }