// ©2023 Batty Bovine Productions, LLC. All Rights Reserved. #include "Ed/EdComboActionGraph.h" #include "ComboActionGraph.h" #include "Ed/AssetEditor_ComboActionGraph.h" #include "Ed/EdComboActionGraphEdge.h" #include "Ed/EdComboActionGraphNode.h" #include "Nodes/ComboActionGraphEdge.h" #include "Nodes/ComboActionGraphNode.h" //#include "Helpers/MounteaDialogueGraphEditorHelpers.h" //#include "Helpers/MounteaDialogueGraphEditorUtilities.h" //#include "Helpers/MounteaDialogueSystemEditorBFC.h" DEFINE_LOG_CATEGORY(LogEdComboActionGraph); void UEdComboActionGraph::RebuildComboActionGraph() { UE_LOG(LogEdComboActionGraph, Warning, TEXT("UEdComboActionGraph::RebuildComboActionGraph has been called")); UComboActionGraph *Graph = GetComboActionGraph(); this->Clear(); for (const TObjectPtr &Node : this->Nodes) { if (UEdComboActionGraphNode *EdNode = Cast(Node)) { if (EdNode->ComboActionGraphNode == nullptr) continue; UComboActionGraphNode *ComboActionGraphNode = EdNode->ComboActionGraphNode; this->NodeMap.Add(ComboActionGraphNode, EdNode); Graph->AllNodes.Add(ComboActionGraphNode); //EdNode->SetDialogueNodeIndex( Graph->AllNodes.Find(EdNode->ComboActionGraphNode) ); for (int PinIdx = 0; PinIdx < EdNode->Pins.Num(); ++PinIdx) { UEdGraphPin* Pin = EdNode->Pins[PinIdx]; if (Pin->Direction != EEdGraphPinDirection::EGPD_Output) continue; for (int LinkToIdx = 0; LinkToIdx < Pin->LinkedTo.Num(); ++LinkToIdx) { UComboActionGraphNode *ChildNode = nullptr; if (UEdComboActionGraphNode *EdNode_Child = Cast(Pin->LinkedTo[LinkToIdx]->GetOwningNode())) { ChildNode = EdNode_Child->ComboActionGraphNode; } else if (UEdComboActionGraphEdge *EdNode_Edge = Cast(Pin->LinkedTo[LinkToIdx]->GetOwningNode())) { UEdComboActionGraphNode *Child = EdNode_Edge->GetEndNode();; if (Child != nullptr) { ChildNode = Child->ComboActionGraphNode; } } if (ChildNode != nullptr) { ComboActionGraphNode->ChildNodes.Add(ChildNode); ChildNode->ParentNodes.Add(ComboActionGraphNode); } else { UE_LOG(LogEdComboActionGraph, Error, TEXT("[RebuildComboActionGraph] Can't find child node")); } } } } else if (UEdComboActionGraphEdge *EdgeNode = Cast(Node)) { UEdComboActionGraphNode *StartNode = EdgeNode->GetStartNode(); UEdComboActionGraphNode *EndNode = EdgeNode->GetEndNode(); UComboActionGraphEdge *Edge = EdgeNode->ComboActionGraphEdge; if (StartNode == nullptr || EndNode == nullptr || Edge == nullptr) { UE_LOG(LogEdComboActionGraph, Error, TEXT("[RebuildComboActionGraph] Add edge failed.")); continue; } this->EdgeMap.Add(Edge, EdgeNode); Edge->SetGraph(Graph); Edge->Rename(nullptr, Graph, REN_DontCreateRedirectors | REN_DoNotDirty); StartNode->ComboActionGraphNode->Edges.Add(EndNode->ComboActionGraphNode, Edge); Edge->SetStartNode(StartNode->ComboActionGraphNode); Edge->SetEndNode(EndNode->ComboActionGraphNode); } } for (UComboActionGraphNode *Node : Graph->AllNodes) { if (Node->ParentNodes.Num() == 0) { Graph->RootNodes.Add(Node); SortNodes(Node); } Node->Graph = Graph; Node->Rename(nullptr, Graph, REN_DontCreateRedirectors | REN_DoNotDirty); } Graph->RootNodes.Sort([&](const UComboActionGraphNode &L, const UComboActionGraphNode &R) { UEdComboActionGraphNode *EdNode_LNode = this->NodeMap[&L]; UEdComboActionGraphNode *EdNode_RNode = this->NodeMap[&R]; return EdNode_LNode->NodePosX < EdNode_RNode->NodePosX; }); } UComboActionGraph *UEdComboActionGraph::GetComboActionGraph() const { return CastChecked(GetOuter()); } bool UEdComboActionGraph::Modify(bool bAlwaysMarkDirty) { bool Rtn = Super::Modify(bAlwaysMarkDirty); this->GetComboActionGraph()->Modify(); for (TObjectPtr &Node : this->Nodes) { Node->Modify(); } return Rtn; } void UEdComboActionGraph::PostEditUndo() { this->NotifyGraphChanged(); Super::PostEditUndo(); } void UEdComboActionGraph::SetDialogueEditorPtr(TWeakPtr NewPtr) { this->ComboActionEditorPtr = NewPtr; } bool UEdComboActionGraph::JumpToNode(const UComboActionGraphNode *Node) { //return FComboActionGraphEditorUtilities::OpenEditorAndJumpToGraphNode(this->ComboActionEditorPtr, *NodeMap.Find(Node)); return false; } void UEdComboActionGraph::Clear() { UComboActionGraph *Graph = this->GetComboActionGraph(); Graph->ClearGraph(); this->NodeMap.Reset(); this->EdgeMap.Reset(); for (int i = 0; i < this->Nodes.Num(); ++i) { if (UEdComboActionGraphNode *EdNode = Cast(Nodes[i])) { UComboActionGraphNode *MounteaDialogueGraphNode = EdNode->ComboActionGraphNode; MounteaDialogueGraphNode->ParentNodes.Reset(); MounteaDialogueGraphNode->ChildNodes.Reset(); MounteaDialogueGraphNode->Edges.Reset(); } } } void UEdComboActionGraph::SortNodes(UComboActionGraphNode *RootNode) { int Level = 0; TArray CurrLevelNodes = { RootNode }; TArray NextLevelNodes; while (CurrLevelNodes.Num() != 0) { int32 LevelWidth = 0; for (int i = 0; i < CurrLevelNodes.Num(); ++i) { UComboActionGraphNode *Node = CurrLevelNodes[i]; auto Comp = [&](const UComboActionGraphNode &L, const UComboActionGraphNode &R) { UEdComboActionGraphNode *EdNode_LNode = NodeMap[&L]; UEdComboActionGraphNode *EdNode_RNode = NodeMap[&R]; return EdNode_LNode->NodePosX < EdNode_RNode->NodePosX; }; Node->ChildNodes.Sort(Comp); Node->ParentNodes.Sort(Comp); for (int j = 0; j < Node->ChildNodes.Num(); ++j) { NextLevelNodes.Add(Node->ChildNodes[j]); } } CurrLevelNodes = NextLevelNodes; NextLevelNodes.Reset(); ++Level; } }