| 
							
							
							
						 |  |  | @@ -0,0 +1,560 @@ | 
		
	
		
			
				|  |  |  |  | #include "CustomBlueprintsEditor.h" | 
		
	
		
			
				|  |  |  |  | #include "SpawnActorBaseNode.h" | 
		
	
		
			
				|  |  |  |  | #include "Globals.h" | 
		
	
		
			
				|  |  |  |  | #include "BlueprintEditorUtils.h" | 
		
	
		
			
				|  |  |  |  | #include "BlueprintActionDatabaseRegistrar.h" | 
		
	
		
			
				|  |  |  |  | #include "BlueprintNodeSpawner.h" | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | struct FK2Node_SpawnActorFromClassHelper | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	static FString WorldContextPinName; | 
		
	
		
			
				|  |  |  |  | 	static FString ClassPinName; | 
		
	
		
			
				|  |  |  |  | 	static FString SpawnTransformPinName; | 
		
	
		
			
				|  |  |  |  | 	static FString TargetPinName; | 
		
	
		
			
				|  |  |  |  | }; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | FString FK2Node_SpawnActorFromClassHelper::WorldContextPinName(TEXT("WorldContextObject")); | 
		
	
		
			
				|  |  |  |  | FString FK2Node_SpawnActorFromClassHelper::ClassPinName(TEXT("Class")); | 
		
	
		
			
				|  |  |  |  | FString FK2Node_SpawnActorFromClassHelper::SpawnTransformPinName(TEXT("SpawnTransform")); | 
		
	
		
			
				|  |  |  |  | FString FK2Node_SpawnActorFromClassHelper::TargetPinName(TEXT("Target")); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #define FMT_TEXT(__x) FText::FromString(FString() + __x) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | UK2Node_SpawnActorBaseNode::UK2Node_SpawnActorBaseNode(const FObjectInitializer& ObjectInitializer) | 
		
	
		
			
				|  |  |  |  | 	: Super(ObjectInitializer) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	NodeTooltip = FMT_TEXT("Oh Nooooos"); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void UK2Node_SpawnActorBaseNode::AllocateDefaultPins() | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Add execution pins | 
		
	
		
			
				|  |  |  |  | 	CreatePin(EGPD_Input, K2Schema->PC_Exec, TEXT(""), NULL, false, false, K2Schema->PN_Execute); | 
		
	
		
			
				|  |  |  |  | 	CreatePin(EGPD_Output, K2Schema->PC_Exec, TEXT(""), NULL, false, false, K2Schema->PN_Then); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// If required add the world context pin | 
		
	
		
			
				|  |  |  |  | 	if(GetBlueprint()->ParentClass->HasMetaData(FBlueprintMetadata::MD_ShowWorldContextPin)) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		CreatePin(EGPD_Input, K2Schema->PC_Object, TEXT(""), UObject::StaticClass(), false, false, FK2Node_SpawnActorFromClassHelper::WorldContextPinName); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Add blueprint pin | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* ClassPin = CreatePin(EGPD_Input, K2Schema->PC_Class, TEXT(""), GetActorClass(), false, false, FK2Node_SpawnActorFromClassHelper::ClassPinName); | 
		
	
		
			
				|  |  |  |  | 	K2Schema->ConstructBasicPinTooltip(*ClassPin, FMT_TEXT("The " + GetObjectName() + " you want to spawn"), ClassPin->PinToolTip); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Transform pin | 
		
	
		
			
				|  |  |  |  | 	if(SpawningFunctionHasTransform()) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		UScriptStruct* TransformStruct = TBaseStructure<FTransform>::Get(); | 
		
	
		
			
				|  |  |  |  | 		UEdGraphPin* TransformPin = CreatePin(EGPD_Input, K2Schema->PC_Struct, TEXT(""), TransformStruct, false, false, FK2Node_SpawnActorFromClassHelper::SpawnTransformPinName); | 
		
	
		
			
				|  |  |  |  | 		K2Schema->ConstructBasicPinTooltip(*TransformPin, FMT_TEXT("The transform to spawn the " + GetObjectName() + " with"), TransformPin->PinToolTip); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Result pin | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* ResultPin = CreatePin(EGPD_Output, K2Schema->PC_Object, TEXT(""), GetActorClass(), false, false, K2Schema->PN_ReturnValue); | 
		
	
		
			
				|  |  |  |  | 	K2Schema->ConstructBasicPinTooltip(*ResultPin, FMT_TEXT("The spawned " + GetObjectName()), ResultPin->PinToolTip); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	RegisterAdditionalPins(K2Schema); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	Super::AllocateDefaultPins(); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void UK2Node_SpawnActorBaseNode::CreatePinsForClass(UClass* InClass, TArray<UEdGraphPin*>& OutClassPins) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	check(InClass != NULL); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	const UObject* const ClassDefaultObject = InClass->GetDefaultObject(false); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	for(TFieldIterator<UProperty> PropertyIt(InClass, EFieldIteratorFlags::IncludeSuper); PropertyIt; ++PropertyIt) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		UProperty* Property = *PropertyIt; | 
		
	
		
			
				|  |  |  |  | 		UClass* PropertyClass = CastChecked<UClass>(Property->GetOuter()); | 
		
	
		
			
				|  |  |  |  | 		const bool bIsDelegate = Property->IsA(UMulticastDelegateProperty::StaticClass()); | 
		
	
		
			
				|  |  |  |  | 		const bool bIsExposedToSpawn = UEdGraphSchema_K2::IsPropertyExposedOnSpawn(Property); | 
		
	
		
			
				|  |  |  |  | 		const bool bIsSettableExternally = !Property->HasAnyPropertyFlags(CPF_DisableEditOnInstance); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		if(bIsExposedToSpawn && | 
		
	
		
			
				|  |  |  |  | 			!Property->HasAnyPropertyFlags(CPF_Parm) && | 
		
	
		
			
				|  |  |  |  | 			bIsSettableExternally && | 
		
	
		
			
				|  |  |  |  | 			Property->HasAllPropertyFlags(CPF_BlueprintVisible) && | 
		
	
		
			
				|  |  |  |  | 			!bIsDelegate && | 
		
	
		
			
				|  |  |  |  | 			(NULL == FindPin(Property->GetName()))) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			UEdGraphPin* Pin = CreatePin(EGPD_Input, TEXT(""), TEXT(""), NULL, false, false, Property->GetName()); | 
		
	
		
			
				|  |  |  |  | 			const bool bPinGood = (Pin != NULL) && K2Schema->ConvertPropertyToPinType(Property, Pin->PinType); | 
		
	
		
			
				|  |  |  |  | 			OutClassPins.Add(Pin); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 			if(ClassDefaultObject && Pin != NULL && K2Schema->PinDefaultValueIsEditable(*Pin)) | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				FString DefaultValueAsString; | 
		
	
		
			
				|  |  |  |  | 				const bool bDefaultValueSet = FBlueprintEditorUtils::PropertyValueToString(Property, reinterpret_cast<const uint8*>(ClassDefaultObject), DefaultValueAsString); | 
		
	
		
			
				|  |  |  |  | 				check(bDefaultValueSet); | 
		
	
		
			
				|  |  |  |  | 				K2Schema->TrySetDefaultValue(*Pin, DefaultValueAsString); | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 			// Copy tooltip from the property. | 
		
	
		
			
				|  |  |  |  | 			if(Pin != nullptr) | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				K2Schema->ConstructBasicPinTooltip(*Pin, Property->GetToolTipText(), Pin->PinToolTip); | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Change class of output pin | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* ResultPin = GetResultPin(); | 
		
	
		
			
				|  |  |  |  | 	ResultPin->PinType.PinSubCategoryObject = InClass; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | UClass* UK2Node_SpawnActorBaseNode::GetClassToSpawn(const TArray<UEdGraphPin*>* InPinsToSearch) const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	UClass* UseSpawnClass = nullptr; | 
		
	
		
			
				|  |  |  |  | 	const TArray<UEdGraphPin*>* PinsToSearch = InPinsToSearch ? InPinsToSearch : &Pins; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* ClassPin = GetClassPin(PinsToSearch); | 
		
	
		
			
				|  |  |  |  | 	if(ClassPin && ClassPin->DefaultObject != NULL && ClassPin->LinkedTo.Num() == 0) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		UseSpawnClass = CastChecked<UClass>(ClassPin->DefaultObject); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else if(ClassPin && (1 == ClassPin->LinkedTo.Num())) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		auto SourcePin = ClassPin->LinkedTo[0]; | 
		
	
		
			
				|  |  |  |  | 		UseSpawnClass = SourcePin ? Cast<UClass>(SourcePin->PinType.PinSubCategoryObject.Get()) : nullptr; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	return UseSpawnClass; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void UK2Node_SpawnActorBaseNode::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	AllocateDefaultPins(); | 
		
	
		
			
				|  |  |  |  | 	UClass* UseSpawnClass = GetClassToSpawn(&OldPins); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	if(UseSpawnClass != NULL) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		// Reassign class pin | 
		
	
		
			
				|  |  |  |  | 		UEdGraphPin* newClassPin = FindPinChecked(FK2Node_SpawnActorFromClassHelper::ClassPinName); | 
		
	
		
			
				|  |  |  |  | 		newClassPin->DefaultObject = UseSpawnClass; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 		TArray<UEdGraphPin*> ClassPins; | 
		
	
		
			
				|  |  |  |  | 		CreatePinsForClass(UseSpawnClass, ClassPins); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void UK2Node_SpawnActorBaseNode::PostPlacedNewNode() | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	Super::PostPlacedNewNode(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UClass* UseSpawnClass = GetClassToSpawn(); | 
		
	
		
			
				|  |  |  |  | 	if(UseSpawnClass != NULL) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		TArray<UEdGraphPin*> ClassPins; | 
		
	
		
			
				|  |  |  |  | 		CreatePinsForClass(UseSpawnClass, ClassPins); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | bool UK2Node_SpawnActorBaseNode::IsSpawnVarPin(UEdGraphPin* Pin) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* ParentPin = Pin->ParentPin; | 
		
	
		
			
				|  |  |  |  | 	while(ParentPin) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		if(ParentPin->PinName == FK2Node_SpawnActorFromClassHelper::SpawnTransformPinName) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			return false; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		ParentPin = ParentPin->ParentPin; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	return(Pin->PinName != K2Schema->PN_Execute && | 
		
	
		
			
				|  |  |  |  | 		Pin->PinName != K2Schema->PN_Then && | 
		
	
		
			
				|  |  |  |  | 		Pin->PinName != K2Schema->PN_ReturnValue && | 
		
	
		
			
				|  |  |  |  | 		Pin->PinName != FK2Node_SpawnActorFromClassHelper::ClassPinName && | 
		
	
		
			
				|  |  |  |  | 		Pin->PinName != FK2Node_SpawnActorFromClassHelper::WorldContextPinName && | 
		
	
		
			
				|  |  |  |  | 		Pin->PinName != FK2Node_SpawnActorFromClassHelper::SpawnTransformPinName && | 
		
	
		
			
				|  |  |  |  | 		Pin->PinName != FK2Node_SpawnActorFromClassHelper::TargetPinName && | 
		
	
		
			
				|  |  |  |  | 		!IsAdditionalPin(Pin)); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void UK2Node_SpawnActorBaseNode::OnClassPinChanged() | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Remove all pins related to archetype variables | 
		
	
		
			
				|  |  |  |  | 	TArray<UEdGraphPin*> OldPins = Pins; | 
		
	
		
			
				|  |  |  |  | 	TArray<UEdGraphPin*> OldClassPins; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	for(int32 i = 0; i < OldPins.Num(); i++) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		UEdGraphPin* OldPin = OldPins[i]; | 
		
	
		
			
				|  |  |  |  | 		if(IsSpawnVarPin(OldPin)) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			Pins.Remove(OldPin); | 
		
	
		
			
				|  |  |  |  | 			OldClassPins.Add(OldPin); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	m_cachedNodeTitle.MarkDirty(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UClass* UseSpawnClass = GetClassToSpawn(); | 
		
	
		
			
				|  |  |  |  | 	TArray<UEdGraphPin*> NewClassPins; | 
		
	
		
			
				|  |  |  |  | 	if(UseSpawnClass != NULL) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		CreatePinsForClass(UseSpawnClass, NewClassPins); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* ResultPin = GetResultPin(); | 
		
	
		
			
				|  |  |  |  | 	// Cache all the pin connections to the ResultPin, we will attempt to recreate them | 
		
	
		
			
				|  |  |  |  | 	TArray<UEdGraphPin*> ResultPinConnectionList = ResultPin->LinkedTo; | 
		
	
		
			
				|  |  |  |  | 	// Because the archetype has changed, we break the output link as the output pin type will change | 
		
	
		
			
				|  |  |  |  | 	ResultPin->BreakAllPinLinks(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Recreate any pin links to the Result pin that are still valid | 
		
	
		
			
				|  |  |  |  | 	for(UEdGraphPin* Connections : ResultPinConnectionList) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		K2Schema->TryCreateConnection(ResultPin, Connections); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	K2Schema->ConstructBasicPinTooltip(*ResultPin, FMT_TEXT("The spawned " + GetObjectName()), ResultPin->PinToolTip); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Rewire the old pins to the new pins so connections are maintained if possible | 
		
	
		
			
				|  |  |  |  | 	RewireOldPinsToNewPins(OldClassPins, NewClassPins); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Destroy the old pins | 
		
	
		
			
				|  |  |  |  | 	DestroyPinList(OldClassPins); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Refresh the UI for the graph so the pin changes show up | 
		
	
		
			
				|  |  |  |  | 	UEdGraph* Graph = GetGraph(); | 
		
	
		
			
				|  |  |  |  | 	Graph->NotifyGraphChanged(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Mark dirty | 
		
	
		
			
				|  |  |  |  | 	FBlueprintEditorUtils::MarkBlueprintAsModified(GetBlueprint()); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void UK2Node_SpawnActorBaseNode::PinConnectionListChanged(UEdGraphPin* ChangedPin) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	if(ChangedPin && (ChangedPin->PinName == FK2Node_SpawnActorFromClassHelper::ClassPinName)) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		OnClassPinChanged(); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void UK2Node_SpawnActorBaseNode::PinDefaultValueChanged(UEdGraphPin* ChangedPin) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	if(ChangedPin && (ChangedPin->PinName == FK2Node_SpawnActorFromClassHelper::ClassPinName)) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		OnClassPinChanged(); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | FText UK2Node_SpawnActorBaseNode::GetTooltipText() const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	return NodeTooltip; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | UEdGraphPin* UK2Node_SpawnActorBaseNode::GetThenPin()const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* Pin = FindPinChecked(K2Schema->PN_Then); | 
		
	
		
			
				|  |  |  |  | 	check(Pin->Direction == EGPD_Output); | 
		
	
		
			
				|  |  |  |  | 	return Pin; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | UEdGraphPin* UK2Node_SpawnActorBaseNode::GetClassPin(const TArray<UEdGraphPin*>* InPinsToSearch) const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	const TArray<UEdGraphPin*>* PinsToSearch = InPinsToSearch ? InPinsToSearch : &Pins; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* Pin = NULL; | 
		
	
		
			
				|  |  |  |  | 	for(auto PinIt = PinsToSearch->CreateConstIterator(); PinIt; ++PinIt) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		UEdGraphPin* TestPin = *PinIt; | 
		
	
		
			
				|  |  |  |  | 		if(TestPin && TestPin->PinName == FK2Node_SpawnActorFromClassHelper::ClassPinName) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			Pin = TestPin; | 
		
	
		
			
				|  |  |  |  | 			break; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	check(Pin == NULL || Pin->Direction == EGPD_Input); | 
		
	
		
			
				|  |  |  |  | 	return Pin; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | UEdGraphPin* UK2Node_SpawnActorBaseNode::GetSpawnTransformPin() const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* Pin = FindPinChecked(FK2Node_SpawnActorFromClassHelper::SpawnTransformPinName); | 
		
	
		
			
				|  |  |  |  | 	check(Pin->Direction == EGPD_Input); | 
		
	
		
			
				|  |  |  |  | 	return Pin; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | UEdGraphPin* UK2Node_SpawnActorBaseNode::GetWorldContextPin() const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* Pin = FindPin(FK2Node_SpawnActorFromClassHelper::WorldContextPinName); | 
		
	
		
			
				|  |  |  |  | 	check(Pin == NULL || Pin->Direction == EGPD_Input); | 
		
	
		
			
				|  |  |  |  | 	return Pin; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | UEdGraphPin* UK2Node_SpawnActorBaseNode::GetResultPin() const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* Pin = FindPinChecked(K2Schema->PN_ReturnValue); | 
		
	
		
			
				|  |  |  |  | 	check(Pin->Direction == EGPD_Output); | 
		
	
		
			
				|  |  |  |  | 	return Pin; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | FLinearColor UK2Node_SpawnActorBaseNode::GetNodeTitleColor() const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	return Super::GetNodeTitleColor(); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | FText UK2Node_SpawnActorBaseNode::GetNodeTitle(ENodeTitleType::Type TitleType) const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	FText NodeTitle = FMT_TEXT("Spawn " + GetObjectName() + " from Class"); | 
		
	
		
			
				|  |  |  |  | 	if(TitleType != ENodeTitleType::MenuTitle) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		if(UEdGraphPin* ClassPin = FindPin(FK2Node_SpawnActorFromClassHelper::ClassPinName)) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			if(ClassPin->LinkedTo.Num() > 0) | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				// Blueprint will be determined dynamically, so we don't have the name in this case | 
		
	
		
			
				|  |  |  |  | 				NodeTitle = FMT_TEXT("Spawn " + GetObjectName()); | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 			else if(ClassPin->DefaultObject == nullptr) | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				NodeTitle = FMT_TEXT("Spawn " + GetObjectName() + " NONE"); | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 			else | 
		
	
		
			
				|  |  |  |  | 			{ | 
		
	
		
			
				|  |  |  |  | 				if(m_cachedNodeTitle.IsOutOfDate(this)) | 
		
	
		
			
				|  |  |  |  | 				{ | 
		
	
		
			
				|  |  |  |  | 					FText ClassName; | 
		
	
		
			
				|  |  |  |  | 					if(UClass* PickedClass = Cast<UClass>(ClassPin->DefaultObject)) | 
		
	
		
			
				|  |  |  |  | 					{ | 
		
	
		
			
				|  |  |  |  | 						ClassName = PickedClass->GetDisplayNameText(); | 
		
	
		
			
				|  |  |  |  | 					} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 					FFormatNamedArguments Args; | 
		
	
		
			
				|  |  |  |  | 					Args.Add(TEXT("ClassName"), ClassName); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 					// FText::Format() is slow, so we cache this to save on performance | 
		
	
		
			
				|  |  |  |  | 					m_cachedNodeTitle.SetCachedText(FText::Format(FMT_TEXT("Spawn {ClassName}"), Args), this); | 
		
	
		
			
				|  |  |  |  | 				} | 
		
	
		
			
				|  |  |  |  | 				NodeTitle = m_cachedNodeTitle; | 
		
	
		
			
				|  |  |  |  | 			} | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 		else | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			NodeTitle = FMT_TEXT(GetObjectName() + " NONE"); | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	return NodeTitle; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | bool UK2Node_SpawnActorBaseNode::IsCompatibleWithGraph(const UEdGraph* TargetGraph) const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	UBlueprint* Blueprint = FBlueprintEditorUtils::FindBlueprintForGraph(TargetGraph); | 
		
	
		
			
				|  |  |  |  | 	return Super::IsCompatibleWithGraph(TargetGraph) && (!Blueprint || FBlueprintEditorUtils::FindUserConstructionScript(Blueprint) != TargetGraph); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void UK2Node_SpawnActorBaseNode::GetNodeAttributes(TArray<TKeyValuePair<FString, FString>>& OutNodeAttributes) const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	UClass* ClassToSpawn = GetClassToSpawn(); | 
		
	
		
			
				|  |  |  |  | 	const FString ClassToSpawnStr = ClassToSpawn ? ClassToSpawn->GetName() : TEXT("InvalidClass"); | 
		
	
		
			
				|  |  |  |  | 	OutNodeAttributes.Add(TKeyValuePair<FString, FString>(TEXT("Type"), FString() + "Spawn" + GetObjectName() + "FromClass")); | 
		
	
		
			
				|  |  |  |  | 	OutNodeAttributes.Add(TKeyValuePair<FString, FString>(TEXT("Class"), GetClass()->GetName())); | 
		
	
		
			
				|  |  |  |  | 	OutNodeAttributes.Add(TKeyValuePair<FString, FString>(TEXT("Name"), GetName())); | 
		
	
		
			
				|  |  |  |  | 	OutNodeAttributes.Add(TKeyValuePair<FString, FString>(TEXT("ActorClass"), ClassToSpawnStr)); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void UK2Node_SpawnActorBaseNode::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	// actions get registered under specific object-keys; the idea is that  | 
		
	
		
			
				|  |  |  |  | 	// actions might have to be updated (or deleted) if their object-key is   | 
		
	
		
			
				|  |  |  |  | 	// mutated (or removed)... here we use the node's class (so if the node  | 
		
	
		
			
				|  |  |  |  | 	// type disappears, then the action should go with it) | 
		
	
		
			
				|  |  |  |  | 	UClass* ActionKey = GetClass(); | 
		
	
		
			
				|  |  |  |  | 	//// to keep from needlessly instantiating a UBlueprintNodeSpawner, first    | 
		
	
		
			
				|  |  |  |  | 	//// check to make sure that the registrar is looking for actions of this type | 
		
	
		
			
				|  |  |  |  | 	//// (could be regenerating actions for a specific asset, and therefore the  | 
		
	
		
			
				|  |  |  |  | 	//// registrar would only accept actions corresponding to that asset) | 
		
	
		
			
				|  |  |  |  | 	if(ActionRegistrar.IsOpenForRegistration(ActionKey)) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass()); | 
		
	
		
			
				|  |  |  |  | 		check(NodeSpawner != nullptr); | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 		ActionRegistrar.AddBlueprintAction(ActionKey, NodeSpawner); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | FText UK2Node_SpawnActorBaseNode::GetMenuCategory() const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	return FMT_TEXT("Ability"); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | FNodeHandlingFunctor* UK2Node_SpawnActorBaseNode::CreateNodeHandler(FKismetCompilerContext& CompilerContext) const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	return new FNodeHandlingFunctor(CompilerContext); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void UK2Node_SpawnActorBaseNode::ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	Super::ExpandNode(CompilerContext, SourceGraph); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	if(!libClass) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		LoadDependencies(); | 
		
	
		
			
				|  |  |  |  | 		if(!libClass) | 
		
	
		
			
				|  |  |  |  | 		{ | 
		
	
		
			
				|  |  |  |  | 			CompilerContext.MessageLog.Error(L"Dependencies not initialized yet"); | 
		
	
		
			
				|  |  |  |  | 			return; | 
		
	
		
			
				|  |  |  |  | 		} | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	FName BeginSpawningBlueprintFuncName = GetBeginSpawningFunction(); | 
		
	
		
			
				|  |  |  |  | 	static FString ActorClassParamName = FString(TEXT("ActorClass")); | 
		
	
		
			
				|  |  |  |  | 	static FString WorldContextParamName = FString(TEXT("WorldContextObject")); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	FName FinishSpawningFuncName = GetFinishSpawningFunction(); | 
		
	
		
			
				|  |  |  |  | 	static FString ActorParamName = FString(TEXT("Actor")); | 
		
	
		
			
				|  |  |  |  | 	static FString TransformParamName = FString(TEXT("SpawnTransform")); | 
		
	
		
			
				|  |  |  |  | 	static FString CollisionHandlingOverrideParamName = FString(TEXT("CollisionHandlingOverride")); | 
		
	
		
			
				|  |  |  |  | 	static FString OwnerParamName = FString(TEXT("Owner")); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	static FString ObjectParamName = FString(TEXT("Object")); | 
		
	
		
			
				|  |  |  |  | 	static FString ValueParamName = FString(TEXT("Value")); | 
		
	
		
			
				|  |  |  |  | 	static FString PropertyNameParamName = FString(TEXT("PropertyName")); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UK2Node_SpawnActorBaseNode* SpawnNode = this; | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* SpawnNodeExec = SpawnNode->GetExecPin(); | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* SpawnWorldContextPin = SpawnNode->GetWorldContextPin(); | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* SpawnClassPin = SpawnNode->GetClassPin(); | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* SpawnNodeThen = SpawnNode->GetThenPin(); | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* SpawnNodeResult = SpawnNode->GetResultPin(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UClass* SpawnClass = (SpawnClassPin != NULL) ? Cast<UClass>(SpawnClassPin->DefaultObject) : NULL; | 
		
	
		
			
				|  |  |  |  | 	if((0 == SpawnClassPin->LinkedTo.Num()) && (NULL == SpawnClass)) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		CompilerContext.MessageLog.Error(L"Spawn node @@ must have a class specified.", SpawnNode); | 
		
	
		
			
				|  |  |  |  | 		// we break exec links so this is the only error we get, don't want the SpawnActor node being considered and giving 'unexpected node' type warnings | 
		
	
		
			
				|  |  |  |  | 		SpawnNode->BreakAllNodeLinks(); | 
		
	
		
			
				|  |  |  |  | 		return; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	////////////////////////////////////////////////////////////////////////// | 
		
	
		
			
				|  |  |  |  | 	// create 'begin spawn' call node | 
		
	
		
			
				|  |  |  |  | 	UK2Node_CallFunction* CallBeginSpawnNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(SpawnNode, SourceGraph); | 
		
	
		
			
				|  |  |  |  | 	CallBeginSpawnNode->FunctionReference.SetExternalMember(BeginSpawningBlueprintFuncName, libClass); | 
		
	
		
			
				|  |  |  |  | 	CallBeginSpawnNode->AllocateDefaultPins(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* CallBeginExec = CallBeginSpawnNode->GetExecPin(); | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* CallBeginWorldContextPin = CallBeginSpawnNode->FindPin(WorldContextParamName); | 
		
	
		
			
				|  |  |  |  | 	if(!CallBeginWorldContextPin) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		CompilerContext.MessageLog.Error(L"World Context Pin not found"); | 
		
	
		
			
				|  |  |  |  | 		return; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* CallBeginActorClassPin = CallBeginSpawnNode->FindPinChecked(ActorClassParamName); | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* CallBeginTransform = nullptr; | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* CallBeginResult = CallBeginSpawnNode->GetReturnValuePin(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Move 'exec' connection from spawn node to 'begin spawn' | 
		
	
		
			
				|  |  |  |  | 	CompilerContext.MovePinLinksToIntermediate(*SpawnNodeExec, *CallBeginExec); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	if(SpawnClassPin->LinkedTo.Num() > 0) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		// Copy the 'blueprint' connection from the spawn node to 'begin spawn' | 
		
	
		
			
				|  |  |  |  | 		CompilerContext.MovePinLinksToIntermediate(*SpawnClassPin, *CallBeginActorClassPin); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	else | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		// Copy blueprint literal onto begin spawn call  | 
		
	
		
			
				|  |  |  |  | 		CallBeginActorClassPin->DefaultObject = SpawnClass; | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Copy the world context connection from the spawn node to 'begin spawn' if necessary | 
		
	
		
			
				|  |  |  |  | 	if(SpawnWorldContextPin) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		CompilerContext.MovePinLinksToIntermediate(*SpawnWorldContextPin, *CallBeginWorldContextPin); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Copy the 'transform' connection from the spawn node to 'begin spawn' | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	if(SpawningFunctionHasTransform()) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		UEdGraphPin* SpawnNodeTransform = SpawnNode->GetSpawnTransformPin(); | 
		
	
		
			
				|  |  |  |  | 		CallBeginTransform = CallBeginSpawnNode->FindPinChecked(TransformParamName); | 
		
	
		
			
				|  |  |  |  | 		CompilerContext.MovePinLinksToIntermediate(*SpawnNodeTransform, *CallBeginTransform); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	ConnectAdditionalPins(CompilerContext, nullptr, CallBeginSpawnNode); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	////////////////////////////////////////////////////////////////////////// | 
		
	
		
			
				|  |  |  |  | 	// create 'finish spawn' call node | 
		
	
		
			
				|  |  |  |  | 	UK2Node_CallFunction* CallFinishSpawnNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(SpawnNode, SourceGraph); | 
		
	
		
			
				|  |  |  |  | 	CallFinishSpawnNode->FunctionReference.SetExternalMember(FinishSpawningFuncName, libClass); | 
		
	
		
			
				|  |  |  |  | 	CallFinishSpawnNode->AllocateDefaultPins(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* CallFinishExec = CallFinishSpawnNode->GetExecPin(); | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* CallFinishThen = CallFinishSpawnNode->GetThenPin(); | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* CallFinishActor = CallFinishSpawnNode->FindPinChecked(ActorParamName); | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* CallFinishResult = CallFinishSpawnNode->GetReturnValuePin(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Move 'then' connection from spawn node to 'finish spawn' | 
		
	
		
			
				|  |  |  |  | 	CompilerContext.MovePinLinksToIntermediate(*SpawnNodeThen, *CallFinishThen); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	if(SpawningFunctionHasTransform()) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		// Copy transform connection | 
		
	
		
			
				|  |  |  |  | 		UEdGraphPin* CallFinishTransform = CallFinishSpawnNode->FindPinChecked(TransformParamName); | 
		
	
		
			
				|  |  |  |  | 		CompilerContext.CopyPinLinksToIntermediate(*CallBeginTransform, *CallFinishTransform); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	ConnectAdditionalPins(CompilerContext, nullptr, CallFinishSpawnNode); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Connect output actor from 'begin' to 'finish' | 
		
	
		
			
				|  |  |  |  | 	CallBeginResult->MakeLinkTo(CallFinishActor); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Move result connection from spawn node to 'finish spawn' | 
		
	
		
			
				|  |  |  |  | 	CallFinishResult->PinType = SpawnNodeResult->PinType; // Copy type so it uses the right actor subclass | 
		
	
		
			
				|  |  |  |  | 	CompilerContext.MovePinLinksToIntermediate(*SpawnNodeResult, *CallFinishResult); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	////////////////////////////////////////////////////////////////////////// | 
		
	
		
			
				|  |  |  |  | 	// create 'set var' nodes | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Get 'result' pin from 'begin spawn', this is the actual actor we want to set properties on | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* LastThen = FKismetCompilerUtilities::GenerateAssignmentNodes(CompilerContext, SourceGraph, CallBeginSpawnNode, SpawnNode, CallBeginResult, GetClassToSpawn()); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Make exec connection between 'then' on last node and 'finish' | 
		
	
		
			
				|  |  |  |  | 	LastThen->MakeLinkTo(CallFinishExec); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 	// Break any links to the expanded node | 
		
	
		
			
				|  |  |  |  | 	SpawnNode->BreakAllNodeLinks(); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | bool UK2Node_SpawnActorBaseNode::HasExternalDependencies(TArray<class UStruct*>* OptionalOutput) const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	UClass* SourceClass = GetClassToSpawn(); | 
		
	
		
			
				|  |  |  |  | 	const UBlueprint* SourceBlueprint = GetBlueprint(); | 
		
	
		
			
				|  |  |  |  | 	const bool bResult = (SourceClass != NULL) && (SourceClass->ClassGeneratedBy != SourceBlueprint); | 
		
	
		
			
				|  |  |  |  | 	if(bResult && OptionalOutput) | 
		
	
		
			
				|  |  |  |  | 	{ | 
		
	
		
			
				|  |  |  |  | 		OptionalOutput->AddUnique(SourceClass); | 
		
	
		
			
				|  |  |  |  | 	} | 
		
	
		
			
				|  |  |  |  | 	const bool bSuperResult = Super::HasExternalDependencies(OptionalOutput); | 
		
	
		
			
				|  |  |  |  | 	return bSuperResult || bResult; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | UClass* USpawnGroupNode::GetActorClass() const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	return abilityGroupClass; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | UClass* USpawnTriggerNode::GetActorClass() const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	return abilityTriggerClass; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | UClass* USpawnModifierNode::GetActorClass() const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	return modifierClass; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void USpawnModifierNode::RegisterAdditionalPins(const class UEdGraphSchema_K2* K2Schema) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* TargetPin = CreatePin(EGPD_Input, K2Schema->PC_Object, TEXT(""), characterClass, false, false, "Target"); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | bool USpawnModifierNode::IsAdditionalPin(class UEdGraphPin* pin) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	return pin->PinName == "Target"; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | void USpawnModifierNode::ConnectAdditionalPins(class FKismetCompilerContext& CompilerContext, UK2Node* last, UK2Node* dst) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* dstPin = dst->FindPin("Target"); | 
		
	
		
			
				|  |  |  |  | 	UEdGraphPin* srcPin = FindPin("Target"); | 
		
	
		
			
				|  |  |  |  | 	if(dstPin && srcPin) | 
		
	
		
			
				|  |  |  |  | 		CompilerContext.CopyPinLinksToIntermediate(*srcPin, *dstPin); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | UClass* USpawnProjectileNode::GetActorClass() const | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  | 	return projectileClass; | 
		
	
		
			
				|  |  |  |  | } |