// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. #include "BlueprintGraphPrivatePCH.h" #include "KismetCompiler.h" #include "Runtime/Engine/Classes/Kismet/GameplayStatics.h" #include "K2Node_GenericCreateObject.h" #define LOCTEXT_NAMESPACE "K2Node_GenericCreateObject" void UK2Node_GenericCreateObject::ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) { UK2Node_CallFunction* CallCreateNode = CompilerContext.SpawnIntermediateNode(this, SourceGraph); CallCreateNode->FunctionReference.SetExternalMember(GET_FUNCTION_NAME_CHECKED(UGameplayStatics, SpawnObject), UGameplayStatics::StaticClass()); CallCreateNode->AllocateDefaultPins(); bool bSucceeded = true; //connect exe { auto SpawnExecPin = GetExecPin(); auto CallExecPin = CallCreateNode->GetExecPin(); bSucceeded &= SpawnExecPin && CallExecPin && CompilerContext.MovePinLinksToIntermediate(*SpawnExecPin, *CallExecPin).CanSafeConnect(); } //connect class { auto SpawnClassPin = GetClassPin(); auto CallClassPin = CallCreateNode->FindPin(TEXT("ObjectClass")); bSucceeded &= SpawnClassPin && CallClassPin && CompilerContext.MovePinLinksToIntermediate(*SpawnClassPin, *CallClassPin).CanSafeConnect(); } //connect outer { auto SpawnOuterPin = GetOuterPin(); auto CallOuterPin = CallCreateNode->FindPin(TEXT("Outer")); bSucceeded &= SpawnOuterPin && CallOuterPin && CompilerContext.MovePinLinksToIntermediate(*SpawnOuterPin, *CallOuterPin).CanSafeConnect(); } UEdGraphPin* CallResultPin = nullptr; //connect result { auto SpawnResultPin = GetResultPin(); CallResultPin = CallCreateNode->GetReturnValuePin(); // cast HACK. It should be safe. The only problem is native code generation. if (SpawnResultPin && CallResultPin) { CallResultPin->PinType = SpawnResultPin->PinType; } bSucceeded &= SpawnResultPin && CallResultPin && CompilerContext.MovePinLinksToIntermediate(*SpawnResultPin, *CallResultPin).CanSafeConnect(); } //assign exposed values and connect then { auto LastThen = FKismetCompilerUtilities::GenerateAssignmentNodes(CompilerContext, SourceGraph, CallCreateNode, this, CallResultPin, GetClassToSpawn()); auto SpawnNodeThen = GetThenPin(); bSucceeded &= SpawnNodeThen && LastThen && CompilerContext.MovePinLinksToIntermediate(*SpawnNodeThen, *LastThen).CanSafeConnect(); } BreakAllNodeLinks(); if (!bSucceeded) { CompilerContext.MessageLog.Error(*LOCTEXT("GenericCreateObject_Error", "ICE: GenericCreateObject error @@").ToString(), this); } } void UK2Node_GenericCreateObject::ValidateNodeDuringCompilation(class FCompilerResultsLog& MessageLog) const { Super::ValidateNodeDuringCompilation(MessageLog); } void UK2Node_GenericCreateObject::EarlyValidation(class FCompilerResultsLog& MessageLog) const { Super::EarlyValidation(MessageLog); auto ClassToSpawn = GetClassToSpawn(); if (!UGameplayStatics::CanSpawnObjectOfClass(ClassToSpawn)) { MessageLog.Error(*FString::Printf(*LOCTEXT("GenericCreateObject_WrongClass", "Wrong class to spawn '%s' in @@").ToString(), *GetPathNameSafe(ClassToSpawn)), this); } auto OuterPin = GetOuterPin(); if (!OuterPin || (!OuterPin->DefaultObject && !OuterPin->LinkedTo.Num())) { MessageLog.Error(*LOCTEXT("GenericCreateObject_NoOuter", "Outer object is required in @@").ToString(), this); } } bool UK2Node_GenericCreateObject::IsCompatibleWithGraph(const UEdGraph* TargetGraph) const { return UK2Node::IsCompatibleWithGraph(TargetGraph); } #undef LOCTEXT_NAMESPACE