From 36deec8b6491b632fb98f5ea38bbc1668dba59b2 Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 09:57:35 +0200 Subject: [PATCH 01/14] Cursor logic move to BP, Duration now almost 0 --- .../Core/BP_DialoguePlayerState.uasset | Bin 58131 -> 89369 bytes Content/Example/M_DialogueExample.umap | Bin 23712 -> 23712 bytes Content/WBP/WBP_Dialogue.uasset | Bin 386662 -> 386736 bytes .../Components/MounteaDialogueManager.cpp | 8 --- .../Private/Graph/MounteaDialogueGraph.cpp | 6 +- .../Helpers/MounteaDialogueSystemBFC.cpp | 55 +++++++++--------- .../Components/MounteaDialogueManager.h | 7 --- .../Data/MounteaDialogueGraphDataTypes.h | 9 +-- .../Private/Ed/EdGraph_MounteaDialogueGraph.h | 3 +- .../MounteaDialogueImportConfig.cpp | 2 +- .../MounteaDialogueImportConfig.h | 2 +- 11 files changed, 35 insertions(+), 57 deletions(-) diff --git a/Content/Blueprints/Core/BP_DialoguePlayerState.uasset b/Content/Blueprints/Core/BP_DialoguePlayerState.uasset index 180184a15994abba68d9789ef56d1aa3f2dc45da..5ca76aa2ed62242be2578f6fb587ba10ba0dbc8b 100644 GIT binary patch literal 89369 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 H1*rdjGza=Q literal 58131 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 Gfd79W4}0bS diff --git a/Content/Example/M_DialogueExample.umap b/Content/Example/M_DialogueExample.umap index f3392c6d180a8dc43b4da6eef20d2b62bec15a2d..768901f9c653d2b1cfd4c9cc1d5d00158eb4cbdc 100644 GIT binary patch delta 123 zcmZ3mlX1aL#toMk1r{;C`=n{L)~EMLm!H{#zY&`sF$U=K85-yr8t58Y=ouU885nJL zFuWop*f^{2_qWAa9;;vT&-Pj%cfxz}Mn&Pt2{AmA4UAaebcD-cfsWZ58Z8SSJ4_0d Xdc3Uhk>F$nBaz7g)@GYaUA4slNeMAZ delta 123 zcmZ3mlX1aL#toMk1>#;jR<|jsbD42@%eo><`_j#i7z6bA3@r7G4Rj66^o$IEjLi;) zSA+zw39hx-%$DQ4V8)Eb3$_22c~9P`C_FhKhG(*Y5euA-a5*f%pA)%$!R~L)6Q)<% WCq1cpIa$F-WO9JD+2&GLZE*nMVlbot diff --git a/Content/WBP/WBP_Dialogue.uasset b/Content/WBP/WBP_Dialogue.uasset index 4cc1ecec244cb9624bff9215142bfc17db995e7b..2ea840332a94faba29ca651c9ca8a68e86bcaca2 100644 GIT binary patch delta 4612 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 H`<(v)UBuRS delta 6510 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 diff --git a/Source/MounteaDialogueSystem/Private/Components/MounteaDialogueManager.cpp b/Source/MounteaDialogueSystem/Private/Components/MounteaDialogueManager.cpp index 00037e95..110042b5 100644 --- a/Source/MounteaDialogueSystem/Private/Components/MounteaDialogueManager.cpp +++ b/Source/MounteaDialogueSystem/Private/Components/MounteaDialogueManager.cpp @@ -22,7 +22,6 @@ UMounteaDialogueManager::UMounteaDialogueManager() , DefaultManagerState(EDialogueManagerState::EDMS_Enabled) , DialogueContext(nullptr) , ReplicatedDialogueContext(nullptr) - , bWasCursorVisible(false) , DialogueContextReplicationKey(0) { bAutoActivate = true; @@ -1003,14 +1002,9 @@ bool UMounteaDialogueManager::InvokeDialogueUI_Implementation(FString& Message) return false; } - bWasCursorVisible = playerController->bShowMouseCursor; - // This event should be responsible for calling logic in Player Controller OnDialogueUserInterfaceChanged.Broadcast(DialogueWidgetClass, DialogueWidgetPtr); - // This Component should not be responsible for setting up Player Controller! - playerController->SetShowMouseCursor(true); - return Execute_UpdateDialogueUI(this, Message, MounteaDialogueWidgetCommands::CreateDialogueWidget); } @@ -1054,8 +1048,6 @@ bool UMounteaDialogueManager::CloseDialogueUI_Implementation() OnDialogueUserInterfaceChanged.Broadcast(DialogueWidgetClass, nullptr); - playerController->SetShowMouseCursor(bWasCursorVisible); - if (DialogueWidgetPtr->Implements()) { FString errorMessage; diff --git a/Source/MounteaDialogueSystem/Private/Graph/MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystem/Private/Graph/MounteaDialogueGraph.cpp index cb221f1d..5bdeb104 100644 --- a/Source/MounteaDialogueSystem/Private/Graph/MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystem/Private/Graph/MounteaDialogueGraph.cpp @@ -209,8 +209,7 @@ void UMounteaDialogueGraph::PostInitProperties() #endif } -void UMounteaDialogueGraph::RegisterTick_Implementation( - const TScriptInterface& ParentTickable) +void UMounteaDialogueGraph::RegisterTick_Implementation(const TScriptInterface& ParentTickable) { if (ParentTickable.GetObject() && ParentTickable.GetInterface()) { @@ -218,8 +217,7 @@ void UMounteaDialogueGraph::RegisterTick_Implementation( } } -void UMounteaDialogueGraph::UnregisterTick_Implementation( - const TScriptInterface& ParentTickable) +void UMounteaDialogueGraph::UnregisterTick_Implementation(const TScriptInterface& ParentTickable) { if (ParentTickable.GetObject() && ParentTickable.GetInterface()) { diff --git a/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueSystemBFC.cpp b/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueSystemBFC.cpp index b8350a83..e6b1b31f 100644 --- a/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueSystemBFC.cpp +++ b/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueSystemBFC.cpp @@ -717,48 +717,47 @@ float UMounteaDialogueSystemBFC::GetRowDuration(const FDialogueRowData& Row) switch (Row.RowDurationMode) { case ERowDurationMode::ERDM_Duration: + { + if (Row.RowSound) { - if (Row.RowSound) - { - ReturnValue = Row.RowSound->Duration; - break; - } - - ReturnValue = Row.RowDuration; + ReturnValue = Row.RowSound->Duration; + break; } + ReturnValue = Row.RowDuration; break; + } case ERowDurationMode::EDRM_Override: - { - ReturnValue = Row.RowDurationOverride; - } + { + ReturnValue = Row.RowDurationOverride; break; + } case ERowDurationMode::EDRM_Add: + { + if (Row.RowSound) { - if (Row.RowSound) - { - ReturnValue = Row.RowSound->Duration; - ReturnValue = ReturnValue + Row.RowDurationOverride; - break; - } - ReturnValue = Row.RowDurationOverride; + ReturnValue = Row.RowSound->Duration; + ReturnValue = ReturnValue + Row.RowDurationOverride; + break; } + ReturnValue = Row.RowDurationOverride; break; + } case ERowDurationMode::ERDM_AutoCalculate: + { + if (GetDialogueSystemSettings_Internal()) { - //TODO: Make 8:100 ratio editable in Settings! - if (GetDialogueSystemSettings_Internal()) - { - ReturnValue= ((Row.RowText.ToString().Len() * GetDialogueSystemSettings_Internal()->GetDurationCoefficient()) / 100.f); - } - else - { - ReturnValue= ((Row.RowText.ToString().Len() * 8.f) / 100.f); - } - break; + ReturnValue= ((Row.RowText.ToString().Len() * GetDialogueSystemSettings_Internal()->GetDurationCoefficient()) / 100.f); } + else + { + ReturnValue= ((Row.RowText.ToString().Len() * 8.f) / 100.f); + } + break; + } } - ReturnValue = FMath::Max(1.f, ReturnValue); + // Timer running in background need some time and replication takes a few ms, too + ReturnValue = FMath::Max(UE_KINDA_SMALL_NUMBER, ReturnValue); return ReturnValue; } diff --git a/Source/MounteaDialogueSystem/Public/Components/MounteaDialogueManager.h b/Source/MounteaDialogueSystem/Public/Components/MounteaDialogueManager.h index 8ec967f4..5c734bc6 100644 --- a/Source/MounteaDialogueSystem/Public/Components/MounteaDialogueManager.h +++ b/Source/MounteaDialogueSystem/Public/Components/MounteaDialogueManager.h @@ -418,13 +418,6 @@ class MOUNTEADIALOGUESYSTEM_API UMounteaDialogueManager : public UActorComponent UPROPERTY(Transient, VisibleAnywhere, Category="Mountea|Dialogue|Manager", AdvancedDisplay, meta=(DisplayThumbnail=false)) FTimerHandle TimerHandle_RowTimer; - /** - * Is saved once Dialogue starts. - * Once Dialogue ends, cached value is set back again. - */ - UPROPERTY(Transient, VisibleAnywhere, Category="Mountea|Dialogue|Manager", AdvancedDisplay) - uint8 bWasCursorVisible : 1; - /** * */ diff --git a/Source/MounteaDialogueSystem/Public/Data/MounteaDialogueGraphDataTypes.h b/Source/MounteaDialogueSystem/Public/Data/MounteaDialogueGraphDataTypes.h index 2f1d73e0..40baf1f0 100644 --- a/Source/MounteaDialogueSystem/Public/Data/MounteaDialogueGraphDataTypes.h +++ b/Source/MounteaDialogueSystem/Public/Data/MounteaDialogueGraphDataTypes.h @@ -59,14 +59,11 @@ enum class EDialogueParticipantState : uint8 UENUM(BlueprintType) enum class ERowDurationMode : uint8 { - ERDM_Manual UMETA(DisplayName="Manual", - Tooltip="Row won't start automatically and will wait for `NextDialogueRow` request.", hidden), - ERDM_Duration UMETA(DisplayName="Duration", - Tooltip="Uses either duration of 'Row Sound' or value from 'Duration'."), + ERDM_Manual UMETA(DisplayName="Manual", Tooltip="Row won't start automatically and will wait for `NextDialogueRow` request.", hidden), + ERDM_Duration UMETA(DisplayName="Duration", Tooltip="Uses either duration of 'Row Sound' or value from 'Duration'."), EDRM_Override UMETA(DisplayName="Override", Tooltip="Uses 'Duration Override' value."), EDRM_Add UMETA(DisplayName="Add Time", Tooltip="Adds 'Duration Override' value to 'Duration'."), - ERDM_AutoCalculate UMETA(DisplayName="Calculate", - Tooltip="Calculates Duration automatically. Base value is: 100 characters per 8 seconds."), + ERDM_AutoCalculate UMETA(DisplayName="Calculate", Tooltip="Calculates Duration automatically. Base value is: 100 characters per 8 seconds."), Default UMETA(hidden) }; diff --git a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h index 8d2d7879..190563d8 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h +++ b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h @@ -25,8 +25,7 @@ class MOUNTEADIALOGUESYSTEMEDITOR_API UEdGraph_MounteaDialogueGraph : public UEd virtual void RebuildMounteaDialogueGraph(); UEdNode_MounteaDialogueGraphNode* CreateEdNode(UMounteaDialogueGraphNode* DialogueNode); - UEdNode_MounteaDialogueGraphEdge* CreateEdgeNode(UEdNode_MounteaDialogueGraphNode* StartNode, - UEdNode_MounteaDialogueGraphNode* EndNode); + UEdNode_MounteaDialogueGraphEdge* CreateEdgeNode(UEdNode_MounteaDialogueGraphNode* StartNode, UEdNode_MounteaDialogueGraphNode* EndNode); void UpdateNodesPositions(); UMounteaDialogueGraph* GetMounteaDialogueGraph() const; diff --git a/Source/MounteaDialogueSystemEditor/Private/ImportConfig/MounteaDialogueImportConfig.cpp b/Source/MounteaDialogueSystemEditor/Private/ImportConfig/MounteaDialogueImportConfig.cpp index af8d413d..af281b0d 100644 --- a/Source/MounteaDialogueSystemEditor/Private/ImportConfig/MounteaDialogueImportConfig.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/ImportConfig/MounteaDialogueImportConfig.cpp @@ -1,4 +1,4 @@ -// // All rights reserved Dominik Morse (Pavlicek) 2024 +// All rights reserved Dominik Morse (Pavlicek) 2024 #include "MounteaDialogueImportConfig.h" diff --git a/Source/MounteaDialogueSystemEditor/Private/ImportConfig/MounteaDialogueImportConfig.h b/Source/MounteaDialogueSystemEditor/Private/ImportConfig/MounteaDialogueImportConfig.h index 94503560..93082668 100644 --- a/Source/MounteaDialogueSystemEditor/Private/ImportConfig/MounteaDialogueImportConfig.h +++ b/Source/MounteaDialogueSystemEditor/Private/ImportConfig/MounteaDialogueImportConfig.h @@ -1,4 +1,4 @@ -// // All rights reserved Dominik Morse (Pavlicek) 2024 +// All rights reserved Dominik Morse (Pavlicek) 2024 #pragma once From 53f15ebf8443987855acd0f4f7726c2b33fe3a0c Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 10:55:48 +0200 Subject: [PATCH 02/14] Exposed getter to options container --- .../Private/Helpers/MounteaDialogueUIBFL.cpp | 19 ++++++++++++ .../WBP/MounteaDialogueOptionsContainer.cpp | 9 ++++++ .../Public/Helpers/MounteaDialogueUIBFL.h | 7 +++++ ...MounteaDialogueOptionsContainerInterface.h | 4 +++ .../WBP/MounteaDialogueOptionsContainer.h | 31 +++++++++---------- 5 files changed, 54 insertions(+), 16 deletions(-) diff --git a/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueUIBFL.cpp b/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueUIBFL.cpp index af49ef8c..a3ff303e 100644 --- a/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueUIBFL.cpp +++ b/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueUIBFL.cpp @@ -11,6 +11,7 @@ #include "Interfaces/UMG/MounteaDialogueViewportWidgetInterface.h" #include "Internationalization/Regex.h" #include "Nodes/MounteaDialogueGraphNode_DialogueNodeBase.h" +#include "WBP/MounteaDialogueOptionsContainer.h" FDialogueOptionData UMounteaDialogueUIBFL::NewDialogueOptionData(const FGuid& Node, const FDialogueRow& DialogueRow) { @@ -209,3 +210,21 @@ void UMounteaDialogueUIBFL::RemoveChildWidget(UUserWidget* ParentWidget, UUserWi LOG_ERROR(TEXT("[RemoveChildWidget] ParentWidget does not implement `MounteaDialogueViewportWidgetInterface`!")); } + +TArray UMounteaDialogueUIBFL::GetDialogueOptions(UUserWidget* ParentWidget) +{ + TArray dialogueOptions; + if (!IsValid(ParentWidget)) + { + LOG_ERROR(TEXT("[GetDialogueOptions] Invalid Parent Widget provided!")); + return dialogueOptions; + } + + if (ParentWidget->Implements()) + { + return IMounteaDialogueOptionsContainerInterface::Execute_GetDialogueOptions(ParentWidget); + } + + LOG_ERROR(TEXT("[GetDialogueOptions] ParentWidget does not implement `MounteaDialogueOptionsContainerInterface`!")); + return dialogueOptions; +} diff --git a/Source/MounteaDialogueSystem/Private/WBP/MounteaDialogueOptionsContainer.cpp b/Source/MounteaDialogueSystem/Private/WBP/MounteaDialogueOptionsContainer.cpp index 02ca12fa..b8928d38 100644 --- a/Source/MounteaDialogueSystem/Private/WBP/MounteaDialogueOptionsContainer.cpp +++ b/Source/MounteaDialogueSystem/Private/WBP/MounteaDialogueOptionsContainer.cpp @@ -125,3 +125,12 @@ void UMounteaDialogueOptionsContainer::ProcessOptionSelected_Implementation(cons dialogueInterface->Execute_OnOptionSelected(ParentDialogueWidget, SelectedOption); } } + +TArray UMounteaDialogueOptionsContainer::GetDialogueOptions_Implementation() const +{ + TArray> dialogueOptions; + for (const auto dialogueOption : DialogueOptions) + dialogueOptions.Add(dialogueOption.Value); + + return dialogueOptions; +} diff --git a/Source/MounteaDialogueSystem/Public/Helpers/MounteaDialogueUIBFL.h b/Source/MounteaDialogueSystem/Public/Helpers/MounteaDialogueUIBFL.h index 8253d494..d7f1dc1d 100644 --- a/Source/MounteaDialogueSystem/Public/Helpers/MounteaDialogueUIBFL.h +++ b/Source/MounteaDialogueSystem/Public/Helpers/MounteaDialogueUIBFL.h @@ -184,4 +184,11 @@ class MOUNTEADIALOGUESYSTEM_API UMounteaDialogueUIBFL : public UBlueprintFunctio UFUNCTION(BlueprintCallable, Category="Mountea|Dialogue|Helpers|HUD", meta=(CustomTag="MounteaK2Setter", HideSelfPin="true")) static void RemoveChildWidget(UPARAM(meta=(MustImplement="/Script/MounteaDialogueSystem.MounteaDialogueViewportWidgetInterface")) UUserWidget* ParentWidget, UUserWidget* ChildWidget); + /** + * Returns all Dialogue Options from the specified Dialogue Options Container parent widget that implements the MounteaDialogueOptionsContainerInterface. + * + * @param ParentWidget The parent widget that should implement the MounteaDialogueOptionsContainerInterface. + */ + UFUNCTION(BlueprintCallable, Category="Mountea|Dialogue|Helpers|HUD", meta=(CustomTag="MounteaK2Setter", HideSelfPin="true")) + static TArray GetDialogueOptions(UPARAM(meta=(MustImplement="/Script/MounteaDialogueSystem.MounteaDialogueOptionsContainerInterface")) UUserWidget* ParentWidget); }; diff --git a/Source/MounteaDialogueSystem/Public/Interfaces/UMG/MounteaDialogueOptionsContainerInterface.h b/Source/MounteaDialogueSystem/Public/Interfaces/UMG/MounteaDialogueOptionsContainerInterface.h index 09164086..5da5a32f 100644 --- a/Source/MounteaDialogueSystem/Public/Interfaces/UMG/MounteaDialogueOptionsContainerInterface.h +++ b/Source/MounteaDialogueSystem/Public/Interfaces/UMG/MounteaDialogueOptionsContainerInterface.h @@ -117,4 +117,8 @@ class MOUNTEADIALOGUESYSTEM_API IMounteaDialogueOptionsContainerInterface void ProcessOptionSelected(const FGuid& SelectedOption, UUserWidget* CallingWidget); virtual void ProcessOptionSelected_Implementation(const FGuid& SelectedOption, UUserWidget* CallingWidget) = 0; + UFUNCTION(BlueprintNativeEvent, Category="Mountea|Dialogue|UserInterface|OptionsContainer") + TArray GetDialogueOptions() const; + virtual TArray GetDialogueOptions_Implementation() const = 0; + }; diff --git a/Source/MounteaDialogueSystem/Public/WBP/MounteaDialogueOptionsContainer.h b/Source/MounteaDialogueSystem/Public/WBP/MounteaDialogueOptionsContainer.h index 2c87458a..de93e0d5 100644 --- a/Source/MounteaDialogueSystem/Public/WBP/MounteaDialogueOptionsContainer.h +++ b/Source/MounteaDialogueSystem/Public/WBP/MounteaDialogueOptionsContainer.h @@ -20,36 +20,35 @@ class MOUNTEADIALOGUESYSTEM_API UMounteaDialogueOptionsContainer : public UUserW GENERATED_BODY() protected: - // IMounteaDialogueOptionsContainerInterface implementation - virtual void SetParentDialogueWidget_Implementation (UUserWidget* NewParentDialogueWidget) override; - virtual UUserWidget* GetParentDialogueWidget_Implementation () const override; - virtual TSoftClassPtr GetDialogueOptionClass_Implementation () const override; - virtual void SetDialogueOptionClass_Implementation (const TSoftClassPtr& NewDialogueOptionClass) override; - virtual void AddNewDialogueOption_Implementation (UMounteaDialogueGraphNode_DialogueNodeBase* Node) override; - virtual void AddNewDialogueOptions_Implementation (const TArray& NewDialogueOptions) override; - virtual void RemoveDialogueOption_Implementation (UMounteaDialogueGraphNode_DialogueNodeBase* DirtyDialogueOption) override; - virtual void RemoveDialogueOptions_Implementation (const TArray& DirtyDialogueOptions) override; - virtual void ClearDialogueOptions_Implementation () override; - virtual void ProcessOptionSelected_Implementation (const FGuid& SelectedOption, UUserWidget* CallingWidget) override; - + virtual void SetParentDialogueWidget_Implementation(UUserWidget* NewParentDialogueWidget) override; + virtual UUserWidget* GetParentDialogueWidget_Implementation() const override; + virtual TSoftClassPtr GetDialogueOptionClass_Implementation() const override; + virtual void SetDialogueOptionClass_Implementation(const TSoftClassPtr& NewDialogueOptionClass) override; + virtual void AddNewDialogueOption_Implementation(UMounteaDialogueGraphNode_DialogueNodeBase* Node) override; + virtual void AddNewDialogueOptions_Implementation(const TArray& NewDialogueOptions) override; + virtual void RemoveDialogueOption_Implementation(UMounteaDialogueGraphNode_DialogueNodeBase* DirtyDialogueOption) override; + virtual void RemoveDialogueOptions_Implementation(const TArray& DirtyDialogueOptions) override; + virtual void ClearDialogueOptions_Implementation() override; + virtual void ProcessOptionSelected_Implementation(const FGuid& SelectedOption, UUserWidget* CallingWidget) override; + virtual TArray GetDialogueOptions_Implementation() const override; + protected: - /** * The class type of the dialogue option widget. Must Implement 'MounteaDialogueOptionInterface'. */ UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="Mountea|Dialogue", meta=(MustImplement="/Script/MounteaDialogueSystem.MounteaDialogueOptionInterface", NoResetToDefault)) - TSoftClassPtr DialogueOptionClass; + TSoftClassPtr DialogueOptionClass; /** * The parent dialogue widget. Must implement 'MounteaDialogueWBPInterface'. */ UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category="Mountea|Dialogue", meta=(MustImplement="/Script/MounteaDialogueSystem.MounteaDialogueWBPInterface", NoResetToDefault)) - TObjectPtr ParentDialogueWidget; + TObjectPtr ParentDialogueWidget; /** * All Dialogue options associated with this container. */ UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category="Mountea|Dialogue") - TMap> DialogueOptions; + TMap> DialogueOptions; }; From 41408de9c68ac07ad4b15d59ae159030fda38ebd Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 12:05:47 +0200 Subject: [PATCH 03/14] Node Execution Order --- .../Nodes/MounteaDialogueGraphNode.cpp | 3 +- .../Public/Nodes/MounteaDialogueGraphNode.h | 4 + .../Ed/EdGraph_MounteaDialogueGraph.cpp | 82 +++++++++++++++++++ .../Private/Ed/EdGraph_MounteaDialogueGraph.h | 6 +- .../Ed/EdNode_MounteaDialogueGraphNode.cpp | 5 ++ 5 files changed, 97 insertions(+), 3 deletions(-) diff --git a/Source/MounteaDialogueSystem/Private/Nodes/MounteaDialogueGraphNode.cpp b/Source/MounteaDialogueSystem/Private/Nodes/MounteaDialogueGraphNode.cpp index d62207a7..013bbfa4 100644 --- a/Source/MounteaDialogueSystem/Private/Nodes/MounteaDialogueGraphNode.cpp +++ b/Source/MounteaDialogueSystem/Private/Nodes/MounteaDialogueGraphNode.cpp @@ -428,14 +428,13 @@ FText UMounteaDialogueGraphNode::GetDefaultTooltipBody() const { const FText InheritsValue = bInheritGraphDecorators ? LOCTEXT("True","Yes") : LOCTEXT("False","No"); const FText Inherits = FText::Format(LOCTEXT("UMounteaDialogueGraphNode_InheritsTooltip", "Inherits Graph Decorators: {0}"), InheritsValue); - FText ImplementsNumber; if (NodeDecorators.Num() == 0) ImplementsNumber = LOCTEXT("None","-"); else ImplementsNumber = FText::FromString(FString::FromInt(NodeDecorators.Num())); const FText Implements = FText::Format(LOCTEXT("UMounteaDialogueGraphNode_ImplementsTooltip", "Implements Decorators: {0}"), ImplementsNumber); - return FText::Format(LOCTEXT("UMounteaDialogueGraphNode_BaseTooltip", "{0} - {1}\n\n{2}\n{3}"), NodeTypeName, FText::FromString(NodeGUID.ToString()), Inherits, Implements); + return FText::Format(LOCTEXT("UMounteaDialogueGraphNode_BaseTooltip", "{0} - {1}\n\n{2}\n{3}\nNode Execution Order: {4}"), NodeTypeName, FText::FromString(NodeGUID.ToString()), Inherits, Implements, ExecutionOrder); } #endif diff --git a/Source/MounteaDialogueSystem/Public/Nodes/MounteaDialogueGraphNode.h b/Source/MounteaDialogueSystem/Public/Nodes/MounteaDialogueGraphNode.h index 0e769208..70c2ad1b 100644 --- a/Source/MounteaDialogueSystem/Public/Nodes/MounteaDialogueGraphNode.h +++ b/Source/MounteaDialogueSystem/Public/Nodes/MounteaDialogueGraphNode.h @@ -30,6 +30,7 @@ class MOUNTEADIALOGUESYSTEM_API UMounteaDialogueGraphNode : public UObject, publ #pragma region Variables #pragma region ReadOnly + public: /** @@ -68,6 +69,9 @@ class MOUNTEADIALOGUESYSTEM_API UMounteaDialogueGraphNode : public UObject, publ UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Private") int32 NodeIndex = INDEX_NONE; + /** Execution order within Parent's scope */ + UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = "Private") + int32 ExecutionOrder = INDEX_NONE; protected: diff --git a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp index 1b66db57..aea88d45 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp @@ -121,6 +121,8 @@ void UEdGraph_MounteaDialogueGraph::RebuildMounteaDialogueGraph() UEdNode_MounteaDialogueGraphNode* EdNode_RNode = NodeMap[&R]; return EdNode_LNode->NodePosX < EdNode_RNode->NodePosX; }); + + AssignExecutionOrder(); } UEdNode_MounteaDialogueGraphEdge* UEdGraph_MounteaDialogueGraph::CreateEdgeNode(UEdNode_MounteaDialogueGraphNode* StartNode, UEdNode_MounteaDialogueGraphNode* EndNode) @@ -226,3 +228,83 @@ void UEdGraph_MounteaDialogueGraph::SortNodes(UMounteaDialogueGraphNode* RootNod ++Level; } } + +void UEdGraph_MounteaDialogueGraph::ResetExecutionOrders() +{ + UMounteaDialogueGraph* Graph = GetMounteaDialogueGraph(); + if (!Graph) return; + + for (UMounteaDialogueGraphNode* Node : Graph->AllNodes) + { + if (Node) + { + Node->ExecutionOrder = INDEX_NONE; + } + } +} + +UMounteaDialogueGraphNode* UEdGraph_MounteaDialogueGraph::GetParentNode(const UMounteaDialogueGraphNode& Node) +{ + if (Node.ParentNodes.Num() > 0) + { + return Node.ParentNodes[0]; + } + return nullptr; +} + +void UEdGraph_MounteaDialogueGraph::AssignExecutionOrder() +{ + ResetExecutionOrders(); + + UMounteaDialogueGraph* Graph = GetMounteaDialogueGraph(); + if (!Graph) return; + + TMap> LayeredNodes; + int32 CurrentExecutionOrder = 0; + + for (UMounteaDialogueGraphNode* RootNode : Graph->RootNodes) + { + if (RootNode) + { + AssignNodeToLayer(RootNode, 0, LayeredNodes); + } + } + + for (int32 LayerIndex = 0; LayeredNodes.Contains(LayerIndex); ++LayerIndex) + { + TArray& NodesInLayer = LayeredNodes[LayerIndex]; + NodesInLayer.Sort([this](const UMounteaDialogueGraphNode& A, const UMounteaDialogueGraphNode& B) + { + UEdNode_MounteaDialogueGraphNode* EdNode_A = NodeMap[&A]; + UEdNode_MounteaDialogueGraphNode* EdNode_B = NodeMap[&B]; + + UMounteaDialogueGraphNode* ParentA = GetParentNode(A); + UMounteaDialogueGraphNode* ParentB = GetParentNode(B); + if (ParentA->ExecutionOrder == ParentB->ExecutionOrder) + { + return EdNode_A->NodePosX < EdNode_B->NodePosX; // Sort by X when parents are the same + } + return ParentA->ExecutionOrder < ParentB->ExecutionOrder; + }); + + for (UMounteaDialogueGraphNode* Node : NodesInLayer) + { + if (Node) + { + Node->ExecutionOrder = CurrentExecutionOrder++; + } + } + } +} + +void UEdGraph_MounteaDialogueGraph::AssignNodeToLayer(UMounteaDialogueGraphNode* Node, int32 LayerIndex, TMap>& LayeredNodes) +{ + if (!Node) return; + + LayeredNodes.FindOrAdd(LayerIndex).Add(Node); + + for (UMounteaDialogueGraphNode* ChildNode : Node->ChildrenNodes) + { + AssignNodeToLayer(ChildNode, LayerIndex + 1, LayeredNodes); + } +} \ No newline at end of file diff --git a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h index 190563d8..75348bbf 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h +++ b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h @@ -26,7 +26,6 @@ class MOUNTEADIALOGUESYSTEMEDITOR_API UEdGraph_MounteaDialogueGraph : public UEd virtual void RebuildMounteaDialogueGraph(); UEdNode_MounteaDialogueGraphNode* CreateEdNode(UMounteaDialogueGraphNode* DialogueNode); UEdNode_MounteaDialogueGraphEdge* CreateEdgeNode(UEdNode_MounteaDialogueGraphNode* StartNode, UEdNode_MounteaDialogueGraphNode* EndNode); - void UpdateNodesPositions(); UMounteaDialogueGraph* GetMounteaDialogueGraph() const; @@ -53,6 +52,11 @@ class MOUNTEADIALOGUESYSTEMEDITOR_API UEdGraph_MounteaDialogueGraph : public UEd void Clear(); void SortNodes(UMounteaDialogueGraphNode* RootNode); + + void ResetExecutionOrders(); + static UMounteaDialogueGraphNode* GetParentNode(const UMounteaDialogueGraphNode& Node); + void AssignExecutionOrder(); + static void AssignNodeToLayer(UMounteaDialogueGraphNode* Node, int32 LayerIndex, TMap>& LayeredNodes); private: diff --git a/Source/MounteaDialogueSystemEditor/Private/Ed/EdNode_MounteaDialogueGraphNode.cpp b/Source/MounteaDialogueSystemEditor/Private/Ed/EdNode_MounteaDialogueGraphNode.cpp index 68b1d8c3..251d5ef2 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Ed/EdNode_MounteaDialogueGraphNode.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/Ed/EdNode_MounteaDialogueGraphNode.cpp @@ -187,6 +187,11 @@ void UEdNode_MounteaDialogueGraphNode::UpdatePosition() DialogueGraphNode->NodePosition = FIntPoint(NodePosX, NodePosY); DialogueGraphNode->Modify(true); } + + if (auto graphEditor = GetDialogueGraphEdGraph()) + { + + } } void UEdNode_MounteaDialogueGraphNode::PostEditUndo() From e817db04ec8e14d3ed0ded098aa05bf2845ff471 Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 12:51:23 +0200 Subject: [PATCH 04/14] Sorting Nodes --- .../Components/MounteaDialogueManager.cpp | 13 +++++++++---- .../Helpers/MounteaDialogueSystemBFC.cpp | 12 ++++++++++-- .../Private/Helpers/MounteaDialogueUIBFL.cpp | 3 ++- .../Public/Helpers/MounteaDialogueSystemBFC.h | 19 ++++++++++++++++++- .../Ed/EdGraph_MounteaDialogueGraph.cpp | 5 +++-- .../Private/Ed/EdGraph_MounteaDialogueGraph.h | 2 +- 6 files changed, 43 insertions(+), 11 deletions(-) diff --git a/Source/MounteaDialogueSystem/Private/Components/MounteaDialogueManager.cpp b/Source/MounteaDialogueSystem/Private/Components/MounteaDialogueManager.cpp index 110042b5..ddd1c5f6 100644 --- a/Source/MounteaDialogueSystem/Private/Components/MounteaDialogueManager.cpp +++ b/Source/MounteaDialogueSystem/Private/Components/MounteaDialogueManager.cpp @@ -129,7 +129,9 @@ void UMounteaDialogueManager::CallDialogueNodeSelected_Implementation(const FGui } // Straight up set dialogue row from Node and index to 0 - DialogueContext->SetDialogueContext(DialogueContext->DialogueParticipant, selectedNode, UMounteaDialogueSystemBFC::GetAllowedChildNodes(selectedNode)); + auto allowedChildNodes = UMounteaDialogueSystemBFC::GetAllowedChildNodes(selectedNode); + UMounteaDialogueSystemBFC::SortNodes(allowedChildNodes); + DialogueContext->SetDialogueContext(DialogueContext->DialogueParticipant, selectedNode, allowedChildNodes); DialogueContext->UpdateActiveDialogueRow(UMounteaDialogueSystemBFC::GetDialogueRow(DialogueContext->ActiveNode)); DialogueContext->UpdateActiveDialogueRowDataIndex(0); @@ -249,7 +251,8 @@ void UMounteaDialogueManager::OnDialogueNodeFinishedEvent_Internal(UMounteaDialo OnDialogueNodeFinishedEvent(DialogueContext); - const TArray allowedChildrenNodes = UMounteaDialogueSystemBFC::GetAllowedChildNodes(DialogueContext->ActiveNode); + TArray allowedChildrenNodes = UMounteaDialogueSystemBFC::GetAllowedChildNodes(DialogueContext->ActiveNode); + UMounteaDialogueSystemBFC::SortNodes(allowedChildrenNodes); // If there are only Complete Nodes left or no DialogueNodes left, just shut it down if (allowedChildrenNodes.Num() == 0) @@ -269,8 +272,10 @@ void UMounteaDialogueManager::OnDialogueNodeFinishedEvent_Internal(UMounteaDialo { OnDialogueClosed.Broadcast(DialogueContext); } - - DialogueContext->SetDialogueContext(DialogueContext->DialogueParticipant, newActiveNode, UMounteaDialogueSystemBFC::GetAllowedChildNodes(newActiveNode)); + + auto allowedChildNodes = UMounteaDialogueSystemBFC::GetAllowedChildNodes(newActiveNode); + UMounteaDialogueSystemBFC::SortNodes(allowedChildNodes); + DialogueContext->SetDialogueContext(DialogueContext->DialogueParticipant, newActiveNode, allowedChildNodes); OnDialogueNodeSelected.Broadcast(DialogueContext); diff --git a/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueSystemBFC.cpp b/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueSystemBFC.cpp index e6b1b31f..d152fb23 100644 --- a/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueSystemBFC.cpp +++ b/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueSystemBFC.cpp @@ -352,7 +352,8 @@ bool UMounteaDialogueSystemBFC::StartDialogue(const UObject* WorldContextObject, } } - const TArray StartNode_Children = GetAllowedChildNodes(NodeToStart); + TArray StartNode_Children = GetAllowedChildNodes(NodeToStart); + SortNodes(StartNode_Children); UMounteaDialogueContext* Context = NewObject(); Context->SetDialogueContext(MainParticipant, NodeToStart, StartNode_Children); @@ -448,7 +449,8 @@ bool UMounteaDialogueSystemBFC::InitializeDialogue(const UObject* WorldContextOb NodeToStart = GetFirstChildNode(NodeToStart); } - const TArray StartNode_Children = GetAllowedChildNodes(NodeToStart); + TArray StartNode_Children = GetAllowedChildNodes(NodeToStart); + SortNodes(StartNode_Children); UMounteaDialogueContext* Context = NewObject(); Context->SetDialogueContext(DialogueParticipant, NodeToStart, StartNode_Children); @@ -671,6 +673,12 @@ TArray UMounteaDialogueSystemBFC::GetAllowedChildNod return ReturnNodes; } +void UMounteaDialogueSystemBFC::SortNodes(TArray& SortedNodes) +{ + SortNodes(SortedNodes); +} + + FDialogueRow UMounteaDialogueSystemBFC::GetDialogueRow(const UMounteaDialogueGraphNode* Node) { if (!Node) diff --git a/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueUIBFL.cpp b/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueUIBFL.cpp index a3ff303e..6b00548f 100644 --- a/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueUIBFL.cpp +++ b/Source/MounteaDialogueSystem/Private/Helpers/MounteaDialogueUIBFL.cpp @@ -41,7 +41,7 @@ FDialogueRow UMounteaDialogueUIBFL::GetDialogueNodeRow(UMounteaDialogueGraphNode TArray UMounteaDialogueUIBFL::FilterDialogueFriendlyNodes(const TArray& RawNodes) { TArray returnArray; - + for (const auto& Itr : RawNodes) { if (!Itr) continue; @@ -52,6 +52,7 @@ TArray UMounteaDialogueUIBFL::Filte } } + UMounteaDialogueSystemBFC::SortNodes(returnArray); return returnArray; } diff --git a/Source/MounteaDialogueSystem/Public/Helpers/MounteaDialogueSystemBFC.h b/Source/MounteaDialogueSystem/Public/Helpers/MounteaDialogueSystemBFC.h index 98cc92f4..3127e874 100644 --- a/Source/MounteaDialogueSystem/Public/Helpers/MounteaDialogueSystemBFC.h +++ b/Source/MounteaDialogueSystem/Public/Helpers/MounteaDialogueSystemBFC.h @@ -249,7 +249,7 @@ class MOUNTEADIALOGUESYSTEM_API UMounteaDialogueSystemBFC : public UBlueprintFun */ UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Dialogue|Helpers", meta=(Keywords="diaogue, child, nodes"), meta=(CustomTag="MounteaK2Getter")) static TArray GetAllowedChildNodes(const UMounteaDialogueGraphNode* ParentNode); - + /** * Returns whether Dialogue Row is valid or not. * @@ -391,4 +391,21 @@ class MOUNTEADIALOGUESYSTEM_API UMounteaDialogueSystemBFC : public UBlueprintFun UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Dialogue|Helpers", meta = (ClassFilter = "Interface"), meta=(DeterminesOutputType = "InterfaceFilter"), meta=(CustomTag="MounteaK2Getter")) static UActorComponent* GetSingleComponentByInterface(const AActor* Target, TSubclassOf InterfaceFilter, bool& bResult); + template + static void SortNodes(TArray& SortedNodes) + { + SortedNodes.Sort([](const NodeType& A, const NodeType& B) + { + return A.ExecutionOrder < B.ExecutionOrder; + }); + } + + /** + * Sorts given array of Dialogue Nodes based on their Execution Order. + * + * @param SortedNodes OUT Nodes array that will be sorted + */ + UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Dialogue|Helpers", meta=(Keywords="sort,order,diaogue,child,nodes"), meta=(CustomTag="MounteaK2Getter")) + static void SortNodes(TArray& SortedNodes); + }; diff --git a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp index aea88d45..1bccaf76 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp @@ -229,7 +229,7 @@ void UEdGraph_MounteaDialogueGraph::SortNodes(UMounteaDialogueGraphNode* RootNod } } -void UEdGraph_MounteaDialogueGraph::ResetExecutionOrders() +void UEdGraph_MounteaDialogueGraph::ResetExecutionOrders() const { UMounteaDialogueGraph* Graph = GetMounteaDialogueGraph(); if (!Graph) return; @@ -275,6 +275,7 @@ void UEdGraph_MounteaDialogueGraph::AssignExecutionOrder() TArray& NodesInLayer = LayeredNodes[LayerIndex]; NodesInLayer.Sort([this](const UMounteaDialogueGraphNode& A, const UMounteaDialogueGraphNode& B) { + // Prefer node order based on their parent's order UEdNode_MounteaDialogueGraphNode* EdNode_A = NodeMap[&A]; UEdNode_MounteaDialogueGraphNode* EdNode_B = NodeMap[&B]; @@ -282,7 +283,7 @@ void UEdGraph_MounteaDialogueGraph::AssignExecutionOrder() UMounteaDialogueGraphNode* ParentB = GetParentNode(B); if (ParentA->ExecutionOrder == ParentB->ExecutionOrder) { - return EdNode_A->NodePosX < EdNode_B->NodePosX; // Sort by X when parents are the same + return EdNode_A->NodePosX < EdNode_B->NodePosX; } return ParentA->ExecutionOrder < ParentB->ExecutionOrder; }); diff --git a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h index 75348bbf..e3d85b5a 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h +++ b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h @@ -53,7 +53,7 @@ class MOUNTEADIALOGUESYSTEMEDITOR_API UEdGraph_MounteaDialogueGraph : public UEd void Clear(); void SortNodes(UMounteaDialogueGraphNode* RootNode); - void ResetExecutionOrders(); + void ResetExecutionOrders() const; static UMounteaDialogueGraphNode* GetParentNode(const UMounteaDialogueGraphNode& Node); void AssignExecutionOrder(); static void AssignNodeToLayer(UMounteaDialogueGraphNode* Node, int32 LayerIndex, TMap>& LayeredNodes); From 20bb35fa845d84301dfde908c2c0eeaeec6120e0 Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 13:04:15 +0200 Subject: [PATCH 05/14] Sorting Nodes with Order --- .../AssetEditor/AssetEditor_MounteaDialogueGraph.cpp | 3 +-- .../Layout/ForceDirectedSolveLayoutStrategy.cpp | 5 +++++ .../Private/Layout/TreeSolveLayoutStrategy.cpp | 11 +++++++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp index 7594e9aa..f4bac063 100644 --- a/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp @@ -1069,8 +1069,7 @@ void FAssetEditor_MounteaDialogueGraph::AutoArrange() UEdGraph_MounteaDialogueGraph* EdGraph = Cast(EditingGraph->EdGraph); check(EdGraph != nullptr); - const FScopedTransaction Transaction(LOCTEXT("MounteaDialogueGraphEditorAutoArrange", - "Mountea Dialogue Graph Editor: Auto Arrange all Nodes")); + const FScopedTransaction Transaction(LOCTEXT("MounteaDialogueGraphEditorAutoArrange", "Mountea Dialogue Graph Editor: Auto Arrange all Nodes")); EdGraph->Modify(true); diff --git a/Source/MounteaDialogueSystemEditor/Private/Layout/ForceDirectedSolveLayoutStrategy.cpp b/Source/MounteaDialogueSystemEditor/Private/Layout/ForceDirectedSolveLayoutStrategy.cpp index 686d6ffb..dc9fadfb 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Layout/ForceDirectedSolveLayoutStrategy.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/Layout/ForceDirectedSolveLayoutStrategy.cpp @@ -57,6 +57,11 @@ void UForceDirectedSolveLayoutStrategy::Layout(UEdGraph* InEdGraph) FBox2D UForceDirectedSolveLayoutStrategy::LayoutOneTree(UMounteaDialogueGraphNode* RootNode, const FBox2D& PreTreeBound) { + Graph->AllNodes.Sort([](const UMounteaDialogueGraphNode& A, const UMounteaDialogueGraphNode& B) + { + return A.ExecutionOrder < B.ExecutionOrder; + }); + float Temp = InitTemperature; FBox2D TreeBound = GetActualBounds(RootNode); TreeBound.Min.X += PreTreeBound.Max.X + OptimalDistance; diff --git a/Source/MounteaDialogueSystemEditor/Private/Layout/TreeSolveLayoutStrategy.cpp b/Source/MounteaDialogueSystemEditor/Private/Layout/TreeSolveLayoutStrategy.cpp index 1846713f..e5b1451a 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Layout/TreeSolveLayoutStrategy.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/Layout/TreeSolveLayoutStrategy.cpp @@ -70,9 +70,15 @@ void UTreeSolveLayoutStrategy::InitPass(UMounteaDialogueGraphNode* RootNode, con } processedNodes.Add(RootNode); - + UEdNode_MounteaDialogueGraphNode* EdNode_RootNode = EdGraph->NodeMap[RootNode]; + // Sort child nodes by execution order before laying them out + RootNode->ChildrenNodes.Sort([](const UMounteaDialogueGraphNode& A, const UMounteaDialogueGraphNode& B) + { + return A.ExecutionOrder < B.ExecutionOrder; + }); + FVector2D ChildAnchor(FVector2D(0.f, GetNodeHeight(EdNode_RootNode) + OptimalDistance + Anchor.Y)); for (int32 i = 0; i < RootNode->ChildrenNodes.Num(); ++i) { @@ -87,7 +93,7 @@ void UTreeSolveLayoutStrategy::InitPass(UMounteaDialogueGraphNode* RootNode, con ChildAnchor.X += GetNodeWidth(EdNode_ChildNode) / 2; InitPass(Child, ChildAnchor); } - + float NodeWidth = GetNodeWidth(EdNode_RootNode); EdNode_RootNode->NodePosY = Anchor.Y; @@ -101,6 +107,7 @@ void UTreeSolveLayoutStrategy::InitPass(UMounteaDialogueGraphNode* RootNode, con } } + bool UTreeSolveLayoutStrategy::ResolveConflictPass(UMounteaDialogueGraphNode* Node) { bool HasConflict = false; From d9e0cf50b5ae589abaf6420901ceb58414e0e474 Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 13:54:40 +0200 Subject: [PATCH 06/14] Brute Manhattan Drawing Policy --- .../AssetEditor_MounteaDialogueGraph.cpp | 3 +- .../AssetGraphScheme_MounteaDialogueGraph.cpp | 3 +- ...ingPolicy_AdvancedMounteaDialogueGraph.cpp | 136 ++++++++++++++++++ ...awingPolicy_AdvancedMounteaDialogueGraph.h | 26 ++++ 4 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp create mode 100644 Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h diff --git a/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp index f4bac063..5bf0cb5a 100644 --- a/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp @@ -1114,8 +1114,7 @@ void FAssetEditor_MounteaDialogueGraph::ValidateGraph() UEdGraph_MounteaDialogueGraph* EdGraph = Cast(EditingGraph->EdGraph); check(EdGraph != nullptr); - const FScopedTransaction Transaction(LOCTEXT("MounteaDialogueGraphEditorValidateGraph", - "Mountea Dialogue Graph Editor: Validate Graph.")); + const FScopedTransaction Transaction(LOCTEXT("MounteaDialogueGraphEditorValidateGraph", "Mountea Dialogue Graph Editor: Validate Graph.")); UMounteaDialogueGraph* MounteaGraph = EdGraph->GetMounteaDialogueGraph(); check(MounteaGraph != nullptr); diff --git a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp index 255e7a94..cf58208f 100644 --- a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp @@ -2,6 +2,7 @@ #include "AssetGraphScheme_MounteaDialogueGraph.h" +#include "FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h" #include "FConnectionDrawingPolicy_MounteaDialogueGraph.h" #include "GraphEditorActions.h" #include "Graph/MounteaDialogueGraph.h" @@ -432,7 +433,6 @@ bool UAssetGraphScheme_MounteaDialogueGraph::CreateAutomaticConversionNodeAndCon FConnectionDrawingPolicy* UAssetGraphScheme_MounteaDialogueGraph::CreateConnectionDrawingPolicy(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements, UEdGraph* InGraphObj) const { - /* if (const UMounteaDialogueGraphEditorSettings* MounteaDialogueGraphEditorSettings = GetMutableDefault()) { if (MounteaDialogueGraphEditorSettings->AllowAdvancedWiring()) @@ -440,7 +440,6 @@ FConnectionDrawingPolicy* UAssetGraphScheme_MounteaDialogueGraph::CreateConnecti return new FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph(InBackLayerID, InFrontLayerID, InZoomFactor, InClippingRect, InDrawElements, InGraphObj); } } - */ return new FConnectionDrawingPolicy_MounteaDialogueGraph(InBackLayerID, InFrontLayerID, InZoomFactor, InClippingRect, InDrawElements, InGraphObj); } diff --git a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp new file mode 100644 index 00000000..5226ef20 --- /dev/null +++ b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp @@ -0,0 +1,136 @@ +// All rights reserved Dominik Morse (Pavlicek) 2024 + + +#include "FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h" + +#include "EditorStyle/FMounteaDialogueGraphEditorStyle.h" +#include "Settings/MounteaDialogueGraphEditorSettings.h" + +FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements, UEdGraph* InGraphObj) + : FKismetConnectionDrawingPolicy(InBackLayerID, InFrontLayerID, InZoomFactor, InClippingRect, InDrawElements, InGraphObj) + , StoredBackLayerID(InBackLayerID) + , StoredFrontLayerID(InFrontLayerID) +{ + if (const UMounteaDialogueGraphEditorSettings* GraphEditorSettings = GetMutableDefault()) + { + switch (GraphEditorSettings->GetArrowType()) + { + case EArrowType::ERT_SimpleArrow: + ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.SimpleArrow")); + break; + case EArrowType::ERT_HollowArrow: + ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.HollowArrow")); + break; + case EArrowType::ERT_FancyArrow: + ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.FancyArrow")); + break; + case EArrowType::ERT_Bubble: + ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.Bubble")); + break; + case EArrowType::ERT_None: + default: + ArrowImage = nullptr; + } + } + else + { + ArrowImage = FAppStyle::GetBrush( TEXT("GenericPlay") ); + } + + ArrowRadius = ArrowImage ? ArrowImage->ImageSize * ZoomFactor * 0.5f : FVector2D(0.f); + MidpointImage = nullptr; + MidpointRadius = FVector2D::ZeroVector; + HoverDeemphasisDarkFraction = 0.8f; +} + +void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawSplineWithArrow(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params) +{ + DrawManhattanConnection(StartPoint, EndPoint, Params); +} + +void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawSplineWithArrow(const FGeometry& StartGeom, const FGeometry& EndGeom, const FConnectionParams& Params) +{ + const FVector2D StartPoint = FGeometryHelper::CenterOf(StartGeom); + const FVector2D EndPoint = FGeometryHelper::CenterOf(EndGeom); + DrawManhattanConnection(StartPoint, EndPoint, Params); +} + +FVector2D FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::ComputeSplineTangent(const FVector2D& Start, const FVector2D& End) const +{ + return FVector2D(0.f, 0.f); // Not used for Manhattan-style lines +} + +void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawManhattanConnection(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params) +{ + const float VerticalOffset = 20.0f; // Adjust this value to control the vertical segment positioning + const float HorizontalOffset = 0.0f; // Adjust this value to control the horizontal segment positioning + + TArray Points; + Points.Add(StartPoint); + + // Determine if we need to go up or down first + if (EndPoint.Y > StartPoint.Y) + { + // Go down first + Points.Add(FVector2D(StartPoint.X, StartPoint.Y + VerticalOffset)); + Points.Add(FVector2D(EndPoint.X - HorizontalOffset, StartPoint.Y + VerticalOffset)); + Points.Add(FVector2D(EndPoint.X - HorizontalOffset, EndPoint.Y)); + } + else + { + // Go up first + Points.Add(FVector2D(StartPoint.X, EndPoint.Y - VerticalOffset)); + Points.Add(FVector2D(EndPoint.X - HorizontalOffset, EndPoint.Y - VerticalOffset)); + Points.Add(FVector2D(EndPoint.X - HorizontalOffset, EndPoint.Y)); + } + + Points.Add(EndPoint); + + // Draw the Manhattan connection + for (int32 i = 0; i < Points.Num() - 1; ++i) + { + FSlateDrawElement::MakeLines( + DrawElementsList, + StoredBackLayerID, + FPaintGeometry(), + { Points[i], Points[i + 1] }, + ESlateDrawEffect::None, + Params.WireColor, + false, + Params.WireThickness + ); + } + + float imageOffset = ArrowImage ? ArrowImage->GetImageSize().X / 2 : 8.f; + FVector2D ArrowEndpoint = FVector2D(EndPoint.X - imageOffset, EndPoint.Y - VerticalOffset - imageOffset); + + // Draw the arrow at the end + DrawArrow(Points[Points.Num() - 2], ArrowEndpoint, Params); +} + +void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawArrow(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params) +{ + if (!ArrowImage) + { + return; + } + + const FVector2D ArrowSize(16.0f, 16.0f); // Adjust this size as needed + const FVector2D ArrowDirection = (EndPoint - StartPoint).GetSafeNormal(); + const FVector2D ArrowPosition = EndPoint - ArrowDirection * ArrowSize.X * 0.5f; + + //const float AngleInRadians = FMath::Atan2(ArrowDirection.Y, ArrowDirection.X); + const float AngleInRadians = FMath::DegreesToRadians(90.f); + + FSlateDrawElement::MakeRotatedBox( + DrawElementsList, + StoredFrontLayerID, + FPaintGeometry(ArrowPosition, ArrowSize, ZoomFactor), + ArrowImage, + ESlateDrawEffect::None, + AngleInRadians, + TOptional(), + FSlateDrawElement::RelativeToElement, + Params.WireColor + ); +} \ No newline at end of file diff --git a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h new file mode 100644 index 00000000..a755acd8 --- /dev/null +++ b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h @@ -0,0 +1,26 @@ +// All rights reserved Dominik Morse (Pavlicek) 2024 + +#pragma once + +#include "CoreMinimal.h" +#include "BlueprintConnectionDrawingPolicy.h" +#include "ConnectionDrawingPolicy.h" + +class FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph : public FKismetConnectionDrawingPolicy +{ +public: + FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements, UEdGraph* InGraphObj); + + virtual void DrawSplineWithArrow(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params) override; + virtual void DrawSplineWithArrow(const FGeometry& StartGeom, const FGeometry& EndGeom, const FConnectionParams& Params) override; + virtual FVector2D ComputeSplineTangent(const FVector2D& Start, const FVector2D& End) const override; + +protected: + void DrawManhattanConnection(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params); + void DrawArrow(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params); + +private: + int32 StoredBackLayerID; + int32 StoredFrontLayerID; +}; + From 0c78d94665bd6c75af5c6b1b36541473f549e485 Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 14:41:07 +0200 Subject: [PATCH 07/14] Brute Manhattan Drawing Policy --- ...ingPolicy_AdvancedMounteaDialogueGraph.cpp | 202 ++++++++++++++---- ...awingPolicy_AdvancedMounteaDialogueGraph.h | 10 +- 2 files changed, 169 insertions(+), 43 deletions(-) diff --git a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp index 5226ef20..222711da 100644 --- a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp @@ -10,26 +10,29 @@ FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::FConnectionDrawingPolicy_ : FKismetConnectionDrawingPolicy(InBackLayerID, InFrontLayerID, InZoomFactor, InClippingRect, InDrawElements, InGraphObj) , StoredBackLayerID(InBackLayerID) , StoredFrontLayerID(InFrontLayerID) + , ZoomFactor(InZoomFactor) + , RoundRadius(FMath::Clamp(20.0f / InZoomFactor, 5.0f, 10.0f)) + , WireThickness(1.5f) { if (const UMounteaDialogueGraphEditorSettings* GraphEditorSettings = GetMutableDefault()) { switch (GraphEditorSettings->GetArrowType()) { - case EArrowType::ERT_SimpleArrow: - ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.SimpleArrow")); - break; - case EArrowType::ERT_HollowArrow: - ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.HollowArrow")); - break; - case EArrowType::ERT_FancyArrow: - ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.FancyArrow")); - break; - case EArrowType::ERT_Bubble: - ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.Bubble")); - break; - case EArrowType::ERT_None: - default: - ArrowImage = nullptr; + case EArrowType::ERT_SimpleArrow: + ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.SimpleArrow")); + break; + case EArrowType::ERT_HollowArrow: + ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.HollowArrow")); + break; + case EArrowType::ERT_FancyArrow: + ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.FancyArrow")); + break; + case EArrowType::ERT_Bubble: + ArrowImage = FMounteaDialogueGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.Bubble")); + break; + case EArrowType::ERT_None: + default: + ArrowImage = nullptr; } } else @@ -57,55 +60,170 @@ void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawSplineWithArrow( FVector2D FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::ComputeSplineTangent(const FVector2D& Start, const FVector2D& End) const { - return FVector2D(0.f, 0.f); // Not used for Manhattan-style lines + return FVector2D(0.0f, 1.0f); // Default tangent for top-down connections } -void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawManhattanConnection(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params) +void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawManhattanConnection(const FVector2D& Start, const FVector2D& End, const FConnectionParams& Params) { - const float VerticalOffset = 20.0f; // Adjust this value to control the vertical segment positioning - const float HorizontalOffset = 0.0f; // Adjust this value to control the horizontal segment positioning + const FVector2D StartDirection(0.0f, 1.0f); + const FVector2D EndDirection(0.0f, -1.0f); - TArray Points; - Points.Add(StartPoint); + if (FMath::IsNearlyEqual((End - Start).SizeSquared(), 0.0f, KINDA_SMALL_NUMBER)) + { + return; + } + + const float DistanceY = End.Y - Start.Y; + const float DistanceX = End.X - Start.X; - // Determine if we need to go up or down first - if (EndPoint.Y > StartPoint.Y) + if (FMath::IsNearlyZero(DistanceX, 1.0f)) { - // Go down first - Points.Add(FVector2D(StartPoint.X, StartPoint.Y + VerticalOffset)); - Points.Add(FVector2D(EndPoint.X - HorizontalOffset, StartPoint.Y + VerticalOffset)); - Points.Add(FVector2D(EndPoint.X - HorizontalOffset, EndPoint.Y)); + // Straight vertical line + FSlateDrawElement::MakeLines( + DrawElementsList, + StoredBackLayerID, + FPaintGeometry(), + { Start, End }, + ESlateDrawEffect::None, + Params.WireColor, + false, + Params.WireThickness * WireThickness + ); } - else + else if (DistanceY < 2 * RoundRadius) { - // Go up first - Points.Add(FVector2D(StartPoint.X, EndPoint.Y - VerticalOffset)); - Points.Add(FVector2D(EndPoint.X - HorizontalOffset, EndPoint.Y - VerticalOffset)); - Points.Add(FVector2D(EndPoint.X - HorizontalOffset, EndPoint.Y)); + // Direct connection with a single curve + FVector2D MidPoint = (Start + End) * 0.5f; + FVector2D MidDirection = FVector2D(DistanceX, 0.0f).GetSafeNormal(); + + DrawRadius(Start, StartDirection, MidPoint, MidDirection, 90); + DrawRadius(MidPoint, MidDirection, End, EndDirection, 90); } + else + { + // Connection with vertical segments and two curves + FVector2D VerticalStart, VerticalStartDirection; + FVector2D VerticalEnd, VerticalEndDirection; + + if (DistanceX > 0) + { + // Normal case: target is to the right + DrawSimpleRadius(Start, StartDirection, 90, VerticalStart, VerticalStartDirection); + DrawSimpleRadius(End, EndDirection, -90, VerticalEnd, VerticalEndDirection); + } + else + { + // Inverted case: target is to the left + DrawSimpleRadius(Start, StartDirection, -90, VerticalStart, VerticalStartDirection); + DrawSimpleRadius(End, EndDirection, 90, VerticalEnd, VerticalEndDirection); + } - Points.Add(EndPoint); + // Draw vertical segment + FSlateDrawElement::MakeLines( + DrawElementsList, + StoredBackLayerID, + FPaintGeometry(), + { VerticalStart, FVector2D(VerticalStart.X, VerticalEnd.Y) }, + ESlateDrawEffect::None, + Params.WireColor, + false, + Params.WireThickness * WireThickness + ); - // Draw the Manhattan connection - for (int32 i = 0; i < Points.Num() - 1; ++i) - { + // Draw horizontal segment FSlateDrawElement::MakeLines( DrawElementsList, StoredBackLayerID, FPaintGeometry(), - { Points[i], Points[i + 1] }, + { FVector2D(VerticalStart.X, VerticalEnd.Y), FVector2D(VerticalEnd.X, VerticalEnd.Y) }, ESlateDrawEffect::None, Params.WireColor, false, - Params.WireThickness + Params.WireThickness * WireThickness ); } - float imageOffset = ArrowImage ? ArrowImage->GetImageSize().X / 2 : 8.f; - FVector2D ArrowEndpoint = FVector2D(EndPoint.X - imageOffset, EndPoint.Y - VerticalOffset - imageOffset); + // Draw the arrow + DrawArrow(FVector2D(End.X, End.Y - GetRadiusOffset(90)), End, Params); +} + +void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawSimpleRadius(const FVector2D& Start, const FVector2D& StartDirection, const int32& AngleDeg, FVector2D& out_End, FVector2D& out_EndDirection) +{ + float StartOffset = GetRadiusOffset(AngleDeg, false); + float PerpendicularOffset = GetRadiusOffset(AngleDeg, true); + FVector2D PerpendicularDirection = StartDirection.GetRotated(FMath::Sign(AngleDeg) * 90); + out_EndDirection = StartDirection.GetRotated(AngleDeg); + + out_End = Start + (StartDirection * StartOffset + PerpendicularDirection * PerpendicularOffset); + DrawRadius(Start, StartDirection, out_End, out_EndDirection, AngleDeg); +} + +void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawRadius(const FVector2D& Start, const FVector2D& StartDirection, const FVector2D& End, const FVector2D& EndDirection, const int32& AngleDeg) +{ + const float Tangent = GetRadiusTangent(AngleDeg); + + FSlateDrawElement::MakeDrawSpaceSpline( + DrawElementsList, + StoredBackLayerID, + Start, StartDirection * Tangent, + End, EndDirection * Tangent, + WireThickness + ); +} + +float FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::GetRadiusOffset(const int32& AngleDeg, bool Perpendicular) const +{ + float RadiusOffset = 1.0f; + int32 AbsAngle = FMath::Abs(AngleDeg); + + if (Perpendicular) + { + AbsAngle = 180 - AbsAngle; + } + + switch (AbsAngle) + { + case 45: + RadiusOffset *= FMath::Sqrt(2.0f) / 2.0f; + break; + case 90: + RadiusOffset = 1.0f; // Direct adjustment for 90-degree angles + break; + case 135: + RadiusOffset *= (1.0f - (FMath::Sqrt(2.0f) / 2.0f)); + break; + case 180: + RadiusOffset *= 1.0f; // Avoid extreme radius for straight lines + break; + } + + return RadiusOffset * ZoomFactor * FMath::Clamp(RoundRadius, 10.0f, 20.0f); // Clamp the radius for stability +} + +float FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::GetRadiusTangent(const int32& AngleDeg) const +{ + float Tangent = 2 * FMath::Sqrt(2.0f) - 1; + + switch (FMath::Abs(AngleDeg)) + { + case 0: + Tangent *= 4.0f / Tangent; + break; + case 45: + Tangent *= 0.55166f; + break; + case 90: + Tangent = 4 * (FMath::Sqrt(2.0f) - 1); + break; + case 135: + Tangent *= 2.0f / Tangent; + break; + case 180: + Tangent *= 4.0f / Tangent; + break; + } - // Draw the arrow at the end - DrawArrow(Points[Points.Num() - 2], ArrowEndpoint, Params); + return Tangent * ZoomFactor * RoundRadius; } void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawArrow(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params) diff --git a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h index a755acd8..d2bef0fd 100644 --- a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h +++ b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h @@ -16,11 +16,19 @@ class FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph : public FKismetConn virtual FVector2D ComputeSplineTangent(const FVector2D& Start, const FVector2D& End) const override; protected: - void DrawManhattanConnection(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params); + void DrawManhattanConnection(const FVector2D& Start, const FVector2D& End, const FConnectionParams& Params); + void DrawSimpleRadius(const FVector2D& Start, const FVector2D& StartDirection, const int32& AngleDeg, FVector2D& out_End, FVector2D& out_EndDirection); + void DrawRadius(const FVector2D& Start, const FVector2D& StartDirection, const FVector2D& End, const FVector2D& EndDirection, const int32& AngleDeg); void DrawArrow(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params); + float GetRadiusOffset(const int32& AngleDeg, bool Perpendicular = false) const; + float GetRadiusTangent(const int32& AngleDeg) const; + private: int32 StoredBackLayerID; int32 StoredFrontLayerID; + float ZoomFactor; + float RoundRadius; + float WireThickness; }; From b17bfe49a437f80e2d5b2a108d5904649aca261a Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 14:42:45 +0200 Subject: [PATCH 08/14] A little visual update --- .../AssetGraphScheme_MounteaDialogueGraph.cpp | 3 +- ...ingPolicy_AdvancedMounteaDialogueGraph.cpp | 149 ++++-------------- ...awingPolicy_AdvancedMounteaDialogueGraph.h | 3 - ...tionDrawingPolicy_MounteaDialogueGraph.cpp | 2 +- .../MounteaDialogueGraphEditorSettings.h | 4 +- 5 files changed, 32 insertions(+), 129 deletions(-) diff --git a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp index cf58208f..38a8c705 100644 --- a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp @@ -433,6 +433,7 @@ bool UAssetGraphScheme_MounteaDialogueGraph::CreateAutomaticConversionNodeAndCon FConnectionDrawingPolicy* UAssetGraphScheme_MounteaDialogueGraph::CreateConnectionDrawingPolicy(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements, UEdGraph* InGraphObj) const { + /* if (const UMounteaDialogueGraphEditorSettings* MounteaDialogueGraphEditorSettings = GetMutableDefault()) { if (MounteaDialogueGraphEditorSettings->AllowAdvancedWiring()) @@ -440,7 +441,7 @@ FConnectionDrawingPolicy* UAssetGraphScheme_MounteaDialogueGraph::CreateConnecti return new FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph(InBackLayerID, InFrontLayerID, InZoomFactor, InClippingRect, InDrawElements, InGraphObj); } } - + */ return new FConnectionDrawingPolicy_MounteaDialogueGraph(InBackLayerID, InFrontLayerID, InZoomFactor, InClippingRect, InDrawElements, InGraphObj); } diff --git a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp index 222711da..f925b0fe 100644 --- a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.cpp @@ -2,7 +2,6 @@ #include "FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h" - #include "EditorStyle/FMounteaDialogueGraphEditorStyle.h" #include "Settings/MounteaDialogueGraphEditorSettings.h" @@ -39,7 +38,7 @@ FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::FConnectionDrawingPolicy_ { ArrowImage = FAppStyle::GetBrush( TEXT("GenericPlay") ); } - + ArrowRadius = ArrowImage ? ArrowImage->ImageSize * ZoomFactor * 0.5f : FVector2D(0.f); MidpointImage = nullptr; MidpointRadius = FVector2D::ZeroVector; @@ -65,110 +64,43 @@ FVector2D FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::ComputeSplineTa void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawManhattanConnection(const FVector2D& Start, const FVector2D& End, const FConnectionParams& Params) { - const FVector2D StartDirection(0.0f, 1.0f); - const FVector2D EndDirection(0.0f, -1.0f); - - if (FMath::IsNearlyEqual((End - Start).SizeSquared(), 0.0f, KINDA_SMALL_NUMBER)) - { - return; - } - const float DistanceY = End.Y - Start.Y; const float DistanceX = End.X - Start.X; - if (FMath::IsNearlyZero(DistanceX, 1.0f)) - { - // Straight vertical line - FSlateDrawElement::MakeLines( - DrawElementsList, - StoredBackLayerID, - FPaintGeometry(), - { Start, End }, - ESlateDrawEffect::None, - Params.WireColor, - false, - Params.WireThickness * WireThickness - ); - } - else if (DistanceY < 2 * RoundRadius) - { - // Direct connection with a single curve - FVector2D MidPoint = (Start + End) * 0.5f; - FVector2D MidDirection = FVector2D(DistanceX, 0.0f).GetSafeNormal(); + // Vertical offset for the horizontal segment + const float VerticalOffset = FMath::Min(abs(DistanceY) * 0.5f, 50.0f); + + // Calculate control points for the curve + FVector2D ControlPoint1, ControlPoint2; - DrawRadius(Start, StartDirection, MidPoint, MidDirection, 90); - DrawRadius(MidPoint, MidDirection, End, EndDirection, 90); + if (DistanceY >= 0) + { + // Downward connection + ControlPoint1 = FVector2D(Start.X, Start.Y + VerticalOffset); + ControlPoint2 = FVector2D(End.X, End.Y - VerticalOffset); } else { - // Connection with vertical segments and two curves - FVector2D VerticalStart, VerticalStartDirection; - FVector2D VerticalEnd, VerticalEndDirection; - - if (DistanceX > 0) - { - // Normal case: target is to the right - DrawSimpleRadius(Start, StartDirection, 90, VerticalStart, VerticalStartDirection); - DrawSimpleRadius(End, EndDirection, -90, VerticalEnd, VerticalEndDirection); - } - else - { - // Inverted case: target is to the left - DrawSimpleRadius(Start, StartDirection, -90, VerticalStart, VerticalStartDirection); - DrawSimpleRadius(End, EndDirection, 90, VerticalEnd, VerticalEndDirection); - } - - // Draw vertical segment - FSlateDrawElement::MakeLines( - DrawElementsList, - StoredBackLayerID, - FPaintGeometry(), - { VerticalStart, FVector2D(VerticalStart.X, VerticalEnd.Y) }, - ESlateDrawEffect::None, - Params.WireColor, - false, - Params.WireThickness * WireThickness - ); - - // Draw horizontal segment - FSlateDrawElement::MakeLines( - DrawElementsList, - StoredBackLayerID, - FPaintGeometry(), - { FVector2D(VerticalStart.X, VerticalEnd.Y), FVector2D(VerticalEnd.X, VerticalEnd.Y) }, - ESlateDrawEffect::None, - Params.WireColor, - false, - Params.WireThickness * WireThickness - ); + // Upward connection + ControlPoint1 = FVector2D(Start.X, Start.Y - VerticalOffset); + ControlPoint2 = FVector2D(End.X, End.Y + VerticalOffset); } - // Draw the arrow - DrawArrow(FVector2D(End.X, End.Y - GetRadiusOffset(90)), End, Params); -} - -void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawSimpleRadius(const FVector2D& Start, const FVector2D& StartDirection, const int32& AngleDeg, FVector2D& out_End, FVector2D& out_EndDirection) -{ - float StartOffset = GetRadiusOffset(AngleDeg, false); - float PerpendicularOffset = GetRadiusOffset(AngleDeg, true); - FVector2D PerpendicularDirection = StartDirection.GetRotated(FMath::Sign(AngleDeg) * 90); - out_EndDirection = StartDirection.GetRotated(AngleDeg); - - out_End = Start + (StartDirection * StartOffset + PerpendicularDirection * PerpendicularOffset); - DrawRadius(Start, StartDirection, out_End, out_EndDirection, AngleDeg); -} - -void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawRadius(const FVector2D& Start, const FVector2D& StartDirection, const FVector2D& End, const FVector2D& EndDirection, const int32& AngleDeg) -{ - const float Tangent = GetRadiusTangent(AngleDeg); - + // Draw the spline FSlateDrawElement::MakeDrawSpaceSpline( DrawElementsList, StoredBackLayerID, - Start, StartDirection * Tangent, - End, EndDirection * Tangent, - WireThickness + Start, + ControlPoint1, + ControlPoint2, + End, + Params.WireThickness * WireThickness, + ESlateDrawEffect::None, + Params.WireColor ); + + // Draw the arrow + DrawArrow(ControlPoint2, End, Params); } float FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::GetRadiusOffset(const int32& AngleDeg, bool Perpendicular) const @@ -200,32 +132,6 @@ float FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::GetRadiusOffset(con return RadiusOffset * ZoomFactor * FMath::Clamp(RoundRadius, 10.0f, 20.0f); // Clamp the radius for stability } -float FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::GetRadiusTangent(const int32& AngleDeg) const -{ - float Tangent = 2 * FMath::Sqrt(2.0f) - 1; - - switch (FMath::Abs(AngleDeg)) - { - case 0: - Tangent *= 4.0f / Tangent; - break; - case 45: - Tangent *= 0.55166f; - break; - case 90: - Tangent = 4 * (FMath::Sqrt(2.0f) - 1); - break; - case 135: - Tangent *= 2.0f / Tangent; - break; - case 180: - Tangent *= 4.0f / Tangent; - break; - } - - return Tangent * ZoomFactor * RoundRadius; -} - void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawArrow(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params) { if (!ArrowImage) @@ -233,12 +139,11 @@ void FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph::DrawArrow(const FVec return; } - const FVector2D ArrowSize(16.0f, 16.0f); // Adjust this size as needed + const FVector2D ArrowSize(16.0f, 16.0f); const FVector2D ArrowDirection = (EndPoint - StartPoint).GetSafeNormal(); const FVector2D ArrowPosition = EndPoint - ArrowDirection * ArrowSize.X * 0.5f; - //const float AngleInRadians = FMath::Atan2(ArrowDirection.Y, ArrowDirection.X); - const float AngleInRadians = FMath::DegreesToRadians(90.f); + const float AngleInRadians = FMath::Atan2(ArrowDirection.Y, ArrowDirection.X); FSlateDrawElement::MakeRotatedBox( DrawElementsList, diff --git a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h index d2bef0fd..e1af8647 100644 --- a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h +++ b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph.h @@ -17,12 +17,9 @@ class FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph : public FKismetConn protected: void DrawManhattanConnection(const FVector2D& Start, const FVector2D& End, const FConnectionParams& Params); - void DrawSimpleRadius(const FVector2D& Start, const FVector2D& StartDirection, const int32& AngleDeg, FVector2D& out_End, FVector2D& out_EndDirection); - void DrawRadius(const FVector2D& Start, const FVector2D& StartDirection, const FVector2D& End, const FVector2D& EndDirection, const int32& AngleDeg); void DrawArrow(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params); float GetRadiusOffset(const int32& AngleDeg, bool Perpendicular = false) const; - float GetRadiusTangent(const int32& AngleDeg) const; private: int32 StoredBackLayerID; diff --git a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_MounteaDialogueGraph.cpp index 6c77ef90..9dcd0905 100644 --- a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_MounteaDialogueGraph.cpp @@ -194,7 +194,7 @@ void FConnectionDrawingPolicy_MounteaDialogueGraph::Internal_DrawLineWithArrow(c return; } - const bool bIsAligned = FMath::IsNearlyEqual(EndPoint.X, StartPoint.X, GraphSettings->GetControlPointDistance()); + const bool bIsAligned = FMath::IsNearlyEqual(EndPoint.X, StartPoint.X, GraphSettings->GetControlPointDistance() * ZoomFactor); // Choose connection drawing method based on conditions if (bIsAligned) diff --git a/Source/MounteaDialogueSystemEditor/Private/Settings/MounteaDialogueGraphEditorSettings.h b/Source/MounteaDialogueSystemEditor/Private/Settings/MounteaDialogueGraphEditorSettings.h index fd581a7f..f2120d48 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Settings/MounteaDialogueGraphEditorSettings.h +++ b/Source/MounteaDialogueSystemEditor/Private/Settings/MounteaDialogueGraphEditorSettings.h @@ -151,10 +151,10 @@ class MOUNTEADIALOGUESYSTEMEDITOR_API UMounteaDialogueGraphEditorSettings : publ bool bUseAdvancedWiring; UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "NodeWiring", meta=(ToolTip="[BETA] Feature]", EditCondition="bUseAdvancedWiring")) - FVector2D AdvancedWiringConnectionTangent = FVector2D(0.0f, 220.f); + FVector2D AdvancedWiringConnectionTangent = FVector2D(0.0f, 100.f); UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "NodeWiring", meta=(ToolTip="[BETA] Feature]", EditCondition="bUseAdvancedWiring")) - float ControlPointDistance = 150.0f; + float ControlPointDistance = 100.0f; /* Advanced Wiring doesn't work now From aed904b6a196e6cba9613685184232ab1cb4b211 Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 14:49:19 +0200 Subject: [PATCH 09/14] Export/Import of Execution Order --- .../Helpers/MounteaDialogueSystemImportExportHelpers.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/MounteaDialogueSystemEditor/Private/Helpers/MounteaDialogueSystemImportExportHelpers.cpp b/Source/MounteaDialogueSystemEditor/Private/Helpers/MounteaDialogueSystemImportExportHelpers.cpp index a9431b0c..96980809 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Helpers/MounteaDialogueSystemImportExportHelpers.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/Helpers/MounteaDialogueSystemImportExportHelpers.cpp @@ -1131,6 +1131,7 @@ void UMounteaDialogueSystemImportExportHelpers::PopulateNodeData(UMounteaDialogu Node->SetNodeGUID(FGuid(JsonObject->GetStringField("id"))); Node->NodeTitle = FText::FromString(JsonObject->GetObjectField("data")->GetStringField("title")); + Node->ExecutionOrder = JsonObject->GetIntegerField(TEXT("executionOrder")); TSharedPtr AdditionalInfoObject = JsonObject->GetObjectField("data")->GetObjectField("additionalInfo"); if (AdditionalInfoObject->HasField("targetNodeId") && Node->Graph) @@ -1589,6 +1590,7 @@ FString UMounteaDialogueSystemImportExportHelpers::CreateNodesJson(const TArray< TSharedPtr NodeObject = MakeShareable(new FJsonObject); NodeObject->SetStringField("id", Data.Node->GetNodeGUID().ToString(EGuidFormats::DigitsWithHyphensLower)); NodeObject->SetStringField("type", Data.Type); + NodeObject->SetNumberField(TEXT("executionOrder"), Data.Node->ExecutionOrder); AddNodePosition(NodeObject, Data.Node); AddNodeData(NodeObject, Data.Node); From 8873eb86b1cb35c181ec4408ae9078f96f88fd0d Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 14:49:57 +0200 Subject: [PATCH 10/14] Version update --- MounteaDialogueSystem.uplugin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MounteaDialogueSystem.uplugin b/MounteaDialogueSystem.uplugin index b50f23e8..a1dc8df0 100644 --- a/MounteaDialogueSystem.uplugin +++ b/MounteaDialogueSystem.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, "Version": 2, - "VersionName": "2.0.3.51", + "VersionName": "2.0.4.51", "FriendlyName": "Mountea Dialogue System", "Description": "Mountea Dialogue System is an Open-source Mountea Framework tool for Unreal Engine for creating (not just) complex dialogues!\nProvides its own Dialogue Tree editor and validation system.", "Category": "Mountea Framework", From 1ea47799e8f520450cbe51640fd9ff7ebed4642c Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 19:24:41 +0200 Subject: [PATCH 11/14] Node Order fix & Node connections fix --- .../Nodes/MounteaDialogueGraphNode.cpp | 2 +- .../AssetEditor_MounteaDialogueGraph.cpp | 2 +- .../Ed/EdGraph_MounteaDialogueGraph.cpp | 29 ++++-- ...tionDrawingPolicy_MounteaDialogueGraph.cpp | 98 +++++-------------- 4 files changed, 50 insertions(+), 81 deletions(-) diff --git a/Source/MounteaDialogueSystem/Private/Nodes/MounteaDialogueGraphNode.cpp b/Source/MounteaDialogueSystem/Private/Nodes/MounteaDialogueGraphNode.cpp index 013bbfa4..3f5f0d5d 100644 --- a/Source/MounteaDialogueSystem/Private/Nodes/MounteaDialogueGraphNode.cpp +++ b/Source/MounteaDialogueSystem/Private/Nodes/MounteaDialogueGraphNode.cpp @@ -434,7 +434,7 @@ FText UMounteaDialogueGraphNode::GetDefaultTooltipBody() const const FText Implements = FText::Format(LOCTEXT("UMounteaDialogueGraphNode_ImplementsTooltip", "Implements Decorators: {0}"), ImplementsNumber); - return FText::Format(LOCTEXT("UMounteaDialogueGraphNode_BaseTooltip", "{0} - {1}\n\n{2}\n{3}\nNode Execution Order: {4}"), NodeTypeName, FText::FromString(NodeGUID.ToString()), Inherits, Implements, ExecutionOrder); + return FText::Format(LOCTEXT("UMounteaDialogueGraphNode_BaseTooltip", "{0} - {1}\n\n{2}\n{3}\nNode Execution Order: {4}"), NodeTypeName, FText::FromString(NodeGUID.ToString(EGuidFormats::DigitsWithHyphensLower)), Inherits, Implements, ExecutionOrder); } #endif diff --git a/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp index 5bf0cb5a..bcdb3b06 100644 --- a/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/AssetEditor/AssetEditor_MounteaDialogueGraph.cpp @@ -49,7 +49,7 @@ const FName FAssetEditorTabs_MounteaDialogueGraph::SearchToolbarID(TEXT("Search" void FAssetEditor_MounteaDialogueGraph::OnPackageSaved(const FString& String, UPackage* Package, FObjectPostSaveContext ObjectPostSaveContext) { - RebuildMounteaDialogueGraph(); + //RebuildMounteaDialogueGraph(); } FAssetEditor_MounteaDialogueGraph::FAssetEditor_MounteaDialogueGraph() diff --git a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp index 1bccaf76..a51019ba 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp @@ -22,7 +22,6 @@ UEdGraph_MounteaDialogueGraph::~UEdGraph_MounteaDialogueGraph() void UEdGraph_MounteaDialogueGraph::RebuildMounteaDialogueGraph() { - UMounteaDialogueGraph* Graph = GetMounteaDialogueGraph(); Clear(); @@ -147,8 +146,6 @@ bool UEdGraph_MounteaDialogueGraph::Modify(bool bAlwaysMarkDirty) { bool Rtn = Super::Modify(bAlwaysMarkDirty); - GetMounteaDialogueGraph()->Modify(); - for (int32 i = 0; i < Nodes.Num(); ++i) { Nodes[i]->Modify(); @@ -275,24 +272,40 @@ void UEdGraph_MounteaDialogueGraph::AssignExecutionOrder() TArray& NodesInLayer = LayeredNodes[LayerIndex]; NodesInLayer.Sort([this](const UMounteaDialogueGraphNode& A, const UMounteaDialogueGraphNode& B) { - // Prefer node order based on their parent's order UEdNode_MounteaDialogueGraphNode* EdNode_A = NodeMap[&A]; UEdNode_MounteaDialogueGraphNode* EdNode_B = NodeMap[&B]; UMounteaDialogueGraphNode* ParentA = GetParentNode(A); UMounteaDialogueGraphNode* ParentB = GetParentNode(B); - if (ParentA->ExecutionOrder == ParentB->ExecutionOrder) + + if (ParentA && !ParentB) return true; + if (!ParentA && ParentB) return false; + + if (ParentA && ParentB) { - return EdNode_A->NodePosX < EdNode_B->NodePosX; + if (ParentA->ExecutionOrder != ParentB->ExecutionOrder) + { + return ParentA->ExecutionOrder < ParentB->ExecutionOrder; + } } - return ParentA->ExecutionOrder < ParentB->ExecutionOrder; + + // If we reach here, either both nodes have no parents or have parents with the same execution order + // In this case, sort based on X position + return EdNode_A->NodePosX < EdNode_B->NodePosX; }); for (UMounteaDialogueGraphNode* Node : NodesInLayer) { if (Node) { - Node->ExecutionOrder = CurrentExecutionOrder++; + if (UMounteaDialogueGraphNode* ParentNode = GetParentNode(*Node)) + { + Node->ExecutionOrder = CurrentExecutionOrder++; + } + else + { + Node->ExecutionOrder = INDEX_NONE; + } } } } diff --git a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_MounteaDialogueGraph.cpp index 9dcd0905..bebda42f 100644 --- a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/FConnectionDrawingPolicy_MounteaDialogueGraph.cpp @@ -86,18 +86,8 @@ void FConnectionDrawingPolicy_MounteaDialogueGraph::Draw(TMap()) { @@ -126,7 +113,7 @@ void FConnectionDrawingPolicy_MounteaDialogueGraph::DrawPreviewConnector(const F FConnectionParams Params; DetermineWiringStyle(Pin, nullptr, /*inout*/ Params); - if (Pin->Direction == EEdGraphPinDirection::EGPD_Output) + if (Pin->Direction == EGPD_Output) { DrawSplineWithArrow(FGeometryHelper::FindClosestPointOnGeom(PinGeometry, EndPoint), EndPoint, Params); } @@ -175,43 +162,34 @@ void FConnectionDrawingPolicy_MounteaDialogueGraph::DetermineLinkGeometry(FArran void FConnectionDrawingPolicy_MounteaDialogueGraph::Internal_DrawLineWithArrow(const FVector2D& StartAnchorPoint, const FVector2D& EndAnchorPoint, const FConnectionParams& Params) { - const float LineSeparationAmount = 4.5f; - const FVector2D DeltaPos = EndAnchorPoint - StartAnchorPoint; const FVector2D UnitDelta = DeltaPos.GetSafeNormal(); - const FVector2D Normal = FVector2D(DeltaPos.Y, -DeltaPos.X).GetSafeNormal(); - // Come up with the final start/end points - const FVector2D DirectionBias = Normal * LineSeparationAmount; - const FVector2D LengthBias = ArrowRadius.X * UnitDelta; - const FVector2D StartPoint = StartAnchorPoint + DirectionBias + LengthBias; - const FVector2D EndPoint = EndAnchorPoint + DirectionBias - LengthBias; - - const UMounteaDialogueGraphEditorSettings* GraphSettings = GetDefault(); - if (GraphSettings == nullptr || GraphSettings->AllowAdvancedWiring() == false) - { - DrawConnection(WireLayerID, StartPoint, EndPoint, Params); - return; - } + const FVector2D StartPoint = StartAnchorPoint; + const FVector2D EndPoint = EndAnchorPoint - (ArrowRadius.X * UnitDelta); - const bool bIsAligned = FMath::IsNearlyEqual(EndPoint.X, StartPoint.X, GraphSettings->GetControlPointDistance() * ZoomFactor); - - // Choose connection drawing method based on conditions - if (bIsAligned) + const float nodesDelta = abs(StartPoint.X - EndPoint.X); + + float OffsetValue = 0.f; + const UMounteaDialogueGraphEditorSettings* GraphSettings = GetDefault(); + if (GraphSettings == nullptr || GraphSettings->AllowAdvancedWiring() == false || nodesDelta <= GraphSettings->GetControlPointDistance()) { DrawConnection(WireLayerID, StartPoint, EndPoint, Params); } else { - DrawCurvedConnection(WireLayerID, StartPoint, EndPoint, Params); + OffsetValue = -3.f; + const FVector2D ConnectionEndPoint = FVector2D(EndPoint.X, EndPoint.Y + OffsetValue); + DrawCurvedConnection(WireLayerID, StartPoint, ConnectionEndPoint, Params); + } // Draw the arrow if (ArrowImage) { - const FVector2D ArrowDrawPos = EndPoint - ArrowRadius; - - const float AngleInRadians = FMath::DegreesToRadians(90.f); //FMath::Atan2(DeltaPos.Y, DeltaPos.X); + FVector2D ArrowDrawPos = EndPoint - ArrowRadius; + ArrowDrawPos.Y += OffsetValue; + const float AngleInRadians = FMath::DegreesToRadians(90.f); FSlateDrawElement::MakeRotatedBox( DrawElementsList, @@ -227,46 +205,24 @@ void FConnectionDrawingPolicy_MounteaDialogueGraph::Internal_DrawLineWithArrow(c } } -/* -void FConnectionDrawingPolicy_MounteaDialogueGraph::DrawConnectionDown(int32 LayerId, const FVector2D& Start, const FVector2D& End, const FConnectionParams& Params) -{ - // Constants for Bezier control points - FVector2D ControlPoint1 = FVector2D(Start.X, Start.Y + (End.Y - Start.Y) / 3); // Adjust to create a smooth curve - FVector2D ControlPoint2 = FVector2D(End.X, End.Y - (End.Y - Start.Y) / 3); - - FSlateDrawElement::MakeCubicBezierSpline( - DrawElementsList, - LayerId, - FPaintGeometry(), - Start, - ControlPoint1, - ControlPoint2, - End, - Params.WireThickness, - ESlateDrawEffect::None, - Params.WireColor - ); -} -*/ - void FConnectionDrawingPolicy_MounteaDialogueGraph::DrawCurvedConnection(int32 LayerId, const FVector2D& Start, const FVector2D& End, const FConnectionParams& Params) { const UMounteaDialogueGraphEditorSettings* GraphSettings = GetDefault(); - FVector2D LeaveTangent = GraphSettings->GetAdvancedWiringConnectionTangent().GetAbs(); - FVector2D ArriveTangent = GraphSettings->GetAdvancedWiringConnectionTangent().GetAbs(); - - const int32 SideValue = End.X >= 0 ? 1 : -1; + FVector2D Tangent = GraphSettings->GetAdvancedWiringConnectionTangent().GetAbs(); - LeaveTangent.X *= -SideValue; - ArriveTangent.X *= SideValue; + const int32 SideValue = (End.X > Start.X) ? 1 : -1; - LeaveTangent.Y *= SideValue; - ArriveTangent.Y *= -SideValue; + Tangent.X *= SideValue; + Tangent.Y *= 0.5f; + + FVector2D ControlPoint1 = Start + (Tangent * ZoomFactor); + FVector2D ControlPoint2 = End - (Tangent * ZoomFactor); + + ControlPoint1 = FMath::Lerp(Start, ControlPoint1, 0.6f); + ControlPoint2 = FMath::Lerp(End, ControlPoint2, 0.6f); - // Control points derived from the tangents - FVector2D ControlPoint1 = Start + (LeaveTangent * ZoomFactor); - FVector2D ControlPoint2 = End + (ArriveTangent * ZoomFactor); + const FVector2D connectionEnd = FVector2D(End.X, End.Y + 5.f); FSlateDrawElement::MakeCubicBezierSpline( DrawElementsList, @@ -275,7 +231,7 @@ void FConnectionDrawingPolicy_MounteaDialogueGraph::DrawCurvedConnection(int32 L Start, ControlPoint1, ControlPoint2, - End, + connectionEnd, Params.WireThickness, ESlateDrawEffect::None, Params.WireColor From 98f73d0048ea9f74abc570526165ba86ac9766e6 Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 20:24:01 +0200 Subject: [PATCH 12/14] Execution Order & Display Fix --- Content/Dialogues/D_TestDialogue.uasset | Bin 19326 -> 20036 bytes .../Ed/EdGraph_MounteaDialogueGraph.cpp | 39 +++++++++--------- .../Private/Ed/EdGraph_MounteaDialogueGraph.h | 6 ++- .../Ed/EdNode_MounteaDialogueGraphNode.cpp | 8 ++-- .../AssetGraphScheme_MounteaDialogueGraph.cpp | 1 - .../MounteaDialogueGraphEditorSettings.h | 2 +- 6 files changed, 29 insertions(+), 27 deletions(-) diff --git a/Content/Dialogues/D_TestDialogue.uasset b/Content/Dialogues/D_TestDialogue.uasset index edf64cf70c77c351dc4aa1ff4c38464eeca6b9ac..bca32b7e31fa8dddcd3b9eea5c6b6160a21483cd 100644 GIT binary patch literal 20036 zcmdU133wD$w!R5r3&@Tr4AAT#kgz3$MNB8%2?^Oq0zpwilN6z`(;d1yfeg=iEW#i= z0tzAlgCK^mC>WGQaDWe&0f{^WWkdmIcrc*Dj%(ietLyeuI#r!cB_El0{BBp(x#ymH zwtMcWTfvX!K2h+XtgLKe9mWFv8T%Jq0rjZOKJ$Wkn?CU$*GI<|^(@)@;W)x|K9leQS)rapxGe!#h1k0id-aqpi#FD{JzEi{mDPdR`6e3oHXtaRww zx9LW>hzaY?Ma3WNy0y5)i}`IbzwJf18&h_De>Gy&okm~xFVydk3hGI?_uDhpkFLS- zwp^=IFd57yi!CcxNXd6Nh3sJd=m<8XrwR@yf2I+PrBFNLC*HDGNRUo+J0vPHjM|Vv zbT#S?hN!_2#)z=6r~!JzfY2~~lt>NY&U9Du2xG12is!txVi#*d0-<%Fw$~K@!robf zMs6AV*~hb2e={mGt?8zd8()jxU9{qKlIh|-%nd#eq%QNL|4x)x{94dc@7`mKA-$6Y zi(qmHeM5r!i~Wq*&!(&N(;yKVzc(iWH_0@Avji88|B~;@V6ZSkw37N7(!JhdNw8%K z4p!FsN<~>RrlHHag*q!+-X4hqNQ^HOnI@@#u3FS1~tgP&2lYc_#N%~x;Ez*{q zLwF&DdNZ6tCit+s<4GBP8Ju-Po`8Jh*{ zTG$*!V;n-XDO<>~nDSFiSq`>vRm@>SmV7u7X3mEQ3r{?DfZ0t+3FTv@sprl#W%T0lobzS81V2i*wBSXvyg4Jv>l#+oV2V3x7YwVWi$<`~D0 zjbGp|Lp;swQ8xsb#U;-Nzpt}EqdjujUBt@o23s%8y&gj>lCEUDF^r(bQ z%z=H=N1E(;lnK(QcjeM)MJ+vgDT|=%%XR@~EN!rp2Bu9hIa6&08=E)ocx$MfIB6=y zy4w=^^SiGF0G;b(SL&8VAwZH$8PA)tgg9FUg2Ds=U_D2UDMMf_ocRmjnj{lNveTv0 znbfE)jew(w7wqXqYbJZ+?(c`7gM=!t1`BQR-4W>E(MxKuVN-X{fSgiSnqbMWWed#A zf}0_zIhw0=D&%4;9FlCaNy4;g9G!*;PPR>l)a=5Pxijn2b4tb(A=|{t_Ai=_cqq5# zgW2e}u$bgXmwS(vGH6C_WG}*39XXn zBP_W>j@@i^QljTe-Vtn^VM11N1VSc=<{W2mq|GjjaYYe(5Yu-A^yYm=YnGY9dVcu4 zm<}?u$C7nzbL>*XpHsV5MrF)2QzB&7dtOfLPPBT5LvV^2MRcc-?!nrXdKPVYdH7>Q z?KZHuwkVfoMp{e`2kW&ir!N9s-NNaS?EPyij$qlkhB&9sSOHBvcH};PUvv*)>1phv zmbYIObFC|lDvOzX^5z8{4K|7!k0Om2arq&4+asgI3r-VU%f6qrXJs!S%9juBAWBa$ z<%#J}?-1jb{pr^8^ZR=pAnt(4CTpfGo9`&JfS7e%&Z#H74xDbvp;X{BXP9$L6v=Gq zos*|qR~+GTOiJp-<8Zl$;9@6KP1jo;(*?VzbZCi1=c7suKz-uV7IF+2#GatDb=N}tRTy`Z(2vRvuZ?Y;GV z-V}xt9Uxr%rK*&Q9KCc8H8>2DZp7+{?tdVu^Bf3{Z*} zIo%K!S*3J*j>`Bw=_9`p3Us7inS^G@cpfdiqWc>Y!2Ykx;XGw$a)G&WkV6e{&Oh_*BH6|LkDZ;|GO-|flIQ)3QJcn-M_*&6nchB^&{F{uwj;Kab!+6Ng z&2m=8pU~w%K9>^zUuFD}hEW4~@^3t}9LsVKmGS>Y#vjK`sGU6d>uZSrA5{3~RfGS} zGWnr+Bz_36$263b-&P5KZX+f8|0Ls&b%k1x?_UYhz&*UspgvFFyn*+XKi|JNe}7(} zcrvGFE&NfNAwEBm1}E{triS?Q^~>ddJY0dXgsMz_oQU($us>>S9Fjo(ebV48Jw2#^ z7XILk)=e7Ri3gR!99sBu`)`y6NAUt#1ONLT_QAV_XMFyH7xXp6pT{SUpF#XZuZH+@ z`y@;D`E8^EV+mE6{gv#)Ef>QUos4L*V05L=){44_WM7?jt1EXH-D z1|HyrXVBvrhvIm~J$R$(q$}`zF7O5oj%9%Z9p(qF4K>&nILHDVUa!y(TF3}lu$SSU zkHg-{*9Dgw`w`{>FN|qNjmwJXPSill=fV3ObV48IRRYk%9-xICptFt|bb;)U6|zAd z%m*1T59$%{yh*;$(G_&acXAxY00&!v4)b6R;QXj@THtilnO7XZ)@5azlt zPAsy9nX9_2;R=AKQj8&h0K6vW$|yNaBy8KX?W@zfjW+CX2JV};Xy+lha#(!;F0WfT z5FtDP2sePc^DRddK4|^b ziOmxV*P;tLa6RxW2URn}#ApCTGwZ}Ih0ZNnd=QnB-*)oAR*6gh*Od2Y^7$olWB5xm z!OK%uzrX$K@9KpweRG6k@p$6|B^(k82hl*>2Vx3BkDNQF6tAis<*3R(RPe#dFAfhc zJ6q3Cbaw7rOD67^3UY5gKtJ>tx43Ij9bs(TzRO>pzv#bEr-ZAG_~Q0QGS{VEpEP6W z`Pl7_&hIT}<0nIQB&iYKKK4wfeH)|pJ+h`}+lk9>0Pjs_)wshlQH{H{#8L;=1Qmkv z1(LJMYyZSkbJiR_P&TUYoh8oK9&CP69su6-RhU)^`#ptyNku6EpAIP4SP z5nDBu@8DF`c*IOPYJdv)t~aguD#v4LXzHn7+P^vSmD_*&vj3vMI!f`VWDg}=ZN{Tg z48cm?asv9H$4X(@qfJYDM$c~6-g@g?ovTW?+K5M<@9<*!bn_=anL4u|V$V0vj=a|8 zS~g_&rkiTML)fUsm)HGNQ+#c06I!qCzd~Y`1@`_px#jT%O7YczMDko$O1S@z@dZ78 zum5b$%DS;}vrmmJ?7n&9PfEC+M8}~FH@rrD2=56vv^aPAjrh;4O=I8qu;6c#Z~i2{ ze`<;^WFXb}@|wT=X-}zg{t9or)p2f`LBBo2I^^-_F@IHxFQxUPgsaW?Qp!0918+V+ zKlB(;c&z!xzdRkaqfh5C4nt_360SDm3&C_KVa}!>S1lPeZ>IikqqMYRklmYZs`(2i zOgfAvsIUcor6q*e@E+%1x^gLIzh6=O&aj9yc?dy7fRYMIxY`UMCAUL%O=iYHo9Z(5 zx=mx_RPia~b2vasAAg*T)}e8Tsn{jejnEaK8|;d(%yI8RKwQHNM)D%XMH) zP+^U0DnoWIF`14WXlLBH?1dwn-flfm9$%0j09ifDcqLqI#+Q~dSJekNeAng!O-Cz3 zr)@H4`)7r(ioCVvQirj(m3*LdbfkoH5$f(|_d6*@mBWR*+S?mv`fr)Crw zXB*!c6*FmrzuX7@;ykX8FrG*EO2_%N=>w(D9S|S+6ip4Fhv$*F60SD)I;?TePYck; zn{IMHa@ty{RY@C)bQ!y z9hc${c4;uzaw1?;h%~T=bcJU`fVulg_dMLV#W=C(FS%bhq2kw15b|7r&kj0jSYTN8 zSmjC|;}N(3KBHSae?rPt;n8DDC%rzU`qu1CVgRaXP3@T&K2S9hLaNF}s^7lvo&na+B6pA7H(|Q9 zUthi>R16dz;ty#Z;4h50$M}^{8rMM$c}{ztLM^B2IT*dlp1aW`G4bOAF@{}vK}$ZG z6maf8#z;ESMq3U*1gjbev0r5)>EBJ7Hu|5>8|NN8v3yLy=)Dg)h*2VQzwj%eGzKx> zRH~VNQ1|+j%u%vxb0j2GbtHDODmyYe>Gr#$&kfVh&IyPz&%C&%`qu19VgRaXO%%jF zS+f%nYO^K`rfN+jmMUBGu`jzP|Lh+YzO;36@Gl)lBtGP20W)w1@++YEKl zqEz#Ar03b5_y^i}e}uubIn$p;syY*$Rd(j4?HkwGiwDOp4ruYk**Y60SKp%DNen~l14bKZbrX!?JCk@(Pd9jRCy@Spw zd*_2s>wRDrh8v1k-(Fn2KJ$O%Ch`n9{>(KOU)ZqPwS^iDR96O_RaWM?m)i_%Fk*gU w@r64>ts8WY%9Z(u{(o?<-rGDYXxPzGxR^7?M1Z^tVWR^+J=BXImx2EO0Ezce*#H0l literal 19326 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 W&$-bNXwHR*iM}5l8pw`xApc)>M;K)Q diff --git a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp index a51019ba..954ff4a9 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.cpp @@ -11,6 +11,7 @@ #include "Helpers/MounteaDialogueGraphEditorHelpers.h" #include "Helpers/MounteaDialogueGraphEditorUtilities.h" #include "Helpers/MounteaDialogueSystemEditorBFC.h" +#include "Nodes/MounteaDialogueGraphNode_StartNode.h" UEdGraph_MounteaDialogueGraph::UEdGraph_MounteaDialogueGraph() { @@ -146,11 +147,13 @@ bool UEdGraph_MounteaDialogueGraph::Modify(bool bAlwaysMarkDirty) { bool Rtn = Super::Modify(bAlwaysMarkDirty); + ResetExecutionOrders(); + AssignExecutionOrder(); + for (int32 i = 0; i < Nodes.Num(); ++i) { Nodes[i]->Modify(); } - return Rtn; } @@ -257,14 +260,12 @@ void UEdGraph_MounteaDialogueGraph::AssignExecutionOrder() if (!Graph) return; TMap> LayeredNodes; - int32 CurrentExecutionOrder = 0; - - for (UMounteaDialogueGraphNode* RootNode : Graph->RootNodes) + int32 CurrentExecutionOrder = 1; + + if (UMounteaDialogueGraphNode* RootNode = Graph->GetStartNode()) { - if (RootNode) - { - AssignNodeToLayer(RootNode, 0, LayeredNodes); - } + RootNode->ExecutionOrder = 0; + AssignNodeToLayer(RootNode, 0, LayeredNodes); } for (int32 LayerIndex = 0; LayeredNodes.Contains(LayerIndex); ++LayerIndex) @@ -277,7 +278,8 @@ void UEdGraph_MounteaDialogueGraph::AssignExecutionOrder() UMounteaDialogueGraphNode* ParentA = GetParentNode(A); UMounteaDialogueGraphNode* ParentB = GetParentNode(B); - + + if (!ParentA && !ParentB) return EdNode_A->NodePosX < EdNode_B->NodePosX; if (ParentA && !ParentB) return true; if (!ParentA && ParentB) return false; @@ -289,23 +291,22 @@ void UEdGraph_MounteaDialogueGraph::AssignExecutionOrder() } } - // If we reach here, either both nodes have no parents or have parents with the same execution order + // If we reach here, either both nodes have parents with the same execution order // In this case, sort based on X position return EdNode_A->NodePosX < EdNode_B->NodePosX; }); for (UMounteaDialogueGraphNode* Node : NodesInLayer) { - if (Node) + if (!Node) continue; + if (Node->IsA(UMounteaDialogueGraphNode_StartNode::StaticClass())) continue; + if (GetParentNode(*Node)) { - if (UMounteaDialogueGraphNode* ParentNode = GetParentNode(*Node)) - { - Node->ExecutionOrder = CurrentExecutionOrder++; - } - else - { - Node->ExecutionOrder = INDEX_NONE; - } + Node->ExecutionOrder = CurrentExecutionOrder++; + } + else + { + Node->ExecutionOrder = INDEX_NONE; } } } diff --git a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h index e3d85b5a..f89b9b1f 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h +++ b/Source/MounteaDialogueSystemEditor/Private/Ed/EdGraph_MounteaDialogueGraph.h @@ -48,6 +48,10 @@ class MOUNTEADIALOGUESYSTEMEDITOR_API UEdGraph_MounteaDialogueGraph : public UEd UPROPERTY(Transient) TMap EdgeMap; +public: + + void AssignExecutionOrder(); + protected: void Clear(); @@ -55,7 +59,7 @@ class MOUNTEADIALOGUESYSTEMEDITOR_API UEdGraph_MounteaDialogueGraph : public UEd void ResetExecutionOrders() const; static UMounteaDialogueGraphNode* GetParentNode(const UMounteaDialogueGraphNode& Node); - void AssignExecutionOrder(); + static void AssignNodeToLayer(UMounteaDialogueGraphNode* Node, int32 LayerIndex, TMap>& LayeredNodes); private: diff --git a/Source/MounteaDialogueSystemEditor/Private/Ed/EdNode_MounteaDialogueGraphNode.cpp b/Source/MounteaDialogueSystemEditor/Private/Ed/EdNode_MounteaDialogueGraphNode.cpp index 251d5ef2..65741439 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Ed/EdNode_MounteaDialogueGraphNode.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/Ed/EdNode_MounteaDialogueGraphNode.cpp @@ -36,6 +36,9 @@ void UEdNode_MounteaDialogueGraphNode::SetMounteaDialogueGraphNode(UMounteaDialo bAllowDuplicate = DialogueGraphNode->bAllowPaste; bAllowPaste = DialogueGraphNode->bAllowPaste; } + + if (GetDialogueGraphEdGraph()) + GetDialogueGraphEdGraph()->AssignExecutionOrder(); } UEdGraph_MounteaDialogueGraph* UEdNode_MounteaDialogueGraphNode::GetDialogueGraphEdGraph() const @@ -187,11 +190,6 @@ void UEdNode_MounteaDialogueGraphNode::UpdatePosition() DialogueGraphNode->NodePosition = FIntPoint(NodePosX, NodePosY); DialogueGraphNode->Modify(true); } - - if (auto graphEditor = GetDialogueGraphEdGraph()) - { - - } } void UEdNode_MounteaDialogueGraphNode::PostEditUndo() diff --git a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp index 38a8c705..4caa93f7 100644 --- a/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp +++ b/Source/MounteaDialogueSystemEditor/Private/GraphScheme/AssetGraphScheme_MounteaDialogueGraph.cpp @@ -118,7 +118,6 @@ UEdGraphNode* FAssetSchemaAction_MounteaDialogueGraph_NewNode::PerformAction(UEd ResultNode = NodeTemplate; } - return ResultNode; } diff --git a/Source/MounteaDialogueSystemEditor/Private/Settings/MounteaDialogueGraphEditorSettings.h b/Source/MounteaDialogueSystemEditor/Private/Settings/MounteaDialogueGraphEditorSettings.h index f2120d48..363c60e1 100644 --- a/Source/MounteaDialogueSystemEditor/Private/Settings/MounteaDialogueGraphEditorSettings.h +++ b/Source/MounteaDialogueSystemEditor/Private/Settings/MounteaDialogueGraphEditorSettings.h @@ -151,7 +151,7 @@ class MOUNTEADIALOGUESYSTEMEDITOR_API UMounteaDialogueGraphEditorSettings : publ bool bUseAdvancedWiring; UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "NodeWiring", meta=(ToolTip="[BETA] Feature]", EditCondition="bUseAdvancedWiring")) - FVector2D AdvancedWiringConnectionTangent = FVector2D(0.0f, 100.f); + FVector2D AdvancedWiringConnectionTangent = FVector2D(0.0f, 350.f); UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "NodeWiring", meta=(ToolTip="[BETA] Feature]", EditCondition="bUseAdvancedWiring")) float ControlPointDistance = 100.0f; From 3f2c4cfb971921744e6edea8f46f50ebbf8389d1 Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 20:48:38 +0200 Subject: [PATCH 13/14] 5.2 update --- MounteaDialogueSystem.uplugin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MounteaDialogueSystem.uplugin b/MounteaDialogueSystem.uplugin index acc75eaa..2d6763d0 100644 --- a/MounteaDialogueSystem.uplugin +++ b/MounteaDialogueSystem.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, "Version": 2, - "VersionName": "2.0.3.52", + "VersionName": "2.0.4.52", "FriendlyName": "Mountea Dialogue System", "Description": "Mountea Dialogue System is an Open-source Mountea Framework tool for Unreal Engine for creating (not just) complex dialogues!\nProvides its own Dialogue Tree editor and validation system.", "Category": "Mountea Framework", From ae52c41000d232df559012a7a42ee725c302fb01 Mon Sep 17 00:00:00 2001 From: Dominik Morse Date: Sat, 12 Oct 2024 20:57:32 +0200 Subject: [PATCH 14/14] 5.3 update --- MounteaDialogueSystem.uplugin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MounteaDialogueSystem.uplugin b/MounteaDialogueSystem.uplugin index 91b79144..e4b26883 100644 --- a/MounteaDialogueSystem.uplugin +++ b/MounteaDialogueSystem.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, "Version": 2, - "VersionName": "2.0.3.53", + "VersionName": "2.0.4.53", "FriendlyName": "Mountea Dialogue System", "Description": "Mountea Dialogue System is an Open-source Mountea Framework tool for Unreal Engine for creating (not just) complex dialogues!\nProvides its own Dialogue Tree editor and validation system.", "Category": "Mountea Framework",