2014-12-07 19:09:38 -05:00
|
|
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
2014-03-14 14:13:41 -04:00
|
|
|
#include "EnvironmentQueryEditorPrivatePCH.h"
|
|
|
|
|
#include "EnvironmentQueryEditorModule.h"
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// EnvironmentQueryGraph
|
|
|
|
|
|
|
|
|
|
namespace EQSGraphVersion
|
|
|
|
|
{
|
|
|
|
|
const int32 Initial = 0;
|
|
|
|
|
const int32 NestedNodes = 1;
|
2014-04-23 19:29:53 -04:00
|
|
|
const int32 CopyPasteOutersBug = 2;
|
2015-02-23 10:30:16 -05:00
|
|
|
const int32 BlueprintClasses = 3;
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
const int32 Latest = BlueprintClasses;
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
2014-10-14 10:29:11 -04:00
|
|
|
UEnvironmentQueryGraph::UEnvironmentQueryGraph(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
|
|
|
|
Schema = UEdGraphSchema_EnvironmentQuery::StaticClass();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct FCompareNodeXLocation
|
|
|
|
|
{
|
|
|
|
|
FORCEINLINE bool operator()(const UEdGraphPin& A, const UEdGraphPin& B) const
|
|
|
|
|
{
|
|
|
|
|
return A.GetOwningNode()->NodePosX < B.GetOwningNode()->NodePosX;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
void UEnvironmentQueryGraph::UpdateAsset(int32 UpdateFlags)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
if (IsLocked())
|
2014-04-23 19:29:53 -04:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
// let's find root node
|
2014-03-14 14:13:41 -04:00
|
|
|
UEnvironmentQueryGraphNode_Root* RootNode = NULL;
|
2015-02-23 10:30:16 -05:00
|
|
|
for (int32 Idx = 0; Idx < Nodes.Num(); Idx++)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
RootNode = Cast<UEnvironmentQueryGraphNode_Root>(Nodes[Idx]);
|
2014-03-14 14:13:41 -04:00
|
|
|
if (RootNode != NULL)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UEnvQuery* Query = Cast<UEnvQuery>(GetOuter());
|
|
|
|
|
Query->Options.Reset();
|
|
|
|
|
if (RootNode && RootNode->Pins.Num() > 0 && RootNode->Pins[0]->LinkedTo.Num() > 0)
|
|
|
|
|
{
|
|
|
|
|
UEdGraphPin* MyPin = RootNode->Pins[0];
|
|
|
|
|
|
|
|
|
|
// sort connections so that they're organized the same as user can see in the editor
|
|
|
|
|
MyPin->LinkedTo.Sort(FCompareNodeXLocation());
|
|
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
for (int32 Idx = 0; Idx < MyPin->LinkedTo.Num(); Idx++)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UEnvironmentQueryGraphNode_Option* OptionNode = Cast<UEnvironmentQueryGraphNode_Option>(MyPin->LinkedTo[Idx]->GetOwningNode());
|
2014-03-14 14:13:41 -04:00
|
|
|
if (OptionNode)
|
|
|
|
|
{
|
|
|
|
|
UEnvQueryOption* OptionInstance = Cast<UEnvQueryOption>(OptionNode->NodeInstance);
|
2014-07-07 17:19:49 -04:00
|
|
|
if (OptionInstance != NULL)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-07-07 17:19:49 -04:00
|
|
|
OptionInstance->Tests.Reset();
|
|
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
for (int32 TestIdx = 0; TestIdx < OptionNode->SubNodes.Num(); TestIdx++)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UEnvironmentQueryGraphNode_Test* TestNode = Cast<UEnvironmentQueryGraphNode_Test>(OptionNode->SubNodes[TestIdx]);
|
2014-07-07 17:19:49 -04:00
|
|
|
if (TestNode && TestNode->bTestEnabled)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2014-07-07 17:19:49 -04:00
|
|
|
UEnvQueryTest* TestInstance = Cast<UEnvQueryTest>(TestNode->NodeInstance);
|
|
|
|
|
if (TestInstance)
|
|
|
|
|
{
|
|
|
|
|
OptionInstance->Tests.Add(TestInstance);
|
|
|
|
|
}
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-07 17:19:49 -04:00
|
|
|
Query->Options.Add(OptionInstance);
|
|
|
|
|
}
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-23 19:29:53 -04:00
|
|
|
RemoveOrphanedNodes();
|
2014-09-03 05:20:46 -04:00
|
|
|
#if USE_EQS_DEBUGGER
|
2014-03-14 14:13:41 -04:00
|
|
|
UEnvQueryManager::NotifyAssetUpdate(Query);
|
2014-09-03 05:20:46 -04:00
|
|
|
#endif
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
2015-03-09 05:40:56 -04:00
|
|
|
void UEnvironmentQueryGraph::Initialize()
|
|
|
|
|
{
|
|
|
|
|
Super::Initialize();
|
|
|
|
|
SpawnMissingNodes();
|
|
|
|
|
CalculateAllWeights();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UEnvironmentQueryGraph::OnLoaded()
|
|
|
|
|
{
|
|
|
|
|
Super::OnLoaded();
|
|
|
|
|
UpdateDeprecatedGeneratorClasses();
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-14 14:13:41 -04:00
|
|
|
void UEnvironmentQueryGraph::CalculateAllWeights()
|
|
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
for (int32 Idx = 0; Idx < Nodes.Num(); Idx++)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UEnvironmentQueryGraphNode_Option* OptionNode = Cast<UEnvironmentQueryGraphNode_Option>(Nodes[Idx]);
|
2014-03-14 14:13:41 -04:00
|
|
|
if (OptionNode)
|
|
|
|
|
{
|
|
|
|
|
OptionNode->CalculateWeights();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UEnvironmentQueryGraph::MarkVersion()
|
|
|
|
|
{
|
|
|
|
|
GraphVersion = EQSGraphVersion::Latest;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UEnvironmentQueryGraph::UpdateVersion()
|
|
|
|
|
{
|
|
|
|
|
if (GraphVersion == EQSGraphVersion::Latest)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// convert to nested nodes
|
|
|
|
|
if (GraphVersion < EQSGraphVersion::NestedNodes)
|
|
|
|
|
{
|
|
|
|
|
UpdateVersion_NestedNodes();
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-23 19:29:53 -04:00
|
|
|
if (GraphVersion < EQSGraphVersion::CopyPasteOutersBug)
|
|
|
|
|
{
|
|
|
|
|
UpdateVersion_FixupOuters();
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
if (GraphVersion < EQSGraphVersion::BlueprintClasses)
|
|
|
|
|
{
|
|
|
|
|
UpdateVersion_CollectClassData();
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-14 14:13:41 -04:00
|
|
|
GraphVersion = EQSGraphVersion::Latest;
|
2014-04-23 19:29:53 -04:00
|
|
|
Modify();
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UEnvironmentQueryGraph::UpdateVersion_NestedNodes()
|
|
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
for (int32 Idx = 0; Idx < Nodes.Num(); Idx++)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UEnvironmentQueryGraphNode_Option* OptionNode = Cast<UEnvironmentQueryGraphNode_Option>(Nodes[Idx]);
|
2014-03-14 14:13:41 -04:00
|
|
|
if (OptionNode)
|
|
|
|
|
{
|
|
|
|
|
UEnvironmentQueryGraphNode* Node = OptionNode;
|
|
|
|
|
while (Node)
|
|
|
|
|
{
|
|
|
|
|
UEnvironmentQueryGraphNode* NextNode = NULL;
|
|
|
|
|
for (int32 iPin = 0; iPin < Node->Pins.Num(); iPin++)
|
|
|
|
|
{
|
|
|
|
|
UEdGraphPin* TestPin = Node->Pins[iPin];
|
|
|
|
|
if (TestPin && TestPin->Direction == EGPD_Output)
|
|
|
|
|
{
|
|
|
|
|
for (int32 iLink = 0; iLink < TestPin->LinkedTo.Num(); iLink++)
|
|
|
|
|
{
|
|
|
|
|
UEdGraphPin* LinkedTo = TestPin->LinkedTo[iLink];
|
|
|
|
|
UEnvironmentQueryGraphNode_Test* LinkedTest = LinkedTo ? Cast<UEnvironmentQueryGraphNode_Test>(LinkedTo->GetOwningNode()) : NULL;
|
|
|
|
|
if (LinkedTest)
|
|
|
|
|
{
|
|
|
|
|
LinkedTest->ParentNode = OptionNode;
|
2015-02-23 10:30:16 -05:00
|
|
|
OptionNode->SubNodes.Add(LinkedTest);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
NextNode = LinkedTest;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Node = NextNode;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
for (int32 Idx = Nodes.Num() - 1; Idx >= 0; Idx--)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UEnvironmentQueryGraphNode_Test* TestNode = Cast<UEnvironmentQueryGraphNode_Test>(Nodes[Idx]);
|
2014-03-14 14:13:41 -04:00
|
|
|
if (TestNode)
|
|
|
|
|
{
|
|
|
|
|
TestNode->Pins.Empty();
|
2015-02-23 10:30:16 -05:00
|
|
|
Nodes.RemoveAt(Idx);
|
2014-03-14 14:13:41 -04:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
UEnvironmentQueryGraphNode_Option* OptionNode = Cast<UEnvironmentQueryGraphNode_Option>(Nodes[Idx]);
|
2014-03-14 14:13:41 -04:00
|
|
|
if (OptionNode && OptionNode->Pins.IsValidIndex(1))
|
|
|
|
|
{
|
|
|
|
|
OptionNode->Pins.RemoveAt(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-23 19:29:53 -04:00
|
|
|
|
|
|
|
|
void UEnvironmentQueryGraph::UpdateVersion_FixupOuters()
|
|
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
for (int32 Idx = 0; Idx < Nodes.Num(); Idx++)
|
2014-04-23 19:29:53 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UEnvironmentQueryGraphNode* MyNode = Cast<UEnvironmentQueryGraphNode>(Nodes[Idx]);
|
2014-04-23 19:29:53 -04:00
|
|
|
if (MyNode)
|
|
|
|
|
{
|
|
|
|
|
MyNode->PostEditImport();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
void UEnvironmentQueryGraph::UpdateVersion_CollectClassData()
|
2014-04-23 19:29:53 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
for (int32 Idx = 0; Idx < Nodes.Num(); Idx++)
|
2014-04-23 19:29:53 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UEnvironmentQueryGraphNode* MyNode = Cast<UEnvironmentQueryGraphNode>(Nodes[Idx]);
|
|
|
|
|
if (MyNode)
|
2014-04-23 19:29:53 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UEnvQueryOption* OptionInstance = Cast<UEnvQueryOption>(MyNode->NodeInstance);
|
|
|
|
|
if (OptionInstance && OptionInstance->Generator)
|
2014-04-23 19:29:53 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UpdateNodeClassData(MyNode, OptionInstance->Generator->GetClass());
|
2014-04-23 19:29:53 -04:00
|
|
|
}
|
|
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
for (int32 SubIdx = 0; SubIdx < MyNode->SubNodes.Num(); SubIdx++)
|
2014-04-23 19:29:53 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UAIGraphNode* SubNode = MyNode->SubNodes[SubIdx];
|
|
|
|
|
if (SubNode && SubNode->NodeInstance)
|
2014-04-23 19:29:53 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UpdateNodeClassData(SubNode, SubNode->NodeInstance->GetClass());
|
2014-04-23 19:29:53 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-02-23 10:30:16 -05:00
|
|
|
}
|
2014-04-23 19:29:53 -04:00
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
void UEnvironmentQueryGraph::UpdateNodeClassData(UAIGraphNode* UpdateNode, UClass* InstanceClass)
|
|
|
|
|
{
|
|
|
|
|
UBlueprint* BPOwner = Cast<UBlueprint>(InstanceClass->ClassGeneratedBy);
|
|
|
|
|
if (BPOwner)
|
2014-04-23 19:29:53 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
UpdateNode->ClassData = FGraphNodeClassData(BPOwner->GetName(), BPOwner->GetOutermost()->GetName(), InstanceClass->GetName(), InstanceClass);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UpdateNode->ClassData = FGraphNodeClassData(InstanceClass, "");
|
2014-04-23 19:29:53 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
void UEnvironmentQueryGraph::CollectAllNodeInstances(TSet<UObject*>& NodeInstances)
|
2014-04-23 19:29:53 -04:00
|
|
|
{
|
2015-02-23 10:30:16 -05:00
|
|
|
Super::CollectAllNodeInstances(NodeInstances);
|
2014-04-23 19:29:53 -04:00
|
|
|
|
2015-02-23 10:30:16 -05:00
|
|
|
for (int32 Idx = 0; Idx < Nodes.Num(); Idx++)
|
|
|
|
|
{
|
|
|
|
|
UEnvironmentQueryGraphNode* MyNode = Cast<UEnvironmentQueryGraphNode>(Nodes[Idx]);
|
|
|
|
|
UEnvQueryOption* OptionInstance = MyNode ? Cast<UEnvQueryOption>(MyNode->NodeInstance) : nullptr;
|
|
|
|
|
if (OptionInstance && OptionInstance->Generator)
|
|
|
|
|
{
|
|
|
|
|
NodeInstances.Add(OptionInstance->Generator);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-23 19:29:53 -04:00
|
|
|
}
|
2015-03-09 05:40:56 -04:00
|
|
|
|
|
|
|
|
void UEnvironmentQueryGraph::UpdateDeprecatedGeneratorClasses()
|
|
|
|
|
{
|
|
|
|
|
for (int32 Idx = 0; Idx < Nodes.Num(); Idx++)
|
|
|
|
|
{
|
|
|
|
|
UEnvironmentQueryGraphNode* MyNode = Cast<UEnvironmentQueryGraphNode>(Nodes[Idx]);
|
|
|
|
|
UEnvQueryOption* OptionInstance = MyNode ? Cast<UEnvQueryOption>(MyNode->NodeInstance) : nullptr;
|
|
|
|
|
if (OptionInstance && OptionInstance->Generator)
|
|
|
|
|
{
|
|
|
|
|
MyNode->ErrorMessage = FGraphNodeClassHelper::GetDeprecationMessage(OptionInstance->Generator->GetClass());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UEnvironmentQueryGraph::SpawnMissingNodes()
|
|
|
|
|
{
|
|
|
|
|
TSet<UEnvQueryOption*> ExistingNodes;
|
|
|
|
|
|
|
|
|
|
for (int32 Idx = 0; Idx < Nodes.Num(); Idx++)
|
|
|
|
|
{
|
|
|
|
|
UEnvironmentQueryGraphNode* MyNode = Cast<UEnvironmentQueryGraphNode>(Nodes[Idx]);
|
|
|
|
|
UEnvQueryOption* OptionInstance = MyNode ? Cast<UEnvQueryOption>(MyNode->NodeInstance) : nullptr;
|
|
|
|
|
if (OptionInstance && OptionInstance->Generator)
|
|
|
|
|
{
|
|
|
|
|
ExistingNodes.Add(OptionInstance);
|
|
|
|
|
|
|
|
|
|
TSet<UEnvQueryTest*> ExistingTests;
|
|
|
|
|
for (int32 SubIdx = 0; SubIdx < MyNode->SubNodes.Num(); SubIdx++)
|
|
|
|
|
{
|
|
|
|
|
UEnvironmentQueryGraphNode* MySubNode = Cast<UEnvironmentQueryGraphNode>(MyNode->SubNodes[SubIdx]);
|
|
|
|
|
UEnvQueryTest* TestInstance = MySubNode ? Cast<UEnvQueryTest>(MySubNode->NodeInstance) : nullptr;
|
|
|
|
|
if (TestInstance)
|
|
|
|
|
{
|
|
|
|
|
ExistingTests.Add(TestInstance);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MyNode->RemoveSubNode(MySubNode);
|
|
|
|
|
SubIdx--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TArray<UEnvQueryTest*> TestsCopy = OptionInstance->Tests;
|
|
|
|
|
for (int32 SubIdx = 0; SubIdx < TestsCopy.Num(); SubIdx++)
|
|
|
|
|
{
|
|
|
|
|
if (ExistingTests.Contains(TestsCopy[SubIdx]) || (TestsCopy[SubIdx] == nullptr))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UEnvironmentQueryGraphNode_Test* TestNode = NewObject<UEnvironmentQueryGraphNode_Test>(this);
|
|
|
|
|
TestNode->NodeInstance = TestsCopy[SubIdx];
|
|
|
|
|
UpdateNodeClassData(TestNode, TestsCopy[SubIdx]->GetClass());
|
|
|
|
|
|
|
|
|
|
MyNode->AddSubNode(TestNode, this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|