第一次提交
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "Utilities/GGA_GameplayEffectFunctionLibrary.h"
|
||||
#include "GameplayEffect.h"
|
||||
#include "Blueprint/BlueprintExceptionInfo.h"
|
||||
#include "UObject/EnumProperty.h"
|
||||
#include "GGA_GameplayEffectContext.h"
|
||||
#include "GGA_LogChannels.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "UGGA_GameplayEffectFunctionLibrary"
|
||||
|
||||
// UGameplayEffect* UGGA_GameplayEffectFunctionLibrary::MakeRuntimeGameplayEffect(FString UniqueName, EGameplayEffectDurationType DurationPolicy, TArray<FGameplayModifierInfo> AttributeModifiers)
|
||||
// {
|
||||
// UGameplayEffect* GameplayEffect = NewObject<UGameplayEffect>(GetTransientPackage(), FName("RuntimeGE_" + GetNameSafe(this) + UniqueName));
|
||||
// GameplayEffect->DurationPolicy = DurationPolicy;
|
||||
// GameplayEffect->Modifiers = AttributeModifiers;
|
||||
// return GameplayEffect;
|
||||
// }
|
||||
|
||||
float UGGA_GameplayEffectFunctionLibrary::GetSetByCallerMagnitudeByTag(FGameplayEffectSpecHandle SpecHandle, FGameplayTag DataTag, bool WarnIfNotFound, float DefaultIfNotFound)
|
||||
{
|
||||
FGameplayEffectSpec* Spec = SpecHandle.Data.Get();
|
||||
if (Spec)
|
||||
{
|
||||
return Spec->GetSetByCallerMagnitude(DataTag, WarnIfNotFound, DefaultIfNotFound);
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float UGGA_GameplayEffectFunctionLibrary::GetSetByCallerMagnitudeByTagFromSpec(const FGameplayEffectSpec& EffectSpec, FGameplayTag DataTag, bool WarnIfNotFound, float DefaultIfNotFound)
|
||||
{
|
||||
return EffectSpec.GetSetByCallerMagnitude(DataTag, WarnIfNotFound, DefaultIfNotFound);
|
||||
}
|
||||
|
||||
float UGGA_GameplayEffectFunctionLibrary::GetSetByCallerMagnitudeByName(FGameplayEffectSpecHandle SpecHandle, FName DataName)
|
||||
{
|
||||
FGameplayEffectSpec* Spec = SpecHandle.Data.Get();
|
||||
if (Spec)
|
||||
{
|
||||
return Spec->GetSetByCallerMagnitude(DataName, false);
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
bool UGGA_GameplayEffectFunctionLibrary::IsActiveGameplayEffectHandleValid(FActiveGameplayEffectHandle Handle)
|
||||
{
|
||||
return Handle.IsValid();
|
||||
}
|
||||
|
||||
void UGGA_GameplayEffectFunctionLibrary::GetOwnedGameplayTags(FGameplayEffectContextHandle EffectContext, FGameplayTagContainer& ActorTagContainer, FGameplayTagContainer& SpecTagContainer)
|
||||
{
|
||||
return EffectContext.GetOwnedGameplayTags(ActorTagContainer, SpecTagContainer);
|
||||
}
|
||||
|
||||
void UGGA_GameplayEffectFunctionLibrary::AddInstigator(FGameplayEffectContextHandle EffectContext, AActor* InInstigator, AActor* InEffectCauser)
|
||||
{
|
||||
EffectContext.AddInstigator(InInstigator, InEffectCauser);
|
||||
}
|
||||
|
||||
void UGGA_GameplayEffectFunctionLibrary::SetEffectCauser(FGameplayEffectContextHandle EffectContext, AActor* InEffectCauser)
|
||||
{
|
||||
EffectContext.AddInstigator(EffectContext.GetInstigator(), InEffectCauser);
|
||||
}
|
||||
|
||||
void UGGA_GameplayEffectFunctionLibrary::SetAbility(FGameplayEffectContextHandle EffectContext, const UGameplayAbility* InGameplayAbility)
|
||||
{
|
||||
EffectContext.SetAbility(InGameplayAbility);
|
||||
}
|
||||
|
||||
const UGameplayAbility* UGGA_GameplayEffectFunctionLibrary::GetAbilityCDO(FGameplayEffectContextHandle EffectContext)
|
||||
{
|
||||
return EffectContext.GetAbility();
|
||||
}
|
||||
|
||||
const UGameplayAbility* UGGA_GameplayEffectFunctionLibrary::GetAbilityInstance(FGameplayEffectContextHandle EffectContext)
|
||||
{
|
||||
return EffectContext.GetAbilityInstance_NotReplicated();
|
||||
}
|
||||
|
||||
int32 UGGA_GameplayEffectFunctionLibrary::GetAbilityLevel(FGameplayEffectContextHandle EffectContext)
|
||||
{
|
||||
return EffectContext.GetAbilityLevel();
|
||||
}
|
||||
|
||||
void UGGA_GameplayEffectFunctionLibrary::AddSourceObject(FGameplayEffectContextHandle EffectContext, const UObject* NewSourceObject)
|
||||
{
|
||||
if (NewSourceObject)
|
||||
{
|
||||
EffectContext.AddSourceObject(NewSourceObject);
|
||||
}
|
||||
}
|
||||
|
||||
bool UGGA_GameplayEffectFunctionLibrary::HasOrigin(FGameplayEffectContextHandle EffectContext)
|
||||
{
|
||||
return EffectContext.HasOrigin();
|
||||
}
|
||||
|
||||
FGGA_GameplayEffectContext* UGGA_GameplayEffectFunctionLibrary::GetEffectContextPtr(FGameplayEffectContextHandle EffectContext)
|
||||
{
|
||||
if (!EffectContext.IsValid())
|
||||
{
|
||||
GGA_LOG(Warning, "Try access invalid effect context!")
|
||||
return nullptr;
|
||||
}
|
||||
if (!EffectContext.Get()->GetScriptStruct()->IsChildOf(FGGA_GameplayEffectContext::StaticStruct()))
|
||||
{
|
||||
GGA_LOG(Warning, "The GameplayEffectContext type is not FGGA_GameplayEffectContext! "
|
||||
"Make sure you are setting AbilitySystemGlobalsClassName as GGA_AbilitySystemGlobals in Gameplay Abilities Settings Under Project Settings! ")
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<FGGA_GameplayEffectContext*>(EffectContext.Get());
|
||||
}
|
||||
|
||||
UAbilitySystemComponent* UGGA_GameplayEffectFunctionLibrary::GetInstigatorAbilitySystemComponent(FGameplayEffectContextHandle EffectContext)
|
||||
{
|
||||
return EffectContext.GetInstigatorAbilitySystemComponent();
|
||||
}
|
||||
|
||||
UAbilitySystemComponent* UGGA_GameplayEffectFunctionLibrary::GetOriginalInstigatorAbilitySystemComponent(FGameplayEffectContextHandle EffectContext)
|
||||
{
|
||||
return EffectContext.GetOriginalInstigatorAbilitySystemComponent();
|
||||
}
|
||||
|
||||
bool UGGA_GameplayEffectFunctionLibrary::HasContextPayload(FGameplayEffectContextHandle EffectContext, const UScriptStruct* PayloadType)
|
||||
{
|
||||
if (const FGGA_GameplayEffectContext* Context = GetEffectContextPtr(EffectContext))
|
||||
{
|
||||
return Context->FindPayloadByType(PayloadType) != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UGGA_GameplayEffectFunctionLibrary::GetContextPayload(FGameplayEffectContextHandle EffectContext, const UScriptStruct* PayloadType, FInstancedStruct& OutPayload)
|
||||
{
|
||||
if (FGGA_GameplayEffectContext* Context = GetEffectContextPtr(EffectContext))
|
||||
{
|
||||
if (FInstancedStruct* Found = Context->FindPayloadByType(PayloadType))
|
||||
{
|
||||
OutPayload = *Found;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
FInstancedStruct UGGA_GameplayEffectFunctionLibrary::GetValidContextPayload(FGameplayEffectContextHandle EffectContext, const UScriptStruct* PayloadType, bool& bValid)
|
||||
{
|
||||
bValid = false;
|
||||
if (FGGA_GameplayEffectContext* Context = GetEffectContextPtr(EffectContext))
|
||||
{
|
||||
if (FInstancedStruct* Found = Context->FindPayloadByType(PayloadType))
|
||||
{
|
||||
bValid = true;
|
||||
return *Found;
|
||||
}
|
||||
}
|
||||
return FInstancedStruct();
|
||||
}
|
||||
|
||||
void UGGA_GameplayEffectFunctionLibrary::GetContextPayload(FGameplayEffectContextHandle EffectContext, const UScriptStruct* PayloadType, EGGA_ContextPayloadResult& ExecResult, int32& Value)
|
||||
{
|
||||
// We should never hit this! stubs to avoid NoExport on the class.
|
||||
checkNoEntry();
|
||||
}
|
||||
|
||||
DEFINE_FUNCTION(UGGA_GameplayEffectFunctionLibrary::execGetContextPayload)
|
||||
{
|
||||
P_GET_STRUCT_REF(FGameplayEffectContextHandle, EffectContext);
|
||||
P_GET_OBJECT(const UScriptStruct, PayloadType);
|
||||
P_GET_ENUM_REF(EGGA_ContextPayloadResult, ExecResult);
|
||||
|
||||
// Read wildcard Value input
|
||||
Stack.MostRecentPropertyAddress = nullptr;
|
||||
Stack.MostRecentPropertyContainer = nullptr;
|
||||
Stack.StepCompiledIn<FStructProperty>(nullptr);
|
||||
|
||||
const FStructProperty* ValueProp = CastField<FStructProperty>(Stack.MostRecentProperty);
|
||||
void* ValuePtr = Stack.MostRecentPropertyAddress;
|
||||
|
||||
P_FINISH;
|
||||
|
||||
P_NATIVE_BEGIN;
|
||||
|
||||
ExecResult = EGGA_ContextPayloadResult::NotValid;
|
||||
|
||||
if (!ValueProp || !ValuePtr || !PayloadType)
|
||||
{
|
||||
FBlueprintExceptionInfo ExceptionInfo(
|
||||
EBlueprintExceptionType::AbortExecution,
|
||||
LOCTEXT("InstancedStruct_GetInvalidValueWarning", "Failed to resolve the Value or PayloadType for Get Context Payload")
|
||||
);
|
||||
FBlueprintCoreDelegates::ThrowScriptException(P_THIS, Stack, ExceptionInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
FInstancedStruct OutPayload;
|
||||
if (GetContextPayload(EffectContext, PayloadType, OutPayload))
|
||||
{
|
||||
if (OutPayload.IsValid() && OutPayload.GetScriptStruct()->IsChildOf(ValueProp->Struct))
|
||||
{
|
||||
// Copy the struct data to the output Value
|
||||
ValueProp->Struct->CopyScriptStruct(ValuePtr, OutPayload.GetMemory());
|
||||
ExecResult = EGGA_ContextPayloadResult::Valid;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExecResult = EGGA_ContextPayloadResult::NotValid;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ExecResult = EGGA_ContextPayloadResult::NotValid;
|
||||
}
|
||||
}
|
||||
|
||||
P_NATIVE_END;
|
||||
}
|
||||
|
||||
|
||||
void UGGA_GameplayEffectFunctionLibrary::SetContextPayload(FGameplayEffectContextHandle EffectContext, EGGA_ContextPayloadResult& ExecResult, const int32& Value)
|
||||
{
|
||||
// We should never hit this! stubs to avoid NoExport on the class.
|
||||
checkNoEntry();
|
||||
}
|
||||
|
||||
DEFINE_FUNCTION(UGGA_GameplayEffectFunctionLibrary::execSetContextPayload)
|
||||
{
|
||||
P_GET_STRUCT_REF(FGameplayEffectContextHandle, EffectContext);
|
||||
P_GET_ENUM_REF(EGGA_ContextPayloadResult, ExecResult);
|
||||
|
||||
// Read wildcard Value input
|
||||
Stack.MostRecentPropertyAddress = nullptr;
|
||||
Stack.MostRecentPropertyContainer = nullptr;
|
||||
Stack.StepCompiledIn<FStructProperty>(nullptr);
|
||||
|
||||
const FStructProperty* ValueProp = CastField<FStructProperty>(Stack.MostRecentProperty);
|
||||
const void* ValuePtr = Stack.MostRecentPropertyAddress;
|
||||
|
||||
P_FINISH;
|
||||
|
||||
P_NATIVE_BEGIN;
|
||||
|
||||
ExecResult = EGGA_ContextPayloadResult::NotValid;
|
||||
|
||||
if (!ValueProp || !ValuePtr || !EffectContext.IsValid())
|
||||
{
|
||||
FBlueprintExceptionInfo ExceptionInfo(
|
||||
EBlueprintExceptionType::AbortExecution,
|
||||
LOCTEXT("InstancedStruct_SetInvalidValueWarning", "Failed to resolve Value or EffectContext for Set Instanced Struct Value")
|
||||
);
|
||||
FBlueprintCoreDelegates::ThrowScriptException(P_THIS, Stack, ExceptionInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create an FInstancedStruct from the input struct
|
||||
FInstancedStruct Payload;
|
||||
Payload.InitializeAs(ValueProp->Struct, static_cast<const uint8*>(ValuePtr));
|
||||
|
||||
if (Payload.IsValid())
|
||||
{
|
||||
// Call the existing SetPayload function
|
||||
if (FGGA_GameplayEffectContext* ContextPtr = GetEffectContextPtr(EffectContext))
|
||||
{
|
||||
ContextPtr->AddOrOverwriteData(Payload);
|
||||
ExecResult = EGGA_ContextPayloadResult::Valid;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FBlueprintExceptionInfo ExceptionInfo(
|
||||
EBlueprintExceptionType::AbortExecution,
|
||||
LOCTEXT("SetGameplayEffectContextPayload", "Failed to create valid InstancedStruct from Value")
|
||||
);
|
||||
FBlueprintCoreDelegates::ThrowScriptException(P_THIS, Stack, ExceptionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
P_NATIVE_END;
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
Reference in New Issue
Block a user