第一次提交

This commit is contained in:
不明不惑
2026-03-03 01:23:02 +08:00
commit 3e434877e8
1053 changed files with 102411 additions and 0 deletions

View File

@@ -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