2014-03-14 14:13:41 -04:00
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
# include "BlueprintGraphPrivatePCH.h"
# include "CompilerResultsLog.h"
# include "ClassIconFinder.h"
# define LOCTEXT_NAMESPACE "K2Node"
UK2Node_Variable : : UK2Node_Variable ( const class FPostConstructInitializeProperties & PCIP )
: Super ( PCIP )
{
}
void UK2Node_Variable : : Serialize ( FArchive & Ar )
{
Super : : Serialize ( Ar ) ;
// Fix old content
if ( Ar . IsLoading ( ) )
{
if ( Ar . UE4Ver ( ) < VER_UE4_VARK2NODE_NULL_VARSRCCLASS_ON_SELF )
{
// See if bSelfContext is set but there is still a class assigned
if ( bSelfContext_DEPRECATED & & VariableSourceClass_DEPRECATED ! = NULL )
{
VariableSourceClass_DEPRECATED = NULL ;
UE_LOG ( LogBlueprint , Log , TEXT ( " VarNode '%s' Variable '%s': Cleared VariableSourceClass. " ) , * GetPathName ( ) , * GetVarNameString ( ) ) ;
}
}
if ( Ar . UE4Ver ( ) < VER_UE4_VARK2NODE_USE_MEMBERREFSTRUCT )
{
// Copy info into new struct
VariableReference . SetDirect ( VariableName_DEPRECATED , FGuid ( ) , VariableSourceClass_DEPRECATED , bSelfContext_DEPRECATED ) ;
}
if ( Ar . UE4Ver ( ) < VER_UE4_K2NODE_REFERENCEGUIDS )
{
FGuid VarGuid ;
if ( UBlueprint : : GetGuidFromClassByFieldName < UProperty > ( GetBlueprint ( ) - > GeneratedClass , VariableReference . GetMemberName ( ) , VarGuid ) )
{
const bool bSelf = VariableReference . IsSelfContext ( ) ;
VariableReference . SetDirect ( VariableReference . GetMemberName ( ) , VarGuid , ( bSelf ? NULL : VariableReference . GetMemberParentClass ( ( UClass * ) NULL ) ) , bSelf ) ;
}
}
}
}
void UK2Node_Variable : : SetFromProperty ( const UProperty * Property , bool bSelfContext )
{
2014-04-23 18:01:32 -04:00
SelfContextInfo = bSelfContext ? ESelfContextInfo : : Unspecified : ESelfContextInfo : : NotSelfContext ;
2014-03-14 14:13:41 -04:00
VariableReference . SetFromField < UProperty > ( Property , bSelfContext ) ;
}
bool UK2Node_Variable : : CreatePinForVariable ( EEdGraphPinDirection Direction )
{
const UEdGraphSchema_K2 * K2Schema = GetDefault < UEdGraphSchema_K2 > ( ) ;
UProperty * VariableProperty = GetPropertyForVariable ( ) ;
2014-09-25 13:31:55 -04:00
// favor the skeleton property if possible (in case the property type has
// been changed, and not yet compiled).
if ( ! VariableReference . IsSelfContext ( ) )
2014-09-24 14:15:01 -04:00
{
2014-09-25 13:31:55 -04:00
UClass * VariableClass = VariableReference . GetMemberParentClass ( GetBlueprint ( ) - > GeneratedClass ) ;
if ( UBlueprintGeneratedClass * BpClassOwner = Cast < UBlueprintGeneratedClass > ( VariableClass ) )
2014-09-24 14:15:01 -04:00
{
2014-09-25 13:31:55 -04:00
// this variable could currently only be a part of some skeleton
// class (the blueprint has not be compiled with it yet), so let's
// check the skeleton class as well, see if we can pull pin data
// from there...
UBlueprint * VariableBlueprint = CastChecked < UBlueprint > ( BpClassOwner - > ClassGeneratedBy ) ;
if ( UProperty * SkelProperty = FindField < UProperty > ( VariableBlueprint - > SkeletonGeneratedClass , VariableReference . GetMemberName ( ) ) )
2014-09-24 14:15:01 -04:00
{
2014-09-25 13:31:55 -04:00
VariableProperty = SkelProperty ;
2014-09-24 14:15:01 -04:00
}
}
}
2014-03-14 14:13:41 -04:00
if ( VariableProperty ! = NULL )
{
// Create the pin
UEdGraphPin * VariablePin = CreatePin ( Direction , TEXT ( " " ) , TEXT ( " " ) , NULL , false , false , GetVarNameString ( ) ) ;
K2Schema - > ConvertPropertyToPinType ( VariableProperty , /*out*/ VariablePin - > PinType ) ;
K2Schema - > SetPinDefaultValueBasedOnType ( VariablePin ) ;
}
else
{
2014-08-19 12:36:44 -04:00
if ( ! VariableReference . IsLocalScope ( ) )
{
Message_Warn ( * FString : : Printf ( TEXT ( " CreatePinForVariable: '%s' variable not found. Base class was probably changed. " ) , * GetVarNameString ( ) ) ) ;
}
2014-03-14 14:13:41 -04:00
return false ;
}
return true ;
}
void UK2Node_Variable : : CreatePinForSelf ( )
{
const UEdGraphSchema_K2 * K2Schema = GetDefault < UEdGraphSchema_K2 > ( ) ;
// Create the self pin
if ( ! K2Schema - > FindSelfPin ( * this , EGPD_Input ) )
{
2014-05-09 17:43:40 -04:00
// Do not create a self pin for locally scoped variables
if ( ! VariableReference . IsLocalScope ( ) )
2014-03-14 14:13:41 -04:00
{
2014-10-03 14:56:47 -04:00
bool bSelfTarget = VariableReference . IsSelfContext ( ) & & ( ESelfContextInfo : : NotSelfContext ! = SelfContextInfo ) ;
2014-10-01 11:49:19 -04:00
UClass * MemberParentClass = VariableReference . GetMemberParentClass ( this ) ;
2014-10-03 14:56:47 -04:00
UClass * TargetClass = nullptr ;
// Self Target pins should always make the class be the owning class of the property,
// so if the node is from a Macro Blueprint, it will hook up as self in any placed Blueprint
if ( bSelfTarget )
{
2014-10-06 17:18:23 -04:00
if ( UProperty * Property = VariableReference . ResolveMember < UProperty > ( this ) )
{
TargetClass = Property - > GetOwnerClass ( ) - > GetAuthoritativeClass ( ) ;
}
else
{
TargetClass = GetBlueprint ( ) - > SkeletonGeneratedClass - > GetAuthoritativeClass ( ) ;
}
2014-10-03 14:56:47 -04:00
}
else
{
TargetClass = MemberParentClass ? MemberParentClass - > GetAuthoritativeClass ( ) : NULL ;
}
UEdGraphPin * TargetPin = CreatePin ( EGPD_Input , K2Schema - > PC_Object , TEXT ( " " ) , TargetClass , false , false , K2Schema - > PN_Self ) ;
2014-10-01 11:49:19 -04:00
TargetPin - > PinFriendlyName = LOCTEXT ( " Target " , " Target " ) ;
2014-10-03 14:56:47 -04:00
if ( bSelfTarget )
2014-05-09 17:43:40 -04:00
{
2014-10-01 11:49:19 -04:00
TargetPin - > bHidden = true ; // don't show in 'self' context
2014-05-09 17:43:40 -04:00
}
2014-03-14 14:13:41 -04:00
}
}
else
{
//@TODO: Check that the self pin types match!
}
}
bool UK2Node_Variable : : RecreatePinForVariable ( EEdGraphPinDirection Direction , TArray < UEdGraphPin * > & OldPins )
{
// probably the node was pasted to a blueprint without the variable
// we don't want to beak any connection, so the pin will be recreated from old one, but compiler will throw error
// find old variable pin
const UEdGraphPin * OldVariablePin = NULL ;
const FString PinName = GetVarNameString ( ) ;
for ( auto Iter = OldPins . CreateConstIterator ( ) ; Iter ; + + Iter )
{
if ( const UEdGraphPin * Pin = * Iter )
{
if ( PinName = = Pin - > PinName )
{
OldVariablePin = Pin ;
break ;
}
}
}
if ( NULL ! = OldVariablePin )
{
// create new pin from old one
UEdGraphPin * VariablePin = CreatePin ( Direction , TEXT ( " " ) , TEXT ( " " ) , NULL , false , false , PinName ) ;
VariablePin - > PinType = OldVariablePin - > PinType ;
const UEdGraphSchema_K2 * K2Schema = GetDefault < UEdGraphSchema_K2 > ( ) ;
K2Schema - > SetPinDefaultValueBasedOnType ( VariablePin ) ;
Message_Note ( * FString : : Printf ( TEXT ( " Pin for variable '%s' recreated, but the variable is missing. " ) , * PinName ) ) ;
return true ;
}
else
{
Message_Warn ( * FString : : Printf ( TEXT ( " RecreatePinForVariable: '%s' pin not found " ) , * PinName ) ) ;
return false ;
}
}
FLinearColor UK2Node_Variable : : GetNodeTitleColor ( ) const
{
UProperty * VariableProperty = GetPropertyForVariable ( ) ;
if ( VariableProperty )
{
const UEdGraphSchema_K2 * K2Schema = GetDefault < UEdGraphSchema_K2 > ( ) ;
FEdGraphPinType VariablePinType ;
K2Schema - > ConvertPropertyToPinType ( VariableProperty , VariablePinType ) ;
return K2Schema - > GetPinTypeColor ( VariablePinType ) ;
}
return FLinearColor : : White ;
}
UK2Node : : ERedirectType UK2Node_Variable : : DoPinsMatchForReconstruction ( const UEdGraphPin * NewPin , int32 NewPinIndex , const UEdGraphPin * OldPin , int32 OldPinIndex ) const
{
const UEdGraphSchema_K2 * K2Schema = GetDefault < UEdGraphSchema_K2 > ( ) ;
if ( OldPin - > PinType . PinCategory = = K2Schema - > PC_Exec )
{
return Super : : DoPinsMatchForReconstruction ( NewPin , NewPinIndex , OldPin , OldPinIndex ) ;
}
2014-04-23 18:19:54 -04:00
const bool bCanMatchSelfs = ( ( OldPin - > PinName = = K2Schema - > PN_Self ) = = ( NewPin - > PinName = = K2Schema - > PN_Self ) ) ;
const bool bTheSameDirection = ( NewPin - > Direction = = OldPin - > Direction ) ;
if ( bCanMatchSelfs & & bTheSameDirection )
2014-03-14 14:13:41 -04:00
{
2014-04-23 18:19:54 -04:00
if ( K2Schema - > ArePinTypesCompatible ( NewPin - > PinType , OldPin - > PinType ) )
2014-03-14 14:13:41 -04:00
{
2014-07-15 15:51:15 -04:00
// If these are split pins, we need to do some name checking logic
if ( NewPin - > ParentPin )
{
// If the OldPin is not split, then these don't match
if ( OldPin - > ParentPin = = nullptr )
{
return ERedirectType_None ;
}
// Go through and find the original variable pin.
// If the number of steps out to the original variable pin is not the same then these don't match
const UEdGraphPin * ParentmostNewPin = NewPin ;
const UEdGraphPin * ParentmostOldPin = OldPin ;
while ( ParentmostNewPin - > ParentPin )
{
if ( ParentmostOldPin - > ParentPin = = nullptr )
{
return ERedirectType_None ;
}
ParentmostNewPin = ParentmostNewPin - > ParentPin ;
ParentmostOldPin = ParentmostOldPin - > ParentPin ;
}
if ( ParentmostOldPin - > ParentPin )
{
return ERedirectType_None ;
}
// Compare whether the names, ignoring the original variable's name in the case of renames, match
FString NewPinPropertyName = NewPin - > PinName . RightChop ( ParentmostNewPin - > PinName . Len ( ) + 1 ) ;
FString OldPinPropertyName = OldPin - > PinName . RightChop ( ParentmostOldPin - > PinName . Len ( ) + 1 ) ;
if ( NewPinPropertyName ! = OldPinPropertyName )
{
return ERedirectType_None ;
}
}
2014-03-14 14:13:41 -04:00
return ERedirectType_Name ;
}
2014-04-23 18:19:54 -04:00
else if ( ( OldPin - > PinName = = NewPin - > PinName ) & & ( ( NewPin - > PinType . PinCategory = = K2Schema - > PC_Object ) | |
( NewPin - > PinType . PinCategory = = K2Schema - > PC_Interface ) ) & & ( NewPin - > PinType . PinSubCategoryObject = = NULL ) )
{
// Special Case: If we had a pin match, and the class isn't loaded yet because of a cyclic dependency, temporarily cast away the const, and fix up.
// @TODO: Fix this up to be less hacky
UBlueprintGeneratedClass * TypeClass = Cast < UBlueprintGeneratedClass > ( OldPin - > PinType . PinSubCategoryObject . Get ( ) ) ;
if ( TypeClass & & TypeClass - > ClassGeneratedBy & & TypeClass - > ClassGeneratedBy - > HasAnyFlags ( RF_BeingRegenerated ) )
{
UEdGraphPin * NonConstNewPin = ( UEdGraphPin * ) NewPin ;
NonConstNewPin - > PinType . PinSubCategoryObject = OldPin - > PinType . PinSubCategoryObject . Get ( ) ;
return ERedirectType_Name ;
}
}
else
{
// Special Case: If we're migrating from old blueprint references to class references, allow pins to be reconnected if coerced
const UClass * PSCOClass = Cast < UClass > ( OldPin - > PinType . PinSubCategoryObject . Get ( ) ) ;
const bool bOldIsBlueprint = PSCOClass & & PSCOClass - > IsChildOf ( UBlueprint : : StaticClass ( ) ) ;
const bool bNewIsClass = ( NewPin - > PinType . PinCategory = = K2Schema - > PC_Class ) ;
if ( bNewIsClass & & bOldIsBlueprint )
{
UEdGraphPin * OldPinNonConst = ( UEdGraphPin * ) OldPin ;
OldPinNonConst - > PinName = NewPin - > PinName ;
return ERedirectType_Name ;
}
}
2014-03-14 14:13:41 -04:00
}
return ERedirectType_None ;
}
UClass * UK2Node_Variable : : GetVariableSourceClass ( ) const
{
UClass * Result = VariableReference . GetMemberParentClass ( this ) ;
return Result ;
}
UProperty * UK2Node_Variable : : GetPropertyForVariable ( ) const
{
const FName VarName = GetVarName ( ) ;
UEdGraphPin * VariablePin = FindPin ( GetVarNameString ( ) ) ;
UProperty * VariableProperty = VariableReference . ResolveMember < UProperty > ( this ) ;
// if the variable has been deprecated, don't use it
if ( VariableProperty ! = NULL )
{
if ( VariableProperty - > HasAllPropertyFlags ( CPF_Deprecated ) )
{
VariableProperty = NULL ;
}
// If the variable has been remapped update the pin
else if ( VariablePin & & VarName ! = GetVarName ( ) )
{
VariablePin - > PinName = GetVarNameString ( ) ;
}
}
return VariableProperty ;
}
UEdGraphPin * UK2Node_Variable : : GetValuePin ( ) const
{
UEdGraphPin * Pin = FindPin ( GetVarNameString ( ) ) ;
check ( Pin = = NULL | | Pin - > Direction = = EGPD_Output ) ;
return Pin ;
}
void UK2Node_Variable : : ValidateNodeDuringCompilation ( class FCompilerResultsLog & MessageLog ) const
{
Super : : ValidateNodeDuringCompilation ( MessageLog ) ;
UProperty * VariableProperty = GetPropertyForVariable ( ) ;
2014-05-09 17:43:40 -04:00
// Local variables do not exist until much later in the compilation than this function can provide
if ( VariableProperty = = NULL & & ! VariableReference . IsLocalScope ( ) )
2014-03-14 14:13:41 -04:00
{
2014-06-19 12:43:03 -04:00
if ( ! VariableReference . IsDeprecated ( ) )
{
2014-09-24 19:47:30 -04:00
FString OwnerName ;
UBlueprint * Blueprint = GetBlueprint ( ) ;
if ( Blueprint ! = nullptr )
{
OwnerName = Blueprint - > GetName ( ) ;
if ( UClass * VarOwnerClass = VariableReference . GetMemberParentClass ( Blueprint - > GeneratedClass ) )
{
OwnerName = VarOwnerClass - > GetName ( ) ;
}
}
2014-09-24 14:15:01 -04:00
FString const VarName = VariableReference . GetMemberName ( ) . ToString ( ) ;
FText const WarningFormat = LOCTEXT ( " VariableNotFound " , " Could not find a variable named \" %s \" in '%s'. \n Make sure '%s' has been compiled for @@ " ) ;
MessageLog . Warning ( * FString : : Printf ( * WarningFormat . ToString ( ) , * VarName , * OwnerName , * OwnerName ) , this ) ;
2014-06-19 12:43:03 -04:00
}
else
{
MessageLog . Warning ( * FString : : Printf ( * LOCTEXT ( " VariableDeprecated " , " Variable '%s' for @@ was deprecated. Please update it. " ) . ToString ( ) , * VariableReference . GetMemberName ( ) . ToString ( ) ) , this ) ;
}
2014-03-14 14:13:41 -04:00
}
2014-08-05 14:16:02 -04:00
if ( VariableProperty & & ( VariableProperty - > ArrayDim > 1 ) )
{
MessageLog . Warning ( * LOCTEXT ( " StaticArray_Warning " , " @@ - the native property is a static array, which is not supported by blueprints " ) . ToString ( ) , this ) ;
}
2014-03-14 14:13:41 -04:00
}
FName UK2Node_Variable : : GetPaletteIcon ( FLinearColor & ColorOut ) const
{
2014-05-09 17:43:40 -04:00
FName ReturnIconName ;
if ( VariableReference . IsLocalScope ( ) )
{
ReturnIconName = GetVariableIconAndColor ( VariableReference . GetMemberScope ( this ) , GetVarName ( ) , ColorOut ) ;
}
else
{
ReturnIconName = GetVariableIconAndColor ( GetVariableSourceClass ( ) , GetVarName ( ) , ColorOut ) ;
}
return ReturnIconName ;
2014-03-14 14:13:41 -04:00
}
2014-06-19 11:32:47 -04:00
FName UK2Node_Variable : : GetVarIconFromPinType ( const FEdGraphPinType & InPinType , FLinearColor & IconColorOut )
2014-03-14 14:13:41 -04:00
{
FName IconBrush = TEXT ( " Kismet.AllClasses.VariableIcon " ) ;
const UEdGraphSchema_K2 * K2Schema = GetDefault < UEdGraphSchema_K2 > ( ) ;
IconColorOut = K2Schema - > GetPinTypeColor ( InPinType ) ;
if ( InPinType . bIsArray )
{
IconBrush = TEXT ( " Kismet.AllClasses.ArrayVariableIcon " ) ;
}
else if ( InPinType . PinSubCategoryObject . IsValid ( ) )
{
2014-06-19 11:32:47 -04:00
if ( UClass * Class = Cast < UClass > ( InPinType . PinSubCategoryObject . Get ( ) ) )
2014-03-14 14:13:41 -04:00
{
2014-06-19 11:32:47 -04:00
IconBrush = FClassIconFinder : : FindIconNameForClass ( Class ) ;
2014-03-14 14:13:41 -04:00
}
}
return IconBrush ;
}
FText UK2Node_Variable : : GetToolTipHeading ( ) const
{
FText Heading = Super : : GetToolTipHeading ( ) ;
UProperty const * VariableProperty = VariableReference . ResolveMember < UProperty > ( this ) ;
if ( VariableProperty & & VariableProperty - > HasAllPropertyFlags ( CPF_Net ) )
{
FText ReplicatedTag = LOCTEXT ( " ReplicatedVar " , " Replicated " ) ;
if ( Heading . IsEmpty ( ) )
{
Heading = ReplicatedTag ;
}
else
{
Heading = FText : : Format ( FText : : FromString ( " {0} \n {1} " ) , ReplicatedTag , Heading ) ;
}
}
return Heading ;
}
2014-06-06 18:51:05 -04:00
void UK2Node_Variable : : GetNodeAttributes ( TArray < TKeyValuePair < FString , FString > > & OutNodeAttributes ) const
{
UProperty * VariableProperty = GetPropertyForVariable ( ) ;
const FString VariableName = VariableProperty ? VariableProperty - > GetName ( ) : TEXT ( " InvalidVariable " ) ;
OutNodeAttributes . Add ( TKeyValuePair < FString , FString > ( TEXT ( " Type " ) , TEXT ( " Variable " ) ) ) ;
OutNodeAttributes . Add ( TKeyValuePair < FString , FString > ( TEXT ( " Class " ) , GetClass ( ) - > GetName ( ) ) ) ;
OutNodeAttributes . Add ( TKeyValuePair < FString , FString > ( TEXT ( " Name " ) , VariableName ) ) ;
}
2014-07-18 14:21:23 -04:00
FName UK2Node_Variable : : GetVariableIconAndColor ( const UStruct * VarScope , FName VarName , FLinearColor & IconColorOut )
2014-03-14 14:13:41 -04:00
{
FName IconBrush = TEXT ( " Kismet.AllClasses.VariableIcon " ) ;
2014-05-09 17:43:40 -04:00
if ( VarScope ! = NULL )
2014-03-14 14:13:41 -04:00
{
2014-05-09 17:43:40 -04:00
UProperty * Property = FindField < UProperty > ( VarScope , VarName ) ;
2014-03-14 14:13:41 -04:00
if ( Property ! = NULL )
{
const UEdGraphSchema_K2 * K2Schema = GetDefault < UEdGraphSchema_K2 > ( ) ;
FEdGraphPinType PinType ;
if ( K2Schema - > ConvertPropertyToPinType ( Property , PinType ) ) // use schema to get the color
{
IconBrush = GetVarIconFromPinType ( PinType , IconColorOut ) ;
}
}
}
return IconBrush ;
}
void UK2Node_Variable : : CheckForErrors ( const UEdGraphSchema_K2 * Schema , FCompilerResultsLog & MessageLog )
{
if ( ! VariableReference . IsSelfContext ( ) & & VariableReference . GetMemberParentClass ( this ) ! = NULL )
{
// Check to see if we're not a self context, if we have a valid context. It may have been purged because of a dead execution chain
UEdGraphPin * ContextPin = Schema - > FindSelfPin ( * this , EGPD_Input ) ;
if ( ( ContextPin ! = NULL ) & & ( ContextPin - > LinkedTo . Num ( ) = = 0 ) & & ( ContextPin - > DefaultObject = = NULL ) )
{
MessageLog . Error ( * LOCTEXT ( " VarNodeError_InvalidVarTarget " , " Variable node @@ uses an invalid target. It may depend on a node that is not connected to the execution chain, and got purged. " ) . ToString ( ) , this ) ;
}
}
}
void UK2Node_Variable : : ReconstructNode ( )
{
// update the variable reference if the property was renamed
UClass * const VarClass = GetVariableSourceClass ( ) ;
if ( VarClass )
{
UClass * SearchClass = VarClass ;
while ( SearchClass ! = NULL )
{
const TMap < FName , FName > * const ClassTaggedPropertyRedirects = UStruct : : TaggedPropertyRedirects . Find ( SearchClass - > GetFName ( ) ) ;
if ( ClassTaggedPropertyRedirects )
{
const FName * const NewPropertyName = ClassTaggedPropertyRedirects - > Find ( VariableReference . GetMemberName ( ) ) ;
if ( NewPropertyName )
{
if ( VariableReference . IsSelfContext ( ) )
{
VariableReference . SetSelfMember ( * NewPropertyName ) ;
}
else
{
VariableReference . SetExternalMember ( * NewPropertyName , VarClass ) ;
}
// found, can break
break ;
}
}
SearchClass = SearchClass - > GetSuperClass ( ) ;
}
}
const FGuid VarGuid = VariableReference . GetMemberGuid ( ) ;
if ( VarGuid . IsValid ( ) )
{
const FName VarName = UBlueprint : : GetFieldNameFromClassByGuid < UProperty > ( VarClass , VarGuid ) ;
if ( VarName ! = NAME_None & & VarName ! = VariableReference . GetMemberName ( ) )
{
if ( VariableReference . IsSelfContext ( ) )
{
VariableReference . SetSelfMember ( VarName ) ;
}
else
{
VariableReference . SetExternalMember ( VarName , VarClass ) ;
}
}
}
Super : : ReconstructNode ( ) ;
}
FName UK2Node_Variable : : GetCornerIcon ( ) const
{
const UProperty * VariableProperty = VariableReference . ResolveMember < UProperty > ( this ) ;
if ( VariableProperty & & VariableProperty - > HasAllPropertyFlags ( CPF_Net ) )
{
return TEXT ( " Graph.Replication.Replicated " ) ;
}
return Super : : GetCornerIcon ( ) ;
}
bool UK2Node_Variable : : HasExternalBlueprintDependencies ( TArray < class UStruct * > * OptionalOutput ) const
{
UClass * SourceClass = GetVariableSourceClass ( ) ;
UBlueprint * SourceBlueprint = GetBlueprint ( ) ;
const bool bResult = ( SourceClass & & ( SourceClass - > ClassGeneratedBy ! = NULL ) & & ( SourceClass - > ClassGeneratedBy ! = SourceBlueprint ) ) ;
if ( bResult & & OptionalOutput )
{
OptionalOutput - > Add ( SourceClass ) ;
}
2014-04-23 20:18:55 -04:00
return bResult | | Super : : HasExternalBlueprintDependencies ( OptionalOutput ) ;
2014-03-14 14:13:41 -04:00
}
FString UK2Node_Variable : : GetDocumentationLink ( ) const
{
if ( UProperty * Property = GetPropertyForVariable ( ) )
{
// discover if the variable property is a non blueprint user variable
UClass * SourceClass = Property - > GetOwnerClass ( ) ;
if ( SourceClass & & SourceClass - > ClassGeneratedBy = = NULL )
{
UStruct * OwnerStruct = Property - > GetOwnerStruct ( ) ;
if ( OwnerStruct )
{
return FString : : Printf ( TEXT ( " Shared/Types/%s%s " ) , OwnerStruct - > GetPrefixCPP ( ) , * OwnerStruct - > GetName ( ) ) ;
}
}
}
return TEXT ( " " ) ;
}
FString UK2Node_Variable : : GetDocumentationExcerptName ( ) const
{
return GetVarName ( ) . ToString ( ) ;
}
2014-10-01 11:49:19 -04:00
void UK2Node_Variable : : AutowireNewNode ( UEdGraphPin * FromPin )
{
const UEdGraphSchema_K2 * K2Schema = CastChecked < UEdGraphSchema_K2 > ( GetSchema ( ) ) ;
// Do some auto-connection
if ( FromPin ! = NULL )
{
bool bConnected = false ;
if ( FromPin - > Direction = = EGPD_Output )
{
// If the source pin has a valid PinSubCategoryObject, we might be doing BP Comms, so check if it is a class
if ( FromPin - > PinType . PinSubCategoryObject . IsValid ( ) & & FromPin - > PinType . PinSubCategoryObject - > IsA ( UClass : : StaticClass ( ) ) )
{
UProperty * VariableProperty = VariableReference . ResolveMember < UProperty > ( this ) ;
if ( VariableProperty )
{
UClass * PropertyOwner = VariableProperty - > GetOwnerClass ( ) ;
2014-10-01 13:44:39 -04:00
if ( PropertyOwner ! = nullptr )
{
PropertyOwner = PropertyOwner - > GetAuthoritativeClass ( ) ;
}
2014-10-01 11:49:19 -04:00
// BP Comms is highly likely at this point, if the source pin's type is a child of the variable's owner class, let's conform the "Target" pin
if ( FromPin - > PinType . PinSubCategoryObject = = PropertyOwner | | dynamic_cast < UClass * > ( FromPin - > PinType . PinSubCategoryObject . Get ( ) ) - > IsChildOf ( PropertyOwner ) )
{
UEdGraphPin * TargetPin = FindPin ( K2Schema - > PN_Self ) ;
TargetPin - > PinType . PinSubCategoryObject = PropertyOwner ;
if ( K2Schema - > TryCreateConnection ( FromPin , TargetPin ) )
{
bConnected = true ;
// Setup the VariableReference correctly since it may no longer be a self member
VariableReference . SetFromField < UProperty > ( GetPropertyForVariable ( ) , false ) ;
TargetPin - > bHidden = false ;
FromPin - > GetOwningNode ( ) - > NodeConnectionListChanged ( ) ;
this - > NodeConnectionListChanged ( ) ;
}
}
}
}
}
if ( ! bConnected )
{
Super : : AutowireNewNode ( FromPin ) ;
}
}
}
2014-09-12 12:56:24 -04:00
FBPVariableDescription const * UK2Node_Variable : : GetBlueprintVarDescription ( ) const
{
FName const & VarName = VariableReference . GetMemberName ( ) ;
UStruct const * VariableScope = VariableReference . GetMemberScope ( this ) ;
bool const bIsLocalVariable = ( VariableScope ! = nullptr ) ;
if ( bIsLocalVariable )
{
return FBlueprintEditorUtils : : FindLocalVariable ( GetBlueprint ( ) , VariableScope , VarName ) ;
}
else if ( UProperty const * VarProperty = GetPropertyForVariable ( ) )
{
UClass const * SourceClass = VarProperty - > GetOwnerClass ( ) ;
UBlueprint const * SourceBlueprint = ( SourceClass ! = nullptr ) ? Cast < UBlueprint > ( SourceClass - > ClassGeneratedBy ) : nullptr ;
if ( SourceBlueprint ! = nullptr )
{
int32 const VarIndex = FBlueprintEditorUtils : : FindNewVariableIndex ( SourceBlueprint , VarName ) ;
return & SourceBlueprint - > NewVariables [ VarIndex ] ;
}
}
return nullptr ;
}
2014-10-07 16:04:29 -04:00
bool UK2Node_Variable : : CanPasteHere ( const UEdGraph * TargetGraph ) const
{
// Do not allow pasting of variables in BPs that cannot handle them
if ( FBlueprintEditorUtils : : FindBlueprintForGraph ( TargetGraph ) - > BlueprintType = = BPTYPE_MacroLibrary & & VariableReference . IsSelfContext ( ) )
{
// Self variables must be from a parent class to the macro BP
if ( UProperty * Property = VariableReference . ResolveMember < UProperty > ( this ) )
{
const UClass * CurrentClass = GetBlueprint ( ) - > SkeletonGeneratedClass - > GetAuthoritativeClass ( ) ;
const UClass * PropertyClass = Property - > GetOwnerClass ( ) - > GetAuthoritativeClass ( ) ;
const bool bIsChildOf = CurrentClass - > IsChildOf ( PropertyClass ) ;
return bIsChildOf ;
}
return false ;
}
return true ;
}
2014-03-14 14:13:41 -04:00
# undef LOCTEXT_NAMESPACE