第一次提交
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "GGA_AttributeGroupNameCustomization.h"
|
||||
#include "DetailWidgetRow.h"
|
||||
#include "GGA_AbilitySystemGlobals.h"
|
||||
#include "GGA_AbilitySystemStructLibrary.h"
|
||||
#include "PropertyCustomizationHelpers.h"
|
||||
|
||||
|
||||
TSharedRef<IPropertyTypeCustomization> FGGA_AttributeGroupNameCustomization::MakeInstance()
|
||||
{
|
||||
return MakeShareable(new FGGA_AttributeGroupNameCustomization());
|
||||
}
|
||||
|
||||
void FGGA_AttributeGroupNameCustomization::CustomizeHeader(TSharedRef<IPropertyHandle> StructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
|
||||
{
|
||||
const UGGA_AbilitySystemGlobals* Globals = Cast<UGGA_AbilitySystemGlobals>(IGameplayAbilitiesModule::Get().GetAbilitySystemGlobals());
|
||||
|
||||
if (Globals == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FNameMap.Reset();
|
||||
|
||||
for (const UCurveTable* CurTable : Globals->GetAttributeDefaultsTables())
|
||||
{
|
||||
if (!IsValid(CurTable))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const TPair<FName, FRealCurve*>& CurveRow : CurTable->GetRowMap())
|
||||
{
|
||||
FString RowName = CurveRow.Key.ToString();
|
||||
|
||||
TArray<FString> RowParts; //[0]GroupName [1]SetName [2]AttribueName
|
||||
RowName.ParseIntoArray(RowParts, TEXT("."));
|
||||
if (RowParts.Num() != 3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
TArray<FString> GroupParts; //[0]MainName [1]SubName
|
||||
RowName.ParseIntoArray(GroupParts, TEXT("->"));
|
||||
if (GroupParts.Num() != 2)
|
||||
{
|
||||
//Add class name as group.
|
||||
FNameMap.FindOrAdd(FName(*RowParts[0]));
|
||||
}
|
||||
else if (GroupParts.Num() == 2)
|
||||
{
|
||||
TArray<FName>& Rows = FNameMap.FindOrAdd(FName(*GroupParts[0]));
|
||||
Rows.AddUnique(FName(*GroupParts[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
PropertyUtilities = StructCustomizationUtils.GetPropertyUtilities();
|
||||
|
||||
MainNamePropertyHandle = StructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FGGA_AttributeGroupName, MainName));
|
||||
SubNamePropertyHandle = StructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FGGA_AttributeGroupName, SubName));
|
||||
if (MainNamePropertyHandle.IsValid() && SubNamePropertyHandle.IsValid())
|
||||
{
|
||||
HeaderRow
|
||||
.NameContent()
|
||||
[
|
||||
StructPropertyHandle->CreatePropertyNameWidget()
|
||||
]
|
||||
.ValueContent()
|
||||
.MinDesiredWidth(600)
|
||||
.MaxDesiredWidth(4096)
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+ SHorizontalBox::Slot()
|
||||
[
|
||||
SNew(SVerticalBox)
|
||||
+ SVerticalBox::Slot()
|
||||
.HAlign(HAlign_Fill)
|
||||
.Padding(1.f, 0.f, 2.f, 0.f)
|
||||
[
|
||||
PropertyCustomizationHelpers::MakePropertyComboBox(MainNamePropertyHandle,
|
||||
FOnGetPropertyComboBoxStrings::CreateStatic(&FGGA_AttributeGroupNameCustomization::GeneratePrimaryComboboxStrings, true,
|
||||
false, &FNameMap),
|
||||
FOnGetPropertyComboBoxValue::CreateSP(this, &FGGA_AttributeGroupNameCustomization::GenerateMainString),
|
||||
FOnPropertyComboBoxValueSelected::CreateSP(this, &FGGA_AttributeGroupNameCustomization::OnMainValueSelected))
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
.HAlign(HAlign_Fill)
|
||||
.Padding(2.f, 0.f, 2.f, 0.f)
|
||||
[
|
||||
PropertyCustomizationHelpers::MakePropertyComboBox(MainNamePropertyHandle,
|
||||
FOnGetPropertyComboBoxStrings::CreateStatic(&FGGA_AttributeGroupNameCustomization::GenerateSubComboboxStrings, true,
|
||||
false, &FNameMap,
|
||||
MainNamePropertyHandle),
|
||||
FOnGetPropertyComboBoxValue::CreateSP(this, &FGGA_AttributeGroupNameCustomization::GenerateSubString),
|
||||
FOnPropertyComboBoxValueSelected::CreateSP(this, &FGGA_AttributeGroupNameCustomization::OnSubValueSelected))
|
||||
]
|
||||
]
|
||||
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FGGA_AttributeGroupNameCustomization::GeneratePrimaryComboboxStrings(TArray<TSharedPtr<FString>>& OutComboBoxStrings, TArray<TSharedPtr<SToolTip>>& OutToolTips, TArray<bool>& OutRestrictedItems,
|
||||
bool bAllowClear, bool bAllowAll,
|
||||
TMap<FName, TArray<FName>>* InItems)
|
||||
{
|
||||
for (auto Iter = InItems->CreateConstIterator(); Iter; ++Iter)
|
||||
{
|
||||
OutComboBoxStrings.Add(MakeShared<FString>(Iter.Key().ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
void FGGA_AttributeGroupNameCustomization::GenerateSubComboboxStrings(TArray<TSharedPtr<FString>>& OutComboBoxStrings, TArray<TSharedPtr<SToolTip>>& OutToolTips,
|
||||
TArray<bool>& OutRestrictedItems, bool bAllowClear, bool bAllowAll,
|
||||
TMap<FName, TArray<FName>>* InItems, TSharedPtr<IPropertyHandle> PrimaryKey)
|
||||
{
|
||||
void* TagDataPtr = nullptr;
|
||||
PrimaryKey->GetValueData(TagDataPtr);
|
||||
const FName* TagPtr = static_cast<FName*>(TagDataPtr);
|
||||
|
||||
if (!TagPtr || TagPtr->IsNone())
|
||||
{
|
||||
OutComboBoxStrings.Add(MakeShared<FString>("Invalid"));
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto Arr = InItems->Find(*TagPtr);
|
||||
if (Arr)
|
||||
{
|
||||
for (auto& Name : *Arr)
|
||||
{
|
||||
OutComboBoxStrings.Add(MakeShared<FString>(Name.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FString FGGA_AttributeGroupNameCustomization::GenerateSubString()
|
||||
{
|
||||
void* TagDataPtr = nullptr;
|
||||
SubNamePropertyHandle->GetValueData(TagDataPtr);
|
||||
const FName* TagPtr = static_cast<FName*>(TagDataPtr);
|
||||
|
||||
FString TagString = TagPtr ? TagPtr->ToString() : "Invalid";
|
||||
|
||||
return TagString;
|
||||
}
|
||||
|
||||
void FGGA_AttributeGroupNameCustomization::OnSubValueSelected(const FString& String)
|
||||
{
|
||||
SubNamePropertyHandle->SetValue(FName(*String));
|
||||
}
|
||||
|
||||
FString FGGA_AttributeGroupNameCustomization::GenerateMainString()
|
||||
{
|
||||
void* TagDataPtr = nullptr;
|
||||
MainNamePropertyHandle->GetValueData(TagDataPtr);
|
||||
const FName* TagPtr = static_cast<FName*>(TagDataPtr);
|
||||
|
||||
FString TagString = TagPtr ? TagPtr->ToString() : "Invalid";
|
||||
|
||||
return TagString;
|
||||
}
|
||||
|
||||
void FGGA_AttributeGroupNameCustomization::OnMainValueSelected(const FString& String)
|
||||
{
|
||||
MainNamePropertyHandle->SetValue(FName(*String));
|
||||
SubNamePropertyHandle->ResetToDefault();
|
||||
}
|
||||
|
||||
void FGGA_AttributeGroupNameCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> StructPropertyHandle, IDetailChildrenBuilder& StructBuilder,
|
||||
IPropertyTypeCustomizationUtils& StructCustomizationUtils)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "GGA_K2Node_ContextPayload.h"
|
||||
#include "EdGraphSchema_K2.h"
|
||||
#include "BlueprintNodeSpawner.h"
|
||||
#include "BlueprintActionDatabaseRegistrar.h"
|
||||
#include "Utilities/GGA_GameplayEffectFunctionLibrary.h"
|
||||
|
||||
void UGGA_K2Node_ContextPayload::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const
|
||||
{
|
||||
Super::GetMenuActions(ActionRegistrar);
|
||||
UClass* Action = GetClass();
|
||||
if (ActionRegistrar.IsOpenForRegistration(Action))
|
||||
{
|
||||
auto CustomizeLambda = [](UEdGraphNode* NewNode, bool bIsTemplateNode, const FName FunctionName)
|
||||
{
|
||||
UGGA_K2Node_ContextPayload* Node = CastChecked<UGGA_K2Node_ContextPayload>(NewNode);
|
||||
UFunction* Function = UGGA_GameplayEffectFunctionLibrary::StaticClass()->FindFunctionByName(FunctionName);
|
||||
check(Function);
|
||||
Node->SetFromFunction(Function);
|
||||
};
|
||||
|
||||
UBlueprintNodeSpawner* SetNodeSpawner = UBlueprintNodeSpawner::Create(GetClass());
|
||||
check(SetNodeSpawner != nullptr);
|
||||
SetNodeSpawner->CustomizeNodeDelegate = UBlueprintNodeSpawner::FCustomizeNodeDelegate::CreateStatic(
|
||||
CustomizeLambda, GET_FUNCTION_NAME_CHECKED(UGGA_GameplayEffectFunctionLibrary, SetContextPayload));
|
||||
ActionRegistrar.AddBlueprintAction(Action, SetNodeSpawner);
|
||||
|
||||
// UBlueprintNodeSpawner* GetNodeSpawner = UBlueprintNodeSpawner::Create(GetClass());
|
||||
// check(GetNodeSpawner != nullptr);
|
||||
// GetNodeSpawner->CustomizeNodeDelegate = UBlueprintNodeSpawner::FCustomizeNodeDelegate::CreateStatic(
|
||||
// CustomizeLambda, GET_FUNCTION_NAME_CHECKED(UGGA_GameplayEffectFunctionLibrary, GetContextPayload));
|
||||
// ActionRegistrar.AddBlueprintAction(Action, GetNodeSpawner);
|
||||
}
|
||||
}
|
||||
|
||||
bool UGGA_K2Node_ContextPayload::IsConnectionDisallowed(const UEdGraphPin* MyPin, const UEdGraphPin* OtherPin, FString& OutReason) const
|
||||
{
|
||||
const UEdGraphPin* ValuePin = FindPinChecked(FName(TEXT("Value")));
|
||||
|
||||
if (MyPin == ValuePin && MyPin->PinType.PinCategory == UEdGraphSchema_K2::PC_Wildcard)
|
||||
{
|
||||
if (OtherPin->PinType.PinCategory != UEdGraphSchema_K2::PC_Struct)
|
||||
{
|
||||
OutReason = TEXT("Value must be a struct.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "GGA_K2Node_EffectContextPayload.h"
|
||||
|
||||
#include "BlueprintActionDatabaseRegistrar.h"
|
||||
#include "BlueprintNodeSpawner.h"
|
||||
#include "EdGraphSchema_K2.h"
|
||||
#include "K2Node_AssignmentStatement.h"
|
||||
#include "K2Node_CallFunction.h"
|
||||
#include "K2Node_TemporaryVariable.h"
|
||||
#include "KismetCompiler.h"
|
||||
#include "Kismet/BlueprintInstancedStructLibrary.h"
|
||||
#include "Utilities/GGA_GameplayEffectFunctionLibrary.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "K2Node"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Node Change events interface implementations
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void UGGA_K2Node_EffectContextPayload::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins)
|
||||
{
|
||||
AllocateDefaultPins();
|
||||
RestoreSplitPins(OldPins);
|
||||
}
|
||||
|
||||
void UGGA_K2Node_EffectContextPayload::PostPlacedNewNode()
|
||||
{
|
||||
Super::PostPlacedNewNode();
|
||||
RefreshOutputType();
|
||||
}
|
||||
|
||||
void UGGA_K2Node_EffectContextPayload::PinConnectionListChanged(UEdGraphPin* Pin)
|
||||
{
|
||||
Super::PinConnectionListChanged(Pin);
|
||||
|
||||
if (Pin && Pin == GetPayloadTypePin())
|
||||
{
|
||||
RefreshOutputType();
|
||||
}
|
||||
}
|
||||
|
||||
void UGGA_K2Node_EffectContextPayload::PinDefaultValueChanged(UEdGraphPin* Pin)
|
||||
{
|
||||
if (Pin == GetPayloadTypePin())
|
||||
{
|
||||
if (Pin->LinkedTo.Num() == 0)
|
||||
{
|
||||
RefreshOutputType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UGGA_K2Node_EffectContextPayload::PostReconstructNode()
|
||||
{
|
||||
Super::PostReconstructNode();
|
||||
RefreshOutputType();
|
||||
}
|
||||
|
||||
void UGGA_K2Node_EffectContextPayload::RefreshOutputType()
|
||||
{
|
||||
UEdGraphPin* OutStructPin = GetOutStructPin();
|
||||
UEdGraphPin* PayloadType = GetPayloadTypePin();
|
||||
|
||||
if (PayloadType->DefaultObject != OutStructPin->PinType.PinSubCategoryObject)
|
||||
{
|
||||
if (OutStructPin->SubPins.Num() > 0)
|
||||
{
|
||||
GetSchema()->RecombinePin(OutStructPin);
|
||||
}
|
||||
|
||||
OutStructPin->PinType.PinSubCategoryObject = PayloadType->DefaultObject;
|
||||
OutStructPin->PinType.PinCategory = (PayloadType->DefaultObject == nullptr) ? UEdGraphSchema_K2::PC_Wildcard : UEdGraphSchema_K2::PC_Struct;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//UK2_Node and EDGraph Interface Implementations
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
FString UGGA_K2Node_EffectContextPayload::GetPinMetaData(FName InPinName, FName InKey)
|
||||
{
|
||||
FString MetaData = Super::GetPinMetaData(InPinName, InKey);
|
||||
if (MetaData.IsEmpty())
|
||||
{
|
||||
//Filters out the abstract classes from the pin search
|
||||
if (InPinName == GetPayloadTypePin()->GetName() && InKey == FBlueprintMetadata::MD_AllowAbstractClasses)
|
||||
{
|
||||
MetaData = TEXT("false");
|
||||
}
|
||||
}
|
||||
return MetaData;
|
||||
}
|
||||
|
||||
FSlateIcon UGGA_K2Node_EffectContextPayload::GetIconAndTint(FLinearColor& OutColor) const
|
||||
{
|
||||
OutColor = FLinearColor(FColor::Black);
|
||||
return FSlateIcon(FAppStyle::GetAppStyleSetName(), "Kismet.AllClasses.FunctionIcon");
|
||||
}
|
||||
|
||||
|
||||
FLinearColor UGGA_K2Node_EffectContextPayload::GetNodeTitleColor() const
|
||||
{
|
||||
return FLinearColor(FColor::Cyan);
|
||||
}
|
||||
|
||||
|
||||
FText UGGA_K2Node_EffectContextPayload::GetMenuCategory() const
|
||||
{
|
||||
return LOCTEXT("K2Node_GetProperty_Category", "GGA|GameplayEffect|Context");
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// PIN GETTERS
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
UEdGraphPin* UGGA_K2Node_EffectContextPayload::GetEffectContextPin() const
|
||||
{
|
||||
UEdGraphPin* Pin = FindPinChecked(K2Node_ContextPayload_PinNames::EffectContextPinName);
|
||||
check(Pin->Direction == EGPD_Input);
|
||||
return Pin;
|
||||
}
|
||||
|
||||
UEdGraphPin* UGGA_K2Node_EffectContextPayload::GetInstancedStructPin() const
|
||||
{
|
||||
UEdGraphPin* Pin = FindPinChecked(K2Node_ContextPayload_PinNames::InstancedStructPinName);
|
||||
check(Pin->Direction == EGPD_Input);
|
||||
return Pin;
|
||||
}
|
||||
|
||||
UEdGraphPin* UGGA_K2Node_EffectContextPayload::GetKeyPin() const
|
||||
{
|
||||
UEdGraphPin* Pin = FindPinChecked(K2Node_ContextPayload_PinNames::KeyPinName);
|
||||
check(Pin->Direction == EGPD_Input);
|
||||
return Pin;
|
||||
}
|
||||
|
||||
UEdGraphPin* UGGA_K2Node_EffectContextPayload::GetPayloadTypePin() const
|
||||
{
|
||||
UEdGraphPin* Pin = FindPinChecked(K2Node_ContextPayload_PinNames::PayloadTypePinName);
|
||||
check(Pin->Direction == EGPD_Input);
|
||||
return Pin;
|
||||
}
|
||||
|
||||
UEdGraphPin* UGGA_K2Node_EffectContextPayload::GetOutStructPin() const
|
||||
{
|
||||
UEdGraphPin* Pin = FindPinChecked(K2Node_ContextPayload_PinNames::OutStructPinName);
|
||||
check(Pin->Direction == EGPD_Output);
|
||||
return Pin;
|
||||
}
|
||||
|
||||
UEdGraphPin* UGGA_K2Node_EffectContextPayload::GetValidPin() const
|
||||
{
|
||||
UEdGraphPin* Pin = FindPinChecked(K2Node_ContextPayload_PinNames::ValidExecPinName);
|
||||
check(Pin->Direction == EGPD_Output);
|
||||
return Pin;
|
||||
}
|
||||
|
||||
UEdGraphPin* UGGA_K2Node_EffectContextPayload::GetInvalidPin() const
|
||||
{
|
||||
UEdGraphPin* Pin = FindPinChecked(K2Node_ContextPayload_PinNames::InvalidExecPinName);
|
||||
check(Pin->Direction == EGPD_Output);
|
||||
return Pin;
|
||||
}
|
||||
|
||||
|
||||
void UGGA_K2Node_GetEffectContextPayload::AllocateDefaultPins()
|
||||
{
|
||||
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);
|
||||
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Struct, FGameplayEffectContextHandle::StaticStruct(), K2Node_ContextPayload_PinNames::EffectContextPinName);
|
||||
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Object, UScriptStruct::StaticClass(), K2Node_ContextPayload_PinNames::PayloadTypePinName);
|
||||
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, K2Node_ContextPayload_PinNames::ValidExecPinName);
|
||||
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, K2Node_ContextPayload_PinNames::InvalidExecPinName);
|
||||
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Wildcard, K2Node_ContextPayload_PinNames::OutStructPinName);
|
||||
|
||||
Super::AllocateDefaultPins();
|
||||
}
|
||||
|
||||
void UGGA_K2Node_GetEffectContextPayload::ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph)
|
||||
{
|
||||
Super::ExpandNode(CompilerContext, SourceGraph);
|
||||
|
||||
UFunction* GetValidContextPayloadFunc = UGGA_GameplayEffectFunctionLibrary::StaticClass()->FindFunctionByName(
|
||||
GET_FUNCTION_NAME_CHECKED_ThreeParams(UGGA_GameplayEffectFunctionLibrary, GetValidContextPayload, FGameplayEffectContextHandle, const UScriptStruct*, bool&));
|
||||
UFunction* GetInstStructValueFunc = UBlueprintInstancedStructLibrary::StaticClass()->FindFunctionByName(GET_FUNCTION_NAME_CHECKED(UBlueprintInstancedStructLibrary, GetInstancedStructValue));
|
||||
|
||||
if (!GetValidContextPayloadFunc || !GetInstStructValueFunc)
|
||||
{
|
||||
CompilerContext.MessageLog.Error(
|
||||
*LOCTEXT("InvalidClass", "The GetValidContextPayload or GetInstancedStructValue functions have not been found. Check ExpandNode in GGA_K2Node_EffectContextPayload.cpp").ToString(),
|
||||
this);
|
||||
return;
|
||||
}
|
||||
|
||||
const UEdGraphSchema_K2* Schema = CompilerContext.GetSchema();
|
||||
bool bIsErrorFree = true;
|
||||
|
||||
|
||||
const FEdGraphPinType& PinType = GetOutStructPin()->PinType;
|
||||
|
||||
UK2Node_TemporaryVariable* TempVarOutput = CompilerContext.SpawnInternalVariable(
|
||||
this, PinType.PinCategory, PinType.PinSubCategory, PinType.PinSubCategoryObject.Get(), PinType.ContainerType, PinType.PinValueType);
|
||||
|
||||
UK2Node_AssignmentStatement* AssignNode = CompilerContext.SpawnIntermediateNode<UK2Node_AssignmentStatement>(this, SourceGraph);
|
||||
UK2Node_CallFunction* const GetPayloadNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph);
|
||||
UK2Node_CallFunction* const GetStructValueNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph);
|
||||
|
||||
GetPayloadNode->SetFromFunction(GetValidContextPayloadFunc);
|
||||
GetStructValueNode->SetFromFunction(GetInstStructValueFunc);
|
||||
|
||||
GetPayloadNode->AllocateDefaultPins();
|
||||
GetStructValueNode->AllocateDefaultPins();
|
||||
AssignNode->AllocateDefaultPins();
|
||||
|
||||
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(GetPayloadNode, this);
|
||||
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(GetStructValueNode, this);
|
||||
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(AssignNode, this);
|
||||
|
||||
//Connect input pins to the GetValidContextPayloadNode
|
||||
//----------------------------------------------------------------------------------------
|
||||
// UEdGraphPin* EffectContextPin = Schema->FindSelfPin(*GetPayloadNode, EGPD_Input);
|
||||
UEdGraphPin* EffectContextPin = GetPayloadNode->FindPinChecked(TEXT("EffectContext"));
|
||||
UEdGraphPin* InterExecLeftPin = GetPayloadNode->GetThenPin();
|
||||
UEdGraphPin* PayloadTypePin = GetPayloadNode->FindPinChecked(TEXT("PayloadType"));
|
||||
UEdGraphPin* InterStructLeftPin = GetPayloadNode->GetReturnValuePin();
|
||||
|
||||
bIsErrorFree &= CompilerContext.MovePinLinksToIntermediate(*GetEffectContextPin(), *EffectContextPin).CanSafeConnect();
|
||||
bIsErrorFree &= CompilerContext.MovePinLinksToIntermediate(*GetPayloadTypePin(), *PayloadTypePin).CanSafeConnect();
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//Connect input Target Pin and the output GetPayloadNode pins to the GetStructValueNode pin
|
||||
//----------------------------------------------------------------------------------------
|
||||
UEdGraphPin* InterExecRightPin = GetStructValueNode->GetExecPin();
|
||||
UEdGraphPin* ValidPin = GetStructValueNode->FindPinChecked(TEXT("Valid"));
|
||||
UEdGraphPin* InvalidPin = GetStructValueNode->FindPinChecked(TEXT("NotValid"));
|
||||
UEdGraphPin* OutStructPin = GetStructValueNode->FindPinChecked(TEXT("Value"));
|
||||
UEdGraphPin* InterStructRightPin = GetStructValueNode->FindPinChecked(TEXT("InstancedStruct"));
|
||||
|
||||
bIsErrorFree &= CompilerContext.MovePinLinksToIntermediate(*GetExecPin(), *InterExecRightPin).CanSafeConnect();
|
||||
bIsErrorFree &= Schema->TryCreateConnection(InterStructLeftPin, InterStructRightPin);
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//Connect the output of GetStructValueNode to the input of Assign node. The Invalid pin directly goes to Invalid pin
|
||||
// but the valid pin goes through the Assign node. The temporary variable is assigned a value, and is connected to the
|
||||
// node's output struct. The order that the connections are made is critical. First the variable needs to connect to the output,
|
||||
// then the variable should be connected to the Variable pin of Assign so the variable type is updated, and only then the Value pin
|
||||
// of Assign can be connected to OutStructPin of the GetStructValueNode.
|
||||
//----------------------------------------------------------------------------------------
|
||||
bIsErrorFree &= CompilerContext.MovePinLinksToIntermediate(*GetOutStructPin(), *TempVarOutput->GetVariablePin()).CanSafeConnect();
|
||||
bIsErrorFree &= Schema->TryCreateConnection(AssignNode->GetVariablePin(), TempVarOutput->GetVariablePin());
|
||||
bIsErrorFree &= Schema->TryCreateConnection(AssignNode->GetValuePin(), OutStructPin);
|
||||
|
||||
bIsErrorFree &= Schema->TryCreateConnection(ValidPin, AssignNode->GetExecPin());
|
||||
bIsErrorFree &= CompilerContext.MovePinLinksToIntermediate(*GetInvalidPin(), *InvalidPin).CanSafeConnect();
|
||||
bIsErrorFree &= CompilerContext.MovePinLinksToIntermediate(*GetValidPin(), *AssignNode->GetThenPin()).CanSafeConnect();
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
if (!bIsErrorFree)
|
||||
{
|
||||
CompilerContext.MessageLog.Error(*LOCTEXT("InternalConnectionError", "Get Context Payload: Internal connection error. @@").ToString(), this);
|
||||
}
|
||||
BreakAllNodeLinks();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//UK2_Node and EDGraph Interface Implementations
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void UGGA_K2Node_GetEffectContextPayload::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const
|
||||
{
|
||||
Super::GetMenuActions(ActionRegistrar);
|
||||
UClass* Action = GetClass();
|
||||
if (ActionRegistrar.IsOpenForRegistration(Action))
|
||||
{
|
||||
UBlueprintNodeSpawner* Spawner = UBlueprintNodeSpawner::Create(GetClass());
|
||||
ActionRegistrar.AddBlueprintAction(Action, Spawner);
|
||||
}
|
||||
}
|
||||
|
||||
FText UGGA_K2Node_GetEffectContextPayload::GetNodeTitle(ENodeTitleType::Type TitleType) const
|
||||
{
|
||||
return LOCTEXT("K2Node_GetProperty_NodeTitle", "Get Context Payload");
|
||||
}
|
||||
|
||||
FText UGGA_K2Node_GetEffectContextPayload::GetTooltipText() const
|
||||
{
|
||||
return LOCTEXT("K2Node_GetProperty_TooltipText", "Outputs the context payload based on the selected payload type");
|
||||
}
|
||||
|
||||
FText UGGA_K2Node_GetEffectContextPayload::GetKeywords() const
|
||||
{
|
||||
return LOCTEXT("GetEffectContextPayload", "Get Gameplay Effect Context Payload");
|
||||
}
|
||||
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "GenericGameplayAbilitiesEditor.h"
|
||||
|
||||
#include "GGA_AttributeGroupNameCustomization.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FGenericGameplayAbilitiesEditorModule"
|
||||
|
||||
void FGenericGameplayAbilitiesEditorModule::StartupModule()
|
||||
{
|
||||
FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
|
||||
PropertyModule.RegisterCustomPropertyTypeLayout("GGA_AttributeGroupName", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FGGA_AttributeGroupNameCustomization::MakeInstance));
|
||||
}
|
||||
|
||||
void FGenericGameplayAbilitiesEditorModule::ShutdownModule()
|
||||
{
|
||||
FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
|
||||
PropertyModule.UnregisterCustomPropertyTypeLayout("GGA_AttributeGroupName");
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FGenericGameplayAbilitiesEditorModule, GenericGameplayAbilitiesEditor)
|
||||
Reference in New Issue
Block a user