Implemented OLSGameplayAbility.
Implemented OLSCollisionChannels. Implemented OLSGameplayEffectContext. Implemented OLSPhysicalMaterialWithTags.
This commit is contained in:
parent
2c4a71b343
commit
c0b033fb22
@ -2,3 +2,549 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "AbilitySystem/Abilities/OLSGameplayAbility.h"
|
#include "AbilitySystem/Abilities/OLSGameplayAbility.h"
|
||||||
|
|
||||||
|
#include "OLSLog.h"
|
||||||
|
#include "AbilitySystem/OLSAbilitySimpleFailureMessage.h"
|
||||||
|
#include "AbilitySystem/OLSAbilitySystemComponent.h"
|
||||||
|
#include "AbilitySystem/Abilities/OLSAbilityCost.h"
|
||||||
|
#include "AbilitySystemBlueprintLibrary.h"
|
||||||
|
#include "AbilitySystemGlobals.h"
|
||||||
|
#include "AbilitySystem/OLSGameplayEffectContext.h"
|
||||||
|
#include "AbilitySystem/Interfaces/OLSAbilitySourceInterface.h"
|
||||||
|
#include "Components/OLSHeroComponent.h"
|
||||||
|
#include "GameFramework/GameplayMessageSubsystem.h"
|
||||||
|
#include "Physics/OLSPhysicalMaterialWithTags.h"
|
||||||
|
|
||||||
|
#include UE_INLINE_GENERATED_CPP_BY_NAME(OLSGameplayAbility)
|
||||||
|
|
||||||
|
DEFINE_LOG_CATEGORY(LogOLSGameplayAbility);
|
||||||
|
|
||||||
|
#define ENSURE_ABILITY_IS_INSTANTIATED_OR_RETURN(FunctionName, ReturnValue) \
|
||||||
|
{ \
|
||||||
|
if (!ensure(IsInstantiated())) \
|
||||||
|
{ \
|
||||||
|
OLS_LOG(LogOLSGameplayAbility, Error, TEXT("%s: " #FunctionName " cannot be called on a non-instanced ability. Check the instancing policy."), *GetPathName()); \
|
||||||
|
return ReturnValue; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
UE_DEFINE_GAMEPLAY_TAG(TAG_ABILITY_SIMPLE_FAILURE_MESSAGE, "Ability.UserFacingSimpleActivateFail.Message");
|
||||||
|
UE_DEFINE_GAMEPLAY_TAG(TAG_ABILITY_PLAY_MONTAGE_FAILURE_MESSAGE, "Ability.PlayMontageOnActivateFail.Message");
|
||||||
|
|
||||||
|
UOLSGameplayAbility::UOLSGameplayAbility(const FObjectInitializer& objectInitializer) : Super(objectInitializer)
|
||||||
|
{
|
||||||
|
ReplicationPolicy = EGameplayAbilityReplicationPolicy::ReplicateNo;
|
||||||
|
InstancingPolicy = EGameplayAbilityInstancingPolicy::InstancedPerActor;
|
||||||
|
NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::LocalPredicted;
|
||||||
|
NetSecurityPolicy = EGameplayAbilityNetSecurityPolicy::ClientOrServer;
|
||||||
|
|
||||||
|
ActivationPolicy = EOLSAbilityActivationPolicy::OnInputTriggered;
|
||||||
|
ActivationGroup = EOLSAbilityActivationGroup::Independent;
|
||||||
|
|
||||||
|
bShouldLogCancellation = false;
|
||||||
|
|
||||||
|
// @TODO: Implement OLSCameraMode.
|
||||||
|
// ActiveCameraMode = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UOLSGameplayAbility::CanActivateAbility(const FGameplayAbilitySpecHandle handle,
|
||||||
|
const FGameplayAbilityActorInfo* actorInfo,
|
||||||
|
const FGameplayTagContainer* sourceTags,
|
||||||
|
const FGameplayTagContainer* targetTags,
|
||||||
|
FGameplayTagContainer* optionalRelevantTags) const
|
||||||
|
{
|
||||||
|
if (!actorInfo || !actorInfo->AbilitySystemComponent.IsValid())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Super::CanActivateAbility(handle, actorInfo, sourceTags, targetTags, optionalRelevantTags))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@TODO Possibly remove after setting up tag relationships
|
||||||
|
UOLSAbilitySystemComponent* asc = CastChecked<UOLSAbilitySystemComponent>(actorInfo->AbilitySystemComponent.Get());
|
||||||
|
if (asc->IsActivationGroupBlocked(ActivationGroup))
|
||||||
|
{
|
||||||
|
if (optionalRelevantTags)
|
||||||
|
{
|
||||||
|
// @TODO: Implement LyraGameplayTags::Ability_ActivateFail_ActivationGroup.
|
||||||
|
// optionalRelevantTags->AddTag(LyraGameplayTags::Ability_ActivateFail_ActivationGroup);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::SetCanBeCanceled(bool canBeCanceled)
|
||||||
|
{
|
||||||
|
// The ability can not block canceling if it's replaceable.
|
||||||
|
if (!canBeCanceled && (ActivationGroup == EOLSAbilityActivationGroup::Exclusive_Replaceable))
|
||||||
|
{
|
||||||
|
OLS_LOG(LogOLSGameplayAbility, Error,
|
||||||
|
TEXT(
|
||||||
|
"Ability [%s] can not block canceling because its activation group is replaceable."
|
||||||
|
), *GetName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Super::SetCanBeCanceled(canBeCanceled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::OnGiveAbility(const FGameplayAbilityActorInfo* actorInfo, const FGameplayAbilitySpec& spec)
|
||||||
|
{
|
||||||
|
Super::OnGiveAbility(actorInfo, spec);
|
||||||
|
|
||||||
|
K2_OnAbilityAdded();
|
||||||
|
|
||||||
|
TryActivateAbilityOnSpawn(actorInfo, spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::OnRemoveAbility(const FGameplayAbilityActorInfo* actorInfo, const FGameplayAbilitySpec& spec)
|
||||||
|
{
|
||||||
|
K2_OnAbilityRemoved();
|
||||||
|
|
||||||
|
Super::OnRemoveAbility(actorInfo, spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::ActivateAbility(const FGameplayAbilitySpecHandle Handle,
|
||||||
|
const FGameplayAbilityActorInfo* ActorInfo,
|
||||||
|
const FGameplayAbilityActivationInfo ActivationInfo,
|
||||||
|
const FGameplayEventData* TriggerEventData)
|
||||||
|
{
|
||||||
|
Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::EndAbility(const FGameplayAbilitySpecHandle Handle,
|
||||||
|
const FGameplayAbilityActorInfo* ActorInfo,
|
||||||
|
const FGameplayAbilityActivationInfo ActivationInfo,
|
||||||
|
bool bReplicateEndAbility, bool bWasCancelled)
|
||||||
|
{
|
||||||
|
// @TODO: Implement UOLSCameraMode.
|
||||||
|
// ClearCameraMode();
|
||||||
|
Super::EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UOLSGameplayAbility::CheckCost(const FGameplayAbilitySpecHandle handle,
|
||||||
|
const FGameplayAbilityActorInfo* actorInfo,
|
||||||
|
FGameplayTagContainer* optionalRelevantTags) const
|
||||||
|
{
|
||||||
|
if (!Super::CheckCost(handle, actorInfo, optionalRelevantTags) || !actorInfo)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify we can afford any additional costs
|
||||||
|
for (const TObjectPtr<UOLSAbilityCost>& additionalCost : AdditionalCosts)
|
||||||
|
{
|
||||||
|
if (additionalCost)
|
||||||
|
{
|
||||||
|
if (!additionalCost->CheckCost(this, handle, actorInfo, /*inout*/ optionalRelevantTags))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::ApplyCost(const FGameplayAbilitySpecHandle handle,
|
||||||
|
const FGameplayAbilityActorInfo* actorInfo,
|
||||||
|
const FGameplayAbilityActivationInfo activationInfo) const
|
||||||
|
{
|
||||||
|
check(actorInfo);
|
||||||
|
|
||||||
|
// Used to determine if the ability actually hit a target (as some costs are only spent on successful attempts)
|
||||||
|
auto determineIfAbilityHitTarget = [&]()
|
||||||
|
{
|
||||||
|
if (actorInfo->IsNetAuthority())
|
||||||
|
{
|
||||||
|
if (UOLSAbilitySystemComponent* ASC = Cast<UOLSAbilitySystemComponent>(actorInfo->AbilitySystemComponent.Get()))
|
||||||
|
{
|
||||||
|
FGameplayAbilityTargetDataHandle targetData;
|
||||||
|
ASC->GetAbilityTargetData(handle, activationInfo, targetData);
|
||||||
|
for (int32 targetDataIdx = 0; targetDataIdx < targetData.Data.Num(); ++targetDataIdx)
|
||||||
|
{
|
||||||
|
if (UAbilitySystemBlueprintLibrary::TargetDataHasHitResult(targetData, targetDataIdx))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pay any additional costs
|
||||||
|
bool hasAbilityHitTarget = false;
|
||||||
|
bool hasDeterminedIfAbilityHitTarget = false;
|
||||||
|
for (const TObjectPtr<UOLSAbilityCost>& additionalCost : AdditionalCosts)
|
||||||
|
{
|
||||||
|
if (additionalCost)
|
||||||
|
{
|
||||||
|
if (additionalCost->ShouldOnlyApplyCostOnHit())
|
||||||
|
{
|
||||||
|
if (!hasDeterminedIfAbilityHitTarget)
|
||||||
|
{
|
||||||
|
hasAbilityHitTarget = determineIfAbilityHitTarget();
|
||||||
|
hasDeterminedIfAbilityHitTarget = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAbilityHitTarget)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
additionalCost->ApplyCost(this, handle, actorInfo, activationInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FGameplayEffectContextHandle UOLSGameplayAbility::MakeEffectContext(const FGameplayAbilitySpecHandle handle,
|
||||||
|
const FGameplayAbilityActorInfo* actorInfo) const
|
||||||
|
{
|
||||||
|
FGameplayEffectContextHandle contextHandle = Super::MakeEffectContext(handle, actorInfo);
|
||||||
|
|
||||||
|
FOLSGameplayEffectContext* effectContext = FOLSGameplayEffectContext::ExtractEffectContext(contextHandle);
|
||||||
|
check(effectContext);
|
||||||
|
|
||||||
|
check(actorInfo);
|
||||||
|
|
||||||
|
AActor* effectCauser = nullptr;
|
||||||
|
const IOLSAbilitySourceInterface* abilitySource = nullptr;
|
||||||
|
float sourceLevel = 0.0f;
|
||||||
|
GetAbilitySource(handle, actorInfo, /*out*/ sourceLevel, /*out*/ abilitySource, /*out*/ effectCauser);
|
||||||
|
|
||||||
|
UObject* sourceObject = GetSourceObject(handle, actorInfo);
|
||||||
|
|
||||||
|
AActor* instigator = actorInfo ? actorInfo->OwnerActor.Get() : nullptr;
|
||||||
|
|
||||||
|
effectContext->SetAbilitySource(abilitySource, sourceLevel);
|
||||||
|
effectContext->AddInstigator(instigator, effectCauser);
|
||||||
|
effectContext->AddSourceObject(sourceObject);
|
||||||
|
|
||||||
|
return contextHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::ApplyAbilityTagsToGameplayEffectSpec(FGameplayEffectSpec& spec,
|
||||||
|
FGameplayAbilitySpec* abilitySpec) const
|
||||||
|
{
|
||||||
|
Super::ApplyAbilityTagsToGameplayEffectSpec(spec, abilitySpec);
|
||||||
|
|
||||||
|
if (const FHitResult* hitResult = spec.GetContext().GetHitResult())
|
||||||
|
{
|
||||||
|
if (const UOLSPhysicalMaterialWithTags* physMatWithTags = Cast<const UOLSPhysicalMaterialWithTags>(hitResult->PhysMaterial.Get()))
|
||||||
|
{
|
||||||
|
spec.CapturedTargetTags.GetSpecTags().AppendTags(physMatWithTags->Tags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UOLSGameplayAbility::DoesAbilitySatisfyTagRequirements(const UAbilitySystemComponent& abilitySystemComponent,
|
||||||
|
const FGameplayTagContainer* sourceTags,
|
||||||
|
const FGameplayTagContainer* targetTags,
|
||||||
|
FGameplayTagContainer* optionalRelevantTags) const
|
||||||
|
{
|
||||||
|
// Specialized version to handle death exclusion and AbilityTags expansion via ASC
|
||||||
|
|
||||||
|
bool isBlocked = false;
|
||||||
|
bool isMissing = false;
|
||||||
|
|
||||||
|
UAbilitySystemGlobals& abilitySystemGlobals = UAbilitySystemGlobals::Get();
|
||||||
|
const FGameplayTag& blockedTag = abilitySystemGlobals.ActivateFailTagsBlockedTag;
|
||||||
|
const FGameplayTag& missingTag = abilitySystemGlobals.ActivateFailTagsMissingTag;
|
||||||
|
|
||||||
|
// Check if any of this ability's tags are currently blocked
|
||||||
|
if (abilitySystemComponent.AreAbilityTagsBlocked(GetAssetTags()))
|
||||||
|
{
|
||||||
|
isBlocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const UOLSAbilitySystemComponent* asc = Cast<UOLSAbilitySystemComponent>(&abilitySystemComponent);
|
||||||
|
static FGameplayTagContainer allRequiredTags;
|
||||||
|
static FGameplayTagContainer allBlockedTags;
|
||||||
|
|
||||||
|
allRequiredTags = ActivationRequiredTags;
|
||||||
|
allBlockedTags = ActivationBlockedTags;
|
||||||
|
|
||||||
|
// Expand our ability tags to add additional required/blocked tags
|
||||||
|
if (asc)
|
||||||
|
{
|
||||||
|
asc->GetAdditionalActivationTagRequirements(GetAssetTags(), allRequiredTags, allBlockedTags);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see the required/blocked tags for this ability
|
||||||
|
if (allBlockedTags.Num() || allRequiredTags.Num())
|
||||||
|
{
|
||||||
|
static FGameplayTagContainer abilitySystemComponentTags;
|
||||||
|
|
||||||
|
abilitySystemComponentTags.Reset();
|
||||||
|
abilitySystemComponent.GetOwnedGameplayTags(abilitySystemComponentTags);
|
||||||
|
|
||||||
|
if (abilitySystemComponentTags.HasAny(allBlockedTags))
|
||||||
|
{
|
||||||
|
// @TODO: Implement LyraGameplayTags::Status_Death.
|
||||||
|
// @TODO: Implement LyraGameplayTags::Ability_ActivateFail_IsDead.
|
||||||
|
// if (optionalRelevantTags && abilitySystemComponentTags.HasTag(LyraGameplayTags::Status_Death))
|
||||||
|
// {
|
||||||
|
// // If player is dead and was rejected due to blocking tags, give that feedback
|
||||||
|
// optionalRelevantTags->AddTag(LyraGameplayTags::Ability_ActivateFail_IsDead);
|
||||||
|
// }
|
||||||
|
|
||||||
|
isBlocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!abilitySystemComponentTags.HasAll(allRequiredTags))
|
||||||
|
{
|
||||||
|
isMissing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceTags != nullptr)
|
||||||
|
{
|
||||||
|
if (SourceBlockedTags.Num() || SourceRequiredTags.Num())
|
||||||
|
{
|
||||||
|
if (sourceTags->HasAny(SourceBlockedTags))
|
||||||
|
{
|
||||||
|
isBlocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sourceTags->HasAll(SourceRequiredTags))
|
||||||
|
{
|
||||||
|
isMissing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetTags != nullptr)
|
||||||
|
{
|
||||||
|
if (TargetBlockedTags.Num() || TargetRequiredTags.Num())
|
||||||
|
{
|
||||||
|
if (targetTags->HasAny(TargetBlockedTags))
|
||||||
|
{
|
||||||
|
isBlocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetTags->HasAll(TargetRequiredTags))
|
||||||
|
{
|
||||||
|
isMissing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBlocked)
|
||||||
|
{
|
||||||
|
if (optionalRelevantTags && blockedTag.IsValid())
|
||||||
|
{
|
||||||
|
optionalRelevantTags->AddTag(blockedTag);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (isMissing)
|
||||||
|
{
|
||||||
|
if (optionalRelevantTags && missingTag.IsValid())
|
||||||
|
{
|
||||||
|
optionalRelevantTags->AddTag(missingTag);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
UOLSAbilitySystemComponent* UOLSGameplayAbility::GetOLSAbilitySystemComponentFromActorInfo() const
|
||||||
|
{
|
||||||
|
return (CurrentActorInfo ? Cast<UOLSAbilitySystemComponent>(CurrentActorInfo->AbilitySystemComponent.Get()) : nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
AController* UOLSGameplayAbility::GetControllerFromActorInfo() const
|
||||||
|
{
|
||||||
|
if (CurrentActorInfo)
|
||||||
|
{
|
||||||
|
if (AController* controller = CurrentActorInfo->PlayerController.Get())
|
||||||
|
{
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for a player controller or pawn in the owner chain.
|
||||||
|
AActor* testActor = CurrentActorInfo->OwnerActor.Get();
|
||||||
|
while (testActor)
|
||||||
|
{
|
||||||
|
if (AController* controller = Cast<AController>(testActor))
|
||||||
|
{
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (APawn* pawn = Cast<APawn>(testActor))
|
||||||
|
{
|
||||||
|
return pawn->GetController();
|
||||||
|
}
|
||||||
|
|
||||||
|
testActor = testActor->GetOwner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
UOLSHeroComponent* UOLSGameplayAbility::GetHeroComponentFromActorInfo() const
|
||||||
|
{
|
||||||
|
return (CurrentActorInfo ? UOLSHeroComponent::FindHeroComponent(CurrentActorInfo->AvatarActor.Get()) : nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UOLSGameplayAbility::CanChangeActivationGroup(EOLSAbilityActivationGroup newGroup) const
|
||||||
|
{
|
||||||
|
if (!IsInstantiated() || !IsActive())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ActivationGroup == newGroup)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
UOLSAbilitySystemComponent* asc = GetOLSAbilitySystemComponentFromActorInfo();
|
||||||
|
check(asc);
|
||||||
|
|
||||||
|
if ((ActivationGroup != EOLSAbilityActivationGroup::Exclusive_Blocking) && asc->IsActivationGroupBlocked(newGroup))
|
||||||
|
{
|
||||||
|
// This ability can't change groups if it's blocked (unless it is the one doing the blocking).
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((newGroup == EOLSAbilityActivationGroup::Exclusive_Replaceable) && !CanBeCanceled())
|
||||||
|
{
|
||||||
|
// This ability can't become replaceable if it can't be canceled.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UOLSGameplayAbility::ChangeActivationGroup(EOLSAbilityActivationGroup newGroup)
|
||||||
|
{
|
||||||
|
ENSURE_ABILITY_IS_INSTANTIATED_OR_RETURN(ChangeActivationGroup, false);
|
||||||
|
|
||||||
|
if (!CanChangeActivationGroup(newGroup))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ActivationGroup != newGroup)
|
||||||
|
{
|
||||||
|
UOLSAbilitySystemComponent* asc = GetOLSAbilitySystemComponentFromActorInfo();
|
||||||
|
check(asc);
|
||||||
|
|
||||||
|
asc->RemoveAbilityFromActivationGroup(ActivationGroup, this);
|
||||||
|
asc->AddAbilityToActivationGroup(newGroup, this);
|
||||||
|
|
||||||
|
ActivationGroup = newGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLSAbilityActivationPolicy UOLSGameplayAbility::GetActivationPolicy() const
|
||||||
|
{
|
||||||
|
return ActivationPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLSAbilityActivationGroup UOLSGameplayAbility::GetActivationGroup() const
|
||||||
|
{
|
||||||
|
return ActivationGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::TryActivateAbilityOnSpawn(const FGameplayAbilityActorInfo* actorInfo,
|
||||||
|
const FGameplayAbilitySpec& spec) const
|
||||||
|
{
|
||||||
|
// Try to activate if activation policy is on spawn.
|
||||||
|
if (actorInfo && !spec.IsActive() && (ActivationPolicy == EOLSAbilityActivationPolicy::OnSpawn))
|
||||||
|
{
|
||||||
|
UAbilitySystemComponent* asc = actorInfo->AbilitySystemComponent.Get();
|
||||||
|
const AActor* avatarActor = actorInfo->AvatarActor.Get();
|
||||||
|
|
||||||
|
// If avatar actor is torn off or about to die, don't try to activate until we get the new one.
|
||||||
|
if (asc && avatarActor && !avatarActor->GetTearOff() && (avatarActor->GetLifeSpan() <= 0.0f))
|
||||||
|
{
|
||||||
|
const bool isLocalExecution = (NetExecutionPolicy == EGameplayAbilityNetExecutionPolicy::LocalPredicted) || (NetExecutionPolicy == EGameplayAbilityNetExecutionPolicy::LocalOnly);
|
||||||
|
const bool iServerExecution = (NetExecutionPolicy == EGameplayAbilityNetExecutionPolicy::ServerOnly) || (NetExecutionPolicy == EGameplayAbilityNetExecutionPolicy::ServerInitiated);
|
||||||
|
|
||||||
|
const bool shouldClientActivate = actorInfo->IsLocallyControlled() && isLocalExecution;
|
||||||
|
const bool shouldServerActivate = actorInfo->IsNetAuthority() && iServerExecution;
|
||||||
|
|
||||||
|
if (shouldClientActivate || shouldServerActivate)
|
||||||
|
{
|
||||||
|
asc->TryActivateAbility(spec.Handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::OnAbilityFailedToActivate(const FGameplayTagContainer& failedReason) const
|
||||||
|
{
|
||||||
|
NativeOnAbilityFailedToActivate(failedReason);
|
||||||
|
K2_OnAbilityFailedToActivate(failedReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::OnPawnAvatarSet()
|
||||||
|
{
|
||||||
|
K2_OnPawnAvatarSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::GetAbilitySource(FGameplayAbilitySpecHandle handle,
|
||||||
|
const FGameplayAbilityActorInfo* actorInfo,
|
||||||
|
float& outSourceLevel,
|
||||||
|
const IOLSAbilitySourceInterface*& outAbilitySource,
|
||||||
|
AActor*& outEffectCauser) const
|
||||||
|
{
|
||||||
|
outSourceLevel = 0.0f;
|
||||||
|
outAbilitySource = nullptr;
|
||||||
|
outEffectCauser = nullptr;
|
||||||
|
|
||||||
|
outEffectCauser = actorInfo->AvatarActor.Get();
|
||||||
|
|
||||||
|
// If we were added by something that's an ability info source, use it
|
||||||
|
UObject* sourceObject = GetSourceObject(handle, actorInfo);
|
||||||
|
|
||||||
|
outAbilitySource = Cast<IOLSAbilitySourceInterface>(sourceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSGameplayAbility::NativeOnAbilityFailedToActivate(const FGameplayTagContainer& failedReason) const
|
||||||
|
{
|
||||||
|
bool simpleFailureFound = false;
|
||||||
|
for (FGameplayTag reason : failedReason)
|
||||||
|
{
|
||||||
|
if (!simpleFailureFound)
|
||||||
|
{
|
||||||
|
if (const FText* pUserFacingMessage = FailureTagToUserFacingMessages.Find(reason))
|
||||||
|
{
|
||||||
|
FOLSAbilitySimpleFailureMessage message;
|
||||||
|
message.PlayerController = GetActorInfo().PlayerController.Get();
|
||||||
|
message.FailureTags = failedReason;
|
||||||
|
message.UserFacingReason = *pUserFacingMessage;
|
||||||
|
|
||||||
|
UGameplayMessageSubsystem& messageSystem = UGameplayMessageSubsystem::Get(GetWorld());
|
||||||
|
messageSystem.BroadcastMessage(TAG_ABILITY_SIMPLE_FAILURE_MESSAGE, message);
|
||||||
|
simpleFailureFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UAnimMontage* montage = FailureTagToAnimMontage.FindRef(reason))
|
||||||
|
{
|
||||||
|
FOLSAbilityMontageFailureMessage message;
|
||||||
|
message.PlayerController = GetActorInfo().PlayerController.Get();
|
||||||
|
message.AvatarActor = GetActorInfo().AvatarActor.Get();
|
||||||
|
message.FailureTags = failedReason;
|
||||||
|
message.FailureMontage = montage;
|
||||||
|
|
||||||
|
UGameplayMessageSubsystem& messageSystem = UGameplayMessageSubsystem::Get(GetWorld());
|
||||||
|
messageSystem.BroadcastMessage(TAG_ABILITY_PLAY_MONTAGE_FAILURE_MESSAGE, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
||||||
|
|
||||||
|
|
||||||
|
#include "AbilitySystem/Interfaces/OLSAbilitySourceInterface.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Add default functionality here for any IOLSAbilitySourceInterface functions that are not pure virtual.
|
@ -0,0 +1,4 @@
|
|||||||
|
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
||||||
|
|
||||||
|
|
||||||
|
#include "AbilitySystem/OLSAbilitySimpleFailureMessage.h"
|
@ -661,6 +661,89 @@ void UOLSAbilitySystemComponent::ClearAbilityInput()
|
|||||||
InputHeldSpecHandles.Reset();
|
InputHeldSpecHandles.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UOLSAbilitySystemComponent::IsActivationGroupBlocked(EOLSAbilityActivationGroup Group) const
|
||||||
|
{
|
||||||
|
bool isBlocked = false;
|
||||||
|
|
||||||
|
switch (Group)
|
||||||
|
{
|
||||||
|
case EOLSAbilityActivationGroup::Independent:
|
||||||
|
// Independent abilities are never blocked.
|
||||||
|
isBlocked = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EOLSAbilityActivationGroup::Exclusive_Replaceable:
|
||||||
|
case EOLSAbilityActivationGroup::Exclusive_Blocking:
|
||||||
|
// Exclusive abilities can activate if nothing is blocking.
|
||||||
|
isBlocked = (ActivationGroupCounts[(uint8)EOLSAbilityActivationGroup::Exclusive_Blocking] > 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
checkf(false, TEXT("IsActivationGroupBlocked: Invalid ActivationGroup [%d]\n"), (uint8)Group);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isBlocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSAbilitySystemComponent::AddAbilityToActivationGroup(EOLSAbilityActivationGroup group,
|
||||||
|
UOLSGameplayAbility* ability)
|
||||||
|
{
|
||||||
|
check(ability);
|
||||||
|
check(ActivationGroupCounts[(uint8)group] < INT32_MAX);
|
||||||
|
|
||||||
|
ActivationGroupCounts[(uint8)group]++;
|
||||||
|
|
||||||
|
constexpr bool shouldReplicateCancelAbility = false;
|
||||||
|
|
||||||
|
switch (group)
|
||||||
|
{
|
||||||
|
case EOLSAbilityActivationGroup::Independent:
|
||||||
|
// Independent abilities do not cancel any other abilities.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EOLSAbilityActivationGroup::Exclusive_Replaceable:
|
||||||
|
case EOLSAbilityActivationGroup::Exclusive_Blocking:
|
||||||
|
CancelActivationGroupAbilities(EOLSAbilityActivationGroup::Exclusive_Replaceable, ability, shouldReplicateCancelAbility);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
checkf(false, TEXT("AddAbilityToActivationGroup: Invalid ActivationGroup [%d]\n"), (uint8)group);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int32 exclusiveCount = ActivationGroupCounts[static_cast<uint8>(
|
||||||
|
EOLSAbilityActivationGroup::Exclusive_Replaceable)] + ActivationGroupCounts[static_cast<uint8>(
|
||||||
|
EOLSAbilityActivationGroup::Exclusive_Blocking)];
|
||||||
|
if (!ensure(exclusiveCount <= 1))
|
||||||
|
{
|
||||||
|
OLS_LOG(LogOLSAbilitySystemComponent, Error,
|
||||||
|
TEXT("Multiple exclusive abilities are running."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSAbilitySystemComponent::RemoveAbilityFromActivationGroup(EOLSAbilityActivationGroup group,
|
||||||
|
UOLSGameplayAbility* ability)
|
||||||
|
{
|
||||||
|
check(ability);
|
||||||
|
check(ActivationGroupCounts[(uint8)group] > 0);
|
||||||
|
|
||||||
|
ActivationGroupCounts[(uint8)group]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UOLSAbilitySystemComponent::CancelActivationGroupAbilities(EOLSAbilityActivationGroup group,
|
||||||
|
UOLSGameplayAbility* ignoreAbility,
|
||||||
|
bool shouldReplicateCancelAbility)
|
||||||
|
{
|
||||||
|
auto shouldCancelFunc = [this, group, ignoreAbility](const UOLSGameplayAbility* ability,
|
||||||
|
FGameplayAbilitySpecHandle handle)
|
||||||
|
{
|
||||||
|
return ((ability->GetActivationGroup() == group) && (ability != ignoreAbility));
|
||||||
|
};
|
||||||
|
|
||||||
|
CancelAbilitiesByFunc(shouldCancelFunc, shouldReplicateCancelAbility);
|
||||||
|
}
|
||||||
|
|
||||||
void UOLSAbilitySystemComponent::AddDynamicTagGameplayEffect(const FGameplayTag& tag)
|
void UOLSAbilitySystemComponent::AddDynamicTagGameplayEffect(const FGameplayTag& tag)
|
||||||
{
|
{
|
||||||
const TSubclassOf<UGameplayEffect> dynamicTagGE = UOLSAssetManager::GetSubclass(UOLSGameDataAsset::Get().DynamicTagGameplayEffect);
|
const TSubclassOf<UGameplayEffect> dynamicTagGE = UOLSAssetManager::GetSubclass(UOLSGameDataAsset::Get().DynamicTagGameplayEffect);
|
||||||
@ -724,11 +807,13 @@ void UOLSAbilitySystemComponent::SetTagRelationshipMapping(UOLSAbilityTagRelatio
|
|||||||
|
|
||||||
void UOLSAbilitySystemComponent::GetAdditionalActivationTagRequirements(const FGameplayTagContainer& abilityTags,
|
void UOLSAbilitySystemComponent::GetAdditionalActivationTagRequirements(const FGameplayTagContainer& abilityTags,
|
||||||
FGameplayTagContainer& outActivationRequired,
|
FGameplayTagContainer& outActivationRequired,
|
||||||
FGameplayTagContainer& outActivationBlocked) const
|
FGameplayTagContainer& outActivationBlocked)
|
||||||
|
const
|
||||||
{
|
{
|
||||||
if (TagRelationshipMapping)
|
if (TagRelationshipMapping)
|
||||||
{
|
{
|
||||||
TagRelationshipMapping->GetRequiredAndBlockedActivationTags(abilityTags, &outActivationRequired, &outActivationBlocked);
|
TagRelationshipMapping->GetRequiredAndBlockedActivationTags(abilityTags, &outActivationRequired,
|
||||||
|
&outActivationBlocked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
||||||
|
|
||||||
|
|
||||||
|
#include "AbilitySystem/OLSGameplayEffectContext.h"
|
||||||
|
|
||||||
|
#if UE_WITH_IRIS
|
||||||
|
#include "Iris/ReplicationState/PropertyNetSerializerInfoRegistry.h"
|
||||||
|
#include "Serialization/GameplayEffectContextNetSerializer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "AbilitySystem/Interfaces/OLSAbilitySourceInterface.h"
|
||||||
|
|
||||||
|
#include UE_INLINE_GENERATED_CPP_BY_NAME(OLSGameplayEffectContext)
|
||||||
|
|
||||||
|
FOLSGameplayEffectContext* FOLSGameplayEffectContext::ExtractEffectContext(FGameplayEffectContextHandle handle)
|
||||||
|
{
|
||||||
|
FGameplayEffectContext* baseEffectContext = handle.Get();
|
||||||
|
if ((baseEffectContext != nullptr) && baseEffectContext->GetScriptStruct()->IsChildOf(StaticStruct()))
|
||||||
|
{
|
||||||
|
return static_cast<FOLSGameplayEffectContext*>(baseEffectContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FOLSGameplayEffectContext::SetAbilitySource(const IOLSAbilitySourceInterface* object, float sourceLevel)
|
||||||
|
{
|
||||||
|
AbilitySourceObject = MakeWeakObjectPtr(Cast<const UObject>(object));
|
||||||
|
//SourceLevel = sourceLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IOLSAbilitySourceInterface* FOLSGameplayEffectContext::GetAbilitySource() const
|
||||||
|
{
|
||||||
|
return Cast<IOLSAbilitySourceInterface>(AbilitySourceObject.Get());
|
||||||
|
}
|
||||||
|
|
||||||
|
FGameplayEffectContext* FOLSGameplayEffectContext::Duplicate() const
|
||||||
|
{
|
||||||
|
FOLSGameplayEffectContext* newContext = new FOLSGameplayEffectContext();
|
||||||
|
*newContext = *this;
|
||||||
|
if (GetHitResult())
|
||||||
|
{
|
||||||
|
// Does a deep copy of the hit result
|
||||||
|
newContext->AddHitResult(*GetHitResult(), true);
|
||||||
|
}
|
||||||
|
return newContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
UScriptStruct* FOLSGameplayEffectContext::GetScriptStruct() const
|
||||||
|
{
|
||||||
|
return FOLSGameplayEffectContext::StaticStruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FOLSGameplayEffectContext::NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess)
|
||||||
|
{
|
||||||
|
return FGameplayEffectContext::NetSerialize(Ar, Map, bOutSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
const UPhysicalMaterial* FOLSGameplayEffectContext::GetPhysicalMaterial() const
|
||||||
|
{
|
||||||
|
if (const FHitResult* hitResultPtr = GetHitResult())
|
||||||
|
{
|
||||||
|
return hitResultPtr->PhysMaterial.Get();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
@ -194,6 +194,11 @@ void UOLSHeroComponent::CheckDefaultInitialization()
|
|||||||
// ContinueInitStateChain(stateChain);
|
// ContinueInitStateChain(stateChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UOLSHeroComponent* UOLSHeroComponent::FindHeroComponent(const AActor* actor)
|
||||||
|
{
|
||||||
|
return (actor ? actor->FindComponentByClass<UOLSHeroComponent>() : nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void UOLSHeroComponent::ClearAbilityCameraMode(const FGameplayAbilitySpecHandle& owningSpecHandle)
|
void UOLSHeroComponent::ClearAbilityCameraMode(const FGameplayAbilitySpecHandle& owningSpecHandle)
|
||||||
{
|
{
|
||||||
if (AbilityCameraModeOwningSpecHandle == owningSpecHandle)
|
if (AbilityCameraModeOwningSpecHandle == owningSpecHandle)
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
||||||
|
|
||||||
|
|
||||||
|
#include "Physics/OLSPhysicalMaterialWithTags.h"
|
||||||
|
|
||||||
|
UOLSPhysicalMaterialWithTags::UOLSPhysicalMaterialWithTags(const FObjectInitializer& objectInitializer) : Super(objectInitializer)
|
||||||
|
{
|
||||||
|
}
|
@ -6,6 +6,8 @@
|
|||||||
#include "Abilities/GameplayAbility.h"
|
#include "Abilities/GameplayAbility.h"
|
||||||
#include "OLSGameplayAbility.generated.h"
|
#include "OLSGameplayAbility.generated.h"
|
||||||
|
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(LogOLSGameplayAbility, Verbose, All);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ELyraAbilityActivationPolicy
|
* ELyraAbilityActivationPolicy
|
||||||
*
|
*
|
||||||
@ -78,9 +80,88 @@ class OLS_API UOLSGameplayAbility : public UGameplayAbility
|
|||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
UOLSGameplayAbility(const FObjectInitializer& objectInitializer);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//~UGameplayAbility interface
|
||||||
|
virtual bool CanActivateAbility(const FGameplayAbilitySpecHandle handle, const FGameplayAbilityActorInfo* actorInfo, const FGameplayTagContainer* sourceTags, const FGameplayTagContainer* targetTags, FGameplayTagContainer* optionalRelevantTags) const override;
|
||||||
|
virtual void SetCanBeCanceled(bool canBeCanceled) override;
|
||||||
|
virtual void OnGiveAbility(const FGameplayAbilityActorInfo* actorInfo, const FGameplayAbilitySpec& spec) override;
|
||||||
|
virtual void OnRemoveAbility(const FGameplayAbilityActorInfo* actorInfo, const FGameplayAbilitySpec& spec) override;
|
||||||
|
virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;
|
||||||
|
virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled) override;
|
||||||
|
virtual bool CheckCost(const FGameplayAbilitySpecHandle handle, const FGameplayAbilityActorInfo* actorInfo, OUT FGameplayTagContainer* optionalRelevantTags = nullptr) const override;
|
||||||
|
virtual void ApplyCost(const FGameplayAbilitySpecHandle handle, const FGameplayAbilityActorInfo* actorInfo, const FGameplayAbilityActivationInfo activationInfo) const override;
|
||||||
|
virtual FGameplayEffectContextHandle MakeEffectContext(const FGameplayAbilitySpecHandle handle, const FGameplayAbilityActorInfo* actorInfo) const override;
|
||||||
|
virtual void ApplyAbilityTagsToGameplayEffectSpec(FGameplayEffectSpec& spec, FGameplayAbilitySpec* abilitySpec) const override;
|
||||||
|
virtual bool DoesAbilitySatisfyTagRequirements(const UAbilitySystemComponent& abilitySystemComponent, const FGameplayTagContainer* sourceTags = nullptr, const FGameplayTagContainer* targetTags = nullptr, OUT FGameplayTagContainer* optionalRelevantTags = nullptr) const override;
|
||||||
|
//~End of UGameplayAbility interface
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "OLS|Ability")
|
||||||
|
class UOLSAbilitySystemComponent* GetOLSAbilitySystemComponentFromActorInfo() const;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "OLS|Ability")
|
||||||
|
AController* GetControllerFromActorInfo() const;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Lyra|Ability")
|
||||||
|
class UOLSHeroComponent* GetHeroComponentFromActorInfo() const;
|
||||||
|
|
||||||
|
// Returns true if the requested activation group is a valid transition.
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "OLS|Ability", Meta = (ExpandBoolAsExecs = "ReturnValue"))
|
||||||
|
bool CanChangeActivationGroup(EOLSAbilityActivationGroup newGroup) const;
|
||||||
|
|
||||||
|
// Tries to change the activation group. Returns true if it successfully changed.
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "OLS|Ability", Meta = (ExpandBoolAsExecs = "ReturnValue"))
|
||||||
|
bool ChangeActivationGroup(EOLSAbilityActivationGroup newGroup);
|
||||||
|
|
||||||
|
// @TODO: Implement OLSCameraMode.
|
||||||
|
// // Sets the ability's camera mode.
|
||||||
|
// UFUNCTION(BlueprintCallable, Category = "Lyra|Ability")
|
||||||
|
// void SetCameraMode(TSubclassOf<ULyraCameraMode> CameraMode);
|
||||||
|
//
|
||||||
|
// // Clears the ability's camera mode. Automatically called if needed when the ability ends.
|
||||||
|
// UFUNCTION(BlueprintCallable, Category = "Lyra|Ability")
|
||||||
|
// void ClearCameraMode();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EOLSAbilityActivationPolicy GetActivationPolicy() const;
|
||||||
|
EOLSAbilityActivationGroup GetActivationGroup() const;
|
||||||
|
|
||||||
|
void TryActivateAbilityOnSpawn(const FGameplayAbilityActorInfo* actorInfo, const FGameplayAbilitySpec& spec) const;
|
||||||
|
|
||||||
|
void OnAbilityFailedToActivate(const FGameplayTagContainer& failedReason) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void OnPawnAvatarSet();
|
||||||
|
|
||||||
|
virtual void GetAbilitySource(FGameplayAbilitySpecHandle handle, const FGameplayAbilityActorInfo* actorInfo,
|
||||||
|
float& outSourceLevel, const class IOLSAbilitySourceInterface*& outAbilitySource,
|
||||||
|
AActor*& outEffectCauser) const;
|
||||||
|
|
||||||
|
// Called when the ability fails to activate
|
||||||
|
virtual void NativeOnAbilityFailedToActivate(const FGameplayTagContainer& failedReason) const;
|
||||||
|
|
||||||
|
// Called when the ability fails to activate
|
||||||
|
UFUNCTION(BlueprintImplementableEvent, DisplayName = "OnAbilityFailedToActivate")
|
||||||
|
void K2_OnAbilityFailedToActivate(const FGameplayTagContainer& FailedReason) const;
|
||||||
|
|
||||||
|
/** Called when this ability is granted to the ability system component. */
|
||||||
|
UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName = "OnAbilityAdded")
|
||||||
|
void K2_OnAbilityAdded();
|
||||||
|
|
||||||
|
/** Called when this ability is removed from the ability system component. */
|
||||||
|
UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName = "OnAbilityRemoved")
|
||||||
|
void K2_OnAbilityRemoved();
|
||||||
|
|
||||||
|
/** Called when the ability system is initialized with a pawn avatar. */
|
||||||
|
UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName = "OnPawnAvatarSet")
|
||||||
|
void K2_OnPawnAvatarSet();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Defines how this ability is meant to activate.
|
// Defines how this ability is meant to activate.
|
||||||
@ -107,6 +188,7 @@ protected:
|
|||||||
UPROPERTY(EditDefaultsOnly, Category = "Advanced")
|
UPROPERTY(EditDefaultsOnly, Category = "Advanced")
|
||||||
uint8 bShouldLogCancellation : 1 = false;
|
uint8 bShouldLogCancellation : 1 = false;
|
||||||
|
|
||||||
|
// @TODO: Implement OLSCameraMode
|
||||||
// Current camera mode set by the ability.
|
// Current camera mode set by the ability.
|
||||||
// TSubclassOf<ULyraCameraMode> ActiveCameraMode;
|
// TSubclassOf<OLSCameraMode> ActiveCameraMode;
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "GameplayTagContainer.h"
|
||||||
|
#include "OLSAbilitySourceInterface.generated.h"
|
||||||
|
|
||||||
|
// This class does not need to be modified.
|
||||||
|
UINTERFACE()
|
||||||
|
class UOLSAbilitySourceInterface : public UInterface
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class OLS_API IOLSAbilitySourceInterface
|
||||||
|
{
|
||||||
|
GENERATED_IINTERFACE_BODY()
|
||||||
|
/**
|
||||||
|
* Compute the multiplier for effect falloff with distance
|
||||||
|
* ABILITY_LOG
|
||||||
|
* @param distance Distance from source to target for ability calculations (distance bullet traveled for a gun, etc...)
|
||||||
|
* @param sourceTags Aggregated Tags from the source
|
||||||
|
* @param targetTags Aggregated Tags currently on the target
|
||||||
|
*
|
||||||
|
* @return Multiplier to apply to the base attribute value due to distance
|
||||||
|
*/
|
||||||
|
virtual float GetDistanceAttenuation(float distance, const FGameplayTagContainer* sourceTags = nullptr,
|
||||||
|
const FGameplayTagContainer* targetTags = nullptr) const = 0;
|
||||||
|
|
||||||
|
virtual float GetPhysicalMaterialAttenuation(const UPhysicalMaterial* physicalMaterial,
|
||||||
|
const FGameplayTagContainer* sourceTags = nullptr,
|
||||||
|
const FGameplayTagContainer* targetTags = nullptr) const = 0;
|
||||||
|
};
|
@ -0,0 +1,28 @@
|
|||||||
|
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "NativeGameplayTags.h"
|
||||||
|
#include "GameplayTagContainer.h"
|
||||||
|
|
||||||
|
#include "OLSAbilitySimpleFailureMessage.generated.h"
|
||||||
|
|
||||||
|
UE_DECLARE_GAMEPLAY_TAG_EXTERN(TAG_ABILITY_SIMPLE_FAILURE_MESSAGE);
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType)
|
||||||
|
struct FOLSAbilitySimpleFailureMessage
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintReadWrite)
|
||||||
|
TObjectPtr<class APlayerController> PlayerController = nullptr;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintReadWrite)
|
||||||
|
FGameplayTagContainer FailureTags;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintReadWrite)
|
||||||
|
FText UserFacingReason;
|
||||||
|
};
|
@ -5,6 +5,7 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "AbilitySystemComponent.h"
|
#include "AbilitySystemComponent.h"
|
||||||
#include "NativeGameplayTags.h"
|
#include "NativeGameplayTags.h"
|
||||||
|
#include "Abilities/OLSGameplayAbility.h"
|
||||||
#include "OLSAbilitySystemComponent.generated.h"
|
#include "OLSAbilitySystemComponent.generated.h"
|
||||||
|
|
||||||
DECLARE_LOG_CATEGORY_EXTERN(LogOLSAbilitySystemComponent, Verbose, All);
|
DECLARE_LOG_CATEGORY_EXTERN(LogOLSAbilitySystemComponent, Verbose, All);
|
||||||
@ -157,17 +158,17 @@ protected:
|
|||||||
virtual void AbilitySpecInputPressed(FGameplayAbilitySpec& spec) override;
|
virtual void AbilitySpecInputPressed(FGameplayAbilitySpec& spec) override;
|
||||||
virtual void AbilitySpecInputReleased(FGameplayAbilitySpec& spec) override;
|
virtual void AbilitySpecInputReleased(FGameplayAbilitySpec& spec) override;
|
||||||
|
|
||||||
virtual void NotifyAbilityActivated(const FGameplayAbilitySpecHandle handle, UGameplayAbility* ability) override;
|
virtual void NotifyAbilityActivated(const FGameplayAbilitySpecHandle handle, class UGameplayAbility* ability) override;
|
||||||
virtual void NotifyAbilityFailed(const FGameplayAbilitySpecHandle handle, UGameplayAbility* ability, const FGameplayTagContainer& failureReason) override;
|
virtual void NotifyAbilityFailed(const FGameplayAbilitySpecHandle handle, class UGameplayAbility* ability, const FGameplayTagContainer& failureReason) override;
|
||||||
virtual void NotifyAbilityEnded(FGameplayAbilitySpecHandle handle, UGameplayAbility* Ability, bool bWasCancelled) override;
|
virtual void NotifyAbilityEnded(FGameplayAbilitySpecHandle handle, class UGameplayAbility* Ability, bool bWasCancelled) override;
|
||||||
virtual void ApplyAbilityBlockAndCancelTags(const FGameplayTagContainer& abilityTags, UGameplayAbility* requestingAbility, bool shouldEnableBlockTags, const FGameplayTagContainer& blockTags, bool shouldExecuteCancelTags, const FGameplayTagContainer& cancelTags) override;
|
virtual void ApplyAbilityBlockAndCancelTags(const FGameplayTagContainer& abilityTags, class UGameplayAbility* requestingAbility, bool shouldEnableBlockTags, const FGameplayTagContainer& blockTags, bool shouldExecuteCancelTags, const FGameplayTagContainer& cancelTags) override;
|
||||||
virtual void HandleChangeAbilityCanBeCanceled(const FGameplayTagContainer& abilityTags, UGameplayAbility* requestingAbility, bool canBeCanceled) override;
|
virtual void HandleChangeAbilityCanBeCanceled(const FGameplayTagContainer& abilityTags, class UGameplayAbility* requestingAbility, bool canBeCanceled) override;
|
||||||
|
|
||||||
/** Notify client that an ability failed to activate */
|
/** Notify client that an ability failed to activate */
|
||||||
UFUNCTION(Client, Unreliable)
|
UFUNCTION(Client, Unreliable)
|
||||||
void ClientNotifyAbilityFailed(const UGameplayAbility* ability, const FGameplayTagContainer& failureReason);
|
void ClientNotifyAbilityFailed(const class UGameplayAbility* ability, const FGameplayTagContainer& failureReason);
|
||||||
|
|
||||||
void HandleAbilityFailed(const UGameplayAbility* ability, const FGameplayTagContainer& failureReason);
|
void HandleAbilityFailed(const class UGameplayAbility* ability, const FGameplayTagContainer& failureReason);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conveniently separates the code that sets the animation to replicate, so it can be further modified.
|
* Conveniently separates the code that sets the animation to replicate, so it can be further modified.
|
||||||
@ -176,7 +177,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef TFunctionRef<bool(const class UOLSGameplayAbility* ability, FGameplayAbilitySpecHandle handle)> TShouldCancelAbilityFunc;
|
typedef TFunctionRef<bool(const UOLSGameplayAbility* ability, FGameplayAbilitySpecHandle handle)> TShouldCancelAbilityFunc;
|
||||||
void CancelAbilitiesByFunc(TShouldCancelAbilityFunc shouldCancelFunc, bool shouldReplicateCancelAbility);
|
void CancelAbilitiesByFunc(TShouldCancelAbilityFunc shouldCancelFunc, bool shouldReplicateCancelAbility);
|
||||||
|
|
||||||
void CancelInputActivatedAbilities(bool shouldReplicateCancelAbility);
|
void CancelInputActivatedAbilities(bool shouldReplicateCancelAbility);
|
||||||
@ -187,11 +188,10 @@ public:
|
|||||||
void ProcessAbilityInput(float deltaTime, bool shouldGamePaused);
|
void ProcessAbilityInput(float deltaTime, bool shouldGamePaused);
|
||||||
void ClearAbilityInput();
|
void ClearAbilityInput();
|
||||||
|
|
||||||
// @TODO: Implement UOLSGameplayAbility.
|
bool IsActivationGroupBlocked(EOLSAbilityActivationGroup Group) const;
|
||||||
// bool IsActivationGroupBlocked(ELyraAbilityActivationGroup Group) const;
|
void AddAbilityToActivationGroup(EOLSAbilityActivationGroup group, UOLSGameplayAbility* ability);
|
||||||
// void AddAbilityToActivationGroup(ELyraAbilityActivationGroup Group, ULyraGameplayAbility* LyraAbility);
|
void RemoveAbilityFromActivationGroup(EOLSAbilityActivationGroup group, UOLSGameplayAbility* ability);
|
||||||
// void RemoveAbilityFromActivationGroup(ELyraAbilityActivationGroup Group, ULyraGameplayAbility* LyraAbility);
|
void CancelActivationGroupAbilities(EOLSAbilityActivationGroup group, UOLSGameplayAbility* ignoreAbility, bool shouldReplicateCancelAbility);
|
||||||
// void CancelActivationGroupAbilities(ELyraAbilityActivationGroup Group, ULyraGameplayAbility* IgnoreLyraAbility, bool bReplicateCancelAbility);
|
|
||||||
|
|
||||||
// Uses a gameplay effect to add the specified dynamic granted tag.
|
// Uses a gameplay effect to add the specified dynamic granted tag.
|
||||||
void AddDynamicTagGameplayEffect(const FGameplayTag& tag);
|
void AddDynamicTagGameplayEffect(const FGameplayTag& tag);
|
||||||
@ -208,8 +208,6 @@ public:
|
|||||||
/** Looks at ability tags and gathers additional required and blocking tags */
|
/** Looks at ability tags and gathers additional required and blocking tags */
|
||||||
void GetAdditionalActivationTagRequirements(const FGameplayTagContainer& abilityTags, FGameplayTagContainer& outActivationRequired, FGameplayTagContainer& outActivationBlocked) const;
|
void GetAdditionalActivationTagRequirements(const FGameplayTagContainer& abilityTags, FGameplayTagContainer& outActivationRequired, FGameplayTagContainer& outActivationBlocked) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "OLS Ability System", DisplayName = "Enable Ability Batch RPCs", meta = (AllowPrivateAccess = true))
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "OLS Ability System", DisplayName = "Enable Ability Batch RPCs", meta = (AllowPrivateAccess = true))
|
||||||
@ -229,4 +227,7 @@ protected:
|
|||||||
|
|
||||||
// Handles to abilities that have their input held.
|
// Handles to abilities that have their input held.
|
||||||
TArray<FGameplayAbilitySpecHandle> InputHeldSpecHandles;
|
TArray<FGameplayAbilitySpecHandle> InputHeldSpecHandles;
|
||||||
|
|
||||||
|
// Number of abilities running in each activation group.
|
||||||
|
int32 ActivationGroupCounts[(uint8)EOLSAbilityActivationGroup::MAX];
|
||||||
};
|
};
|
||||||
|
63
Source/ols/Public/AbilitySystem/OLSGameplayEffectContext.h
Normal file
63
Source/ols/Public/AbilitySystem/OLSGameplayEffectContext.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GameplayEffectTypes.h"
|
||||||
|
#include "OLSGameplayEffectContext.generated.h"
|
||||||
|
|
||||||
|
USTRUCT()
|
||||||
|
struct FOLSGameplayEffectContext : public FGameplayEffectContext
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
FOLSGameplayEffectContext()
|
||||||
|
: FGameplayEffectContext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLSGameplayEffectContext(AActor* InInstigator, AActor* InEffectCauser)
|
||||||
|
: FGameplayEffectContext(InInstigator, InEffectCauser)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the wrapped FLyraGameplayEffectContext from the handle, or nullptr if it doesn't exist or is the wrong type */
|
||||||
|
static OLS_API FOLSGameplayEffectContext* ExtractEffectContext(struct FGameplayEffectContextHandle handle);
|
||||||
|
|
||||||
|
/** Sets the object used as the ability source */
|
||||||
|
void SetAbilitySource(const class IOLSAbilitySourceInterface* object, float sourceLevel);
|
||||||
|
|
||||||
|
/** Returns the ability source interface associated with the source object. Only valid on the authority. */
|
||||||
|
const IOLSAbilitySourceInterface* GetAbilitySource() const;
|
||||||
|
|
||||||
|
virtual FGameplayEffectContext* Duplicate() const override;
|
||||||
|
|
||||||
|
virtual UScriptStruct* GetScriptStruct() const override;
|
||||||
|
|
||||||
|
/** Overridden to serialize new fields */
|
||||||
|
virtual bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) override;
|
||||||
|
|
||||||
|
/** Returns the physical material from the hit result if there is one */
|
||||||
|
const UPhysicalMaterial* GetPhysicalMaterial() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** ID to allow the identification of multiple bullets that were part of the same cartridge */
|
||||||
|
UPROPERTY()
|
||||||
|
int32 CartridgeID = -1;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/** Ability Source object (should implement ILyraAbilitySourceInterface). NOT replicated currently */
|
||||||
|
UPROPERTY()
|
||||||
|
TWeakObjectPtr<const UObject> AbilitySourceObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct TStructOpsTypeTraits<FOLSGameplayEffectContext> : public TStructOpsTypeTraitsBase2<FOLSGameplayEffectContext>
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
WithNetSerializer = true,
|
||||||
|
WithCopy = true
|
||||||
|
};
|
||||||
|
};
|
@ -39,6 +39,11 @@ public:
|
|||||||
/** The name of this component-implemented feature */
|
/** The name of this component-implemented feature */
|
||||||
static const FName NAME_ActorFeatureName;
|
static const FName NAME_ActorFeatureName;
|
||||||
|
|
||||||
|
/** Returns the hero component if one exists on the specified actor. */
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Lyra|Hero")
|
||||||
|
static UOLSHeroComponent* FindHeroComponent(const AActor* actor);
|
||||||
|
|
||||||
|
|
||||||
/** Overrides the camera from an active gameplay ability */
|
/** Overrides the camera from an active gameplay ability */
|
||||||
//@TODO: implement UOLSCameraMode.
|
//@TODO: implement UOLSCameraMode.
|
||||||
// void SetAbilityCameraMode(TSubclassOf<ULyraCameraMode> CameraMode, const FGameplayAbilitySpecHandle& OwningSpecHandle);
|
// void SetAbilityCameraMode(TSubclassOf<ULyraCameraMode> CameraMode, const FGameplayAbilitySpecHandle& OwningSpecHandle);
|
||||||
|
23
Source/ols/Public/Physics/OLSCollisionChannels.h
Normal file
23
Source/ols/Public/Physics/OLSCollisionChannels.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* when you modify this, please note that this information can be saved with instances
|
||||||
|
* also DefaultEngine.ini [/Script/Engine.CollisionProfile] should match with this list
|
||||||
|
**/
|
||||||
|
|
||||||
|
// Trace against Actors/Components which provide interactions.
|
||||||
|
#define OLS_TraceChannel_Interaction ECC_GameTraceChannel1
|
||||||
|
|
||||||
|
// Trace used by weapons, will hit physics assets instead of capsules
|
||||||
|
#define OLS_TraceChannel_Weapon ECC_GameTraceChannel2
|
||||||
|
|
||||||
|
// Trace used by by weapons, will hit pawn capsules instead of physics assets
|
||||||
|
#define OLS_TraceChannel_Weapon_Capsule ECC_GameTraceChannel3
|
||||||
|
|
||||||
|
// Trace used by by weapons, will trace through multiple pawns rather than stopping on the first hit
|
||||||
|
#define OLS_TraceChannel_Weapon_Multi ECC_GameTraceChannel4
|
||||||
|
|
||||||
|
// Allocated to aim assist by the ShooterCore game feature
|
||||||
|
// ECC_GameTraceChannel5
|
25
Source/ols/Public/Physics/OLSPhysicalMaterialWithTags.h
Normal file
25
Source/ols/Public/Physics/OLSPhysicalMaterialWithTags.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "GameplayTagContainer.h"
|
||||||
|
#include "PhysicalMaterials/PhysicalMaterial.h"
|
||||||
|
#include "OLSPhysicalMaterialWithTags.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class OLS_API UOLSPhysicalMaterialWithTags : public UPhysicalMaterial
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UOLSPhysicalMaterialWithTags(const FObjectInitializer& objectInitializer);
|
||||||
|
|
||||||
|
// A container of gameplay tags that game code can use to reason about this physical material
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=PhysicalProperties)
|
||||||
|
FGameplayTagContainer Tags;
|
||||||
|
};
|
@ -19,7 +19,11 @@ public class ols : ModuleRules
|
|||||||
"GameFeatures",
|
"GameFeatures",
|
||||||
"ModularGameplay",
|
"ModularGameplay",
|
||||||
"EnhancedInput",
|
"EnhancedInput",
|
||||||
"OLSAnimation", "AIModule", "CommonLoadingScreen", "CommonUser"
|
"OLSAnimation",
|
||||||
|
"AIModule",
|
||||||
|
"CommonLoadingScreen",
|
||||||
|
"CommonUser",
|
||||||
|
"PhysicsCore"
|
||||||
});
|
});
|
||||||
|
|
||||||
PrivateDependencyModuleNames.AddRange(new[]
|
PrivateDependencyModuleNames.AddRange(new[]
|
||||||
|
Loading…
Reference in New Issue
Block a user