From c682f72afa6869c63972d3ed027078bcdde23462 Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Mon, 20 Nov 2023 21:25:36 +0000 Subject: [PATCH 01/99] Add Generic Graph Plugin for Creating Custom Graph --- .../Plugins/GenericGraph/.gitignore | 14 + .../Plugins/GenericGraph/GenericGraph.uplugin | 30 + EndlessVendetta/Plugins/GenericGraph/LICENSE | 21 + .../Resources/AutoArrangeIcon.png | 3 + .../GenericGraph/Resources/Icon128.png | 3 + .../GenericGraphEditor.Build.cs | 62 ++ .../Private/AssetTypeActions_GenericGraph.cpp | 48 + .../Private/AutoLayout/AutoLayoutStrategy.cpp | 96 ++ .../ForceDirectedLayoutStrategy.cpp | 162 ++++ .../Private/AutoLayout/TreeLayoutStrategy.cpp | 241 ++++++ .../AssetEditorToolbar_GenericGraph.cpp | 46 + .../AssetEditor_GenericGraph.cpp | 819 ++++++++++++++++++ .../AssetGraphSchema_GenericGraph.cpp | 476 ++++++++++ .../ConnectionDrawingPolicy_GenericGraph.cpp | 149 ++++ .../EdGraph_GenericGraph.cpp | 205 +++++ .../EdNode_GenericGraphEdge.cpp | 97 +++ .../EdNode_GenericGraphNode.cpp | 84 ++ .../EditorCommands_GenericGraph.cpp | 11 + .../GenericGraphDragConnection.cpp | 325 +++++++ .../GenericGraphEditorStyle.cpp | 54 ++ .../SEdNode_GenericGraphEdge.cpp | 199 +++++ .../SEdNode_GenericGraphNode.cpp | 336 +++++++ .../Settings_GenericGraphEditor.cpp | 24 + .../Private/GenericGraphEditor.cpp | 55 ++ .../Private/GenericGraphFactory.cpp | 117 +++ .../Private/GenericGraphNodeFactory.cpp | 20 + .../Public/AssetTypeActions_GenericGraph.h | 19 + .../Public/AutoLayout/AutoLayoutStrategy.h | 40 + .../AutoLayout/ForceDirectedLayoutStrategy.h | 24 + .../Public/AutoLayout/TreeLayoutStrategy.h | 29 + .../AssetEditorToolbar_GenericGraph.h | 24 + .../AssetEditor_GenericGraph.h | 137 +++ .../AssetGraphSchema_GenericGraph.h | 90 ++ .../Colors_GenericGraph.h | 45 + .../ConnectionDrawingPolicy_GenericGraph.h | 27 + .../EdGraph_GenericGraph.h | 39 + .../EdNode_GenericGraphEdge.h | 42 + .../EdNode_GenericGraphNode.h | 42 + .../EditorCommands_GenericGraph.h | 18 + .../GenericGraphDragConnection.h | 52 ++ .../GenericGraphEditorStyle.h | 16 + .../SEdNode_GenericGraphEdge.h | 40 + .../SEdNode_GenericGraphNode.h | 32 + .../Settings_GenericGraphEditor.h | 42 + .../Public/GenericGraphEditor.h | 23 + .../Public/GenericGraphEditorModule.h | 34 + .../Public/GenericGraphEditorPCH.h | 13 + .../Public/GenericGraphFactory.h | 22 + .../Public/GenericGraphNodeFactory.h | 8 + .../GenericGraphRuntime.Build.cs | 51 ++ .../Private/GenericGraph.cpp | 136 +++ .../Private/GenericGraphEdge.cpp | 23 + .../Private/GenericGraphNode.cpp | 90 ++ .../Private/GenericGraphRuntime.cpp | 29 + .../Private/GenericGraphRuntimePCH.h | 12 + .../GenericGraphRuntime/Public/GenericGraph.h | 60 ++ .../Public/GenericGraphEdge.h | 48 + .../Public/GenericGraphNode.h | 94 ++ .../Public/IGenericGraphRuntime.h | 36 + .../GenericGraph/docs/images/GenericGraph.png | 3 + .../docs/images/ability-graph.png | 3 + .../docs/images/dialogue/dialogue01.png | 3 + .../docs/images/dialogue/dialogue02.png | 3 + .../docs/images/dialogue/dialogue03.png | 3 + .../Plugins/GenericGraph/readme.rst | 51 ++ 65 files changed, 5200 insertions(+) create mode 100644 EndlessVendetta/Plugins/GenericGraph/.gitignore create mode 100644 EndlessVendetta/Plugins/GenericGraph/GenericGraph.uplugin create mode 100644 EndlessVendetta/Plugins/GenericGraph/LICENSE create mode 100644 EndlessVendetta/Plugins/GenericGraph/Resources/AutoArrangeIcon.png create mode 100644 EndlessVendetta/Plugins/GenericGraph/Resources/Icon128.png create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/GenericGraphEditor.Build.cs create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AssetTypeActions_GenericGraph.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/AutoLayoutStrategy.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/ForceDirectedLayoutStrategy.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/TreeLayoutStrategy.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetEditorToolbar_GenericGraph.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetEditor_GenericGraph.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetGraphSchema_GenericGraph.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/ConnectionDrawingPolicy_GenericGraph.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdGraph_GenericGraph.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdNode_GenericGraphEdge.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdNode_GenericGraphNode.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EditorCommands_GenericGraph.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/GenericGraphDragConnection.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/GenericGraphEditorStyle.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/SEdNode_GenericGraphEdge.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/SEdNode_GenericGraphNode.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/Settings_GenericGraphEditor.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphEditor.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphFactory.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphNodeFactory.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AssetTypeActions_GenericGraph.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/AutoLayoutStrategy.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/ForceDirectedLayoutStrategy.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/TreeLayoutStrategy.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetEditorToolbar_GenericGraph.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetEditor_GenericGraph.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetGraphSchema_GenericGraph.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/Colors_GenericGraph.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/ConnectionDrawingPolicy_GenericGraph.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdGraph_GenericGraph.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdNode_GenericGraphEdge.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdNode_GenericGraphNode.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EditorCommands_GenericGraph.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/GenericGraphDragConnection.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/GenericGraphEditorStyle.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/SEdNode_GenericGraphEdge.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/SEdNode_GenericGraphNode.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/Settings_GenericGraphEditor.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditor.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditorModule.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditorPCH.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphFactory.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphNodeFactory.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/GenericGraphRuntime.Build.cs create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraph.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphEdge.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphNode.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphRuntime.cpp create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphRuntimePCH.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraph.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraphEdge.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraphNode.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/IGenericGraphRuntime.h create mode 100644 EndlessVendetta/Plugins/GenericGraph/docs/images/GenericGraph.png create mode 100644 EndlessVendetta/Plugins/GenericGraph/docs/images/ability-graph.png create mode 100644 EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue01.png create mode 100644 EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue02.png create mode 100644 EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue03.png create mode 100644 EndlessVendetta/Plugins/GenericGraph/readme.rst diff --git a/EndlessVendetta/Plugins/GenericGraph/.gitignore b/EndlessVendetta/Plugins/GenericGraph/.gitignore new file mode 100644 index 00000000..7b887157 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/.gitignore @@ -0,0 +1,14 @@ +Binaries +DerivedDataCache +Intermediate +Saved +Build +*.sdf +*.sln +*.suo +*.opensdf +*.opendb +*.db +/docs/sphinx-build-result +/.vs +NoCommit \ No newline at end of file diff --git a/EndlessVendetta/Plugins/GenericGraph/GenericGraph.uplugin b/EndlessVendetta/Plugins/GenericGraph/GenericGraph.uplugin new file mode 100644 index 00000000..68e4ef88 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/GenericGraph.uplugin @@ -0,0 +1,30 @@ +{ + "FileVersion" : 3, + "Version" : 1, + "VersionName" : "1.0", + "FriendlyName" : "Generic Graph Plugin", + "Description" : "", + "Category" : "GenericGraph", + "CreatedBy" : "jinyuliao", + "CreatedByURL" : "", + "DocsURL" : "", + "MarketplaceURL" : "", + "SupportURL" : "", + "EnabledByDefault" : true, + "CanContainContent" : true, + "IsBetaVersion" : false, + "Installed" : false, + "Modules" : + [ + { + "Name" : "GenericGraphRuntime", + "Type" : "Runtime", + "LoadingPhase" : "PreDefault" + }, + { + "Name" : "GenericGraphEditor", + "Type" : "Editor", + "LoadingPhase" : "Default" + } + ] +} \ No newline at end of file diff --git a/EndlessVendetta/Plugins/GenericGraph/LICENSE b/EndlessVendetta/Plugins/GenericGraph/LICENSE new file mode 100644 index 00000000..9c189b15 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 jinyuliao + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/EndlessVendetta/Plugins/GenericGraph/Resources/AutoArrangeIcon.png b/EndlessVendetta/Plugins/GenericGraph/Resources/AutoArrangeIcon.png new file mode 100644 index 00000000..b5e6c3b1 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Resources/AutoArrangeIcon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71dff338a731ee7bf2def0d378b0a866615d2ee72aa591ab4ed7ad1105049806 +size 5528 diff --git a/EndlessVendetta/Plugins/GenericGraph/Resources/Icon128.png b/EndlessVendetta/Plugins/GenericGraph/Resources/Icon128.png new file mode 100644 index 00000000..57ee2a55 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Resources/Icon128.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9eb6f69963ee569b0a8a4446e21f69d0a93205caf07b30cc37b1fddb62599602 +size 15543 diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/GenericGraphEditor.Build.cs b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/GenericGraphEditor.Build.cs new file mode 100644 index 00000000..aa57f0ce --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/GenericGraphEditor.Build.cs @@ -0,0 +1,62 @@ +using UnrealBuildTool; + +public class GenericGraphEditor : ModuleRules +{ + public GenericGraphEditor(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + bLegacyPublicIncludePaths = false; + ShadowVariableWarningLevel = WarningLevel.Error; + + PublicIncludePaths.AddRange( + new string[] { + // ... add public include paths required here ... + } + ); + + PrivateIncludePaths.AddRange( + new string[] { + // ... add other private include paths required here ... + "GenericGraphEditor/Private", + "GenericGraphEditor/Public", + } + ); + + PublicDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + "UnrealEd", + // ... add other public dependencies that you statically link with here ... + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "GenericGraphRuntime", + "AssetTools", + "Slate", + "InputCore", + "SlateCore", + "GraphEditor", + "PropertyEditor", + "EditorStyle", + "Kismet", + "KismetWidgets", + "ApplicationCore", + "ToolMenus", + // ... add private dependencies that you statically link with here ... + } + ); + + DynamicallyLoadedModuleNames.AddRange( + new string[] + { + // ... add any modules that your module loads dynamically here ... + } + ); + } +} diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AssetTypeActions_GenericGraph.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AssetTypeActions_GenericGraph.cpp new file mode 100644 index 00000000..643911c7 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AssetTypeActions_GenericGraph.cpp @@ -0,0 +1,48 @@ +#include "AssetTypeActions_GenericGraph.h" +#include "GenericGraphEditorPCH.h" +#include "GenericGraphAssetEditor/AssetEditor_GenericGraph.h" + +#define LOCTEXT_NAMESPACE "AssetTypeActions_GenericGraph" + +FAssetTypeActions_GenericGraph::FAssetTypeActions_GenericGraph(EAssetTypeCategories::Type InAssetCategory) + : MyAssetCategory(InAssetCategory) +{ +} + +FText FAssetTypeActions_GenericGraph::GetName() const +{ + return LOCTEXT("FGenericGraphAssetTypeActionsName", "Generic Graph"); +} + +FColor FAssetTypeActions_GenericGraph::GetTypeColor() const +{ + return FColor(129, 196, 115); +} + +UClass* FAssetTypeActions_GenericGraph::GetSupportedClass() const +{ + return UGenericGraph::StaticClass(); +} + +void FAssetTypeActions_GenericGraph::OpenAssetEditor(const TArray& InObjects, TSharedPtr EditWithinLevelEditor) +{ + const EToolkitMode::Type Mode = EditWithinLevelEditor.IsValid() ? EToolkitMode::WorldCentric : EToolkitMode::Standalone; + + for (auto ObjIt = InObjects.CreateConstIterator(); ObjIt; ++ObjIt) + { + if (UGenericGraph* Graph = Cast(*ObjIt)) + { + TSharedRef NewGraphEditor(new FAssetEditor_GenericGraph()); + NewGraphEditor->InitGenericGraphAssetEditor(Mode, EditWithinLevelEditor, Graph); + } + } +} + +uint32 FAssetTypeActions_GenericGraph::GetCategories() +{ + return MyAssetCategory; +} + +////////////////////////////////////////////////////////////////////////// + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/AutoLayoutStrategy.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/AutoLayoutStrategy.cpp new file mode 100644 index 00000000..4d03bd87 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/AutoLayoutStrategy.cpp @@ -0,0 +1,96 @@ +#include "AutoLayout/AutoLayoutStrategy.h" +#include "Kismet/KismetMathLibrary.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphNode.h" +#include "GenericGraphAssetEditor/SEdNode_GenericGraphNode.h" + +UAutoLayoutStrategy::UAutoLayoutStrategy() +{ + Settings = nullptr; + MaxIteration = 50; + OptimalDistance = 150; +} + +UAutoLayoutStrategy::~UAutoLayoutStrategy() +{ + +} + +FBox2D UAutoLayoutStrategy::GetNodeBound(UEdGraphNode* EdNode) +{ + int32 NodeWidth = GetNodeWidth(Cast(EdNode)); + int32 NodeHeight = GetNodeHeight(Cast(EdNode)); + FVector2D Min(EdNode->NodePosX, EdNode->NodePosY); + FVector2D Max(EdNode->NodePosX + NodeWidth, EdNode->NodePosY + NodeHeight); + return FBox2D(Min, Max); +} + +FBox2D UAutoLayoutStrategy::GetActualBounds(UGenericGraphNode* RootNode) +{ + int Level = 0; + TArray CurrLevelNodes = { RootNode }; + TArray NextLevelNodes; + + FBox2D Rtn = GetNodeBound(EdGraph->NodeMap[RootNode]); + + while (CurrLevelNodes.Num() != 0) + { + for (int i = 0; i < CurrLevelNodes.Num(); ++i) + { + UGenericGraphNode* Node = CurrLevelNodes[i]; + check(Node != nullptr); + + Rtn += GetNodeBound(EdGraph->NodeMap[Node]); + + for (int j = 0; j < Node->ChildrenNodes.Num(); ++j) + { + NextLevelNodes.Add(Node->ChildrenNodes[j]); + } + } + + CurrLevelNodes = NextLevelNodes; + NextLevelNodes.Reset(); + ++Level; + } + return Rtn; +} + +void UAutoLayoutStrategy::RandomLayoutOneTree(UGenericGraphNode* RootNode, const FBox2D& Bound) +{ + int Level = 0; + TArray CurrLevelNodes = { RootNode }; + TArray NextLevelNodes; + + while (CurrLevelNodes.Num() != 0) + { + for (int i = 0; i < CurrLevelNodes.Num(); ++i) + { + UGenericGraphNode* Node = CurrLevelNodes[i]; + check(Node != nullptr); + + UEdNode_GenericGraphNode* EdNode_Node = EdGraph->NodeMap[Node]; + + EdNode_Node->NodePosX = UKismetMathLibrary::RandomFloatInRange(Bound.Min.X, Bound.Max.X); + EdNode_Node->NodePosY = UKismetMathLibrary::RandomFloatInRange(Bound.Min.Y, Bound.Max.Y); + + for (int j = 0; j < Node->ChildrenNodes.Num(); ++j) + { + NextLevelNodes.Add(Node->ChildrenNodes[j]); + } + } + + CurrLevelNodes = NextLevelNodes; + NextLevelNodes.Reset(); + ++Level; + } +} + +int32 UAutoLayoutStrategy::GetNodeWidth(UEdNode_GenericGraphNode* EdNode) +{ + return EdNode->SEdNode->GetCachedGeometry().GetLocalSize().X; +} + +int32 UAutoLayoutStrategy::GetNodeHeight(UEdNode_GenericGraphNode* EdNode) +{ + return EdNode->SEdNode->GetCachedGeometry().GetLocalSize().Y; +} + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/ForceDirectedLayoutStrategy.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/ForceDirectedLayoutStrategy.cpp new file mode 100644 index 00000000..8d66bfcb --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/ForceDirectedLayoutStrategy.cpp @@ -0,0 +1,162 @@ +#include "AutoLayout/ForceDirectedLayoutStrategy.h" + +static inline float CoolDown(float Temp, float CoolDownRate) +{ + if (Temp < .01) return .01; + return Temp - (Temp / CoolDownRate); +} + +static inline float GetAttractForce(float X, float K) +{ + return (X * X) / K; +} + +static inline float GetRepulseForce(float X, float k) +{ + return X != 0 ? k * k / X : TNumericLimits::Max(); +} + +UForceDirectedLayoutStrategy::UForceDirectedLayoutStrategy() +{ + bRandomInit = false; + CoolDownRate = 10; + InitTemperature = 10.f; +} + +UForceDirectedLayoutStrategy::~UForceDirectedLayoutStrategy() +{ + +} + +void UForceDirectedLayoutStrategy::Layout(UEdGraph* _EdGraph) +{ + EdGraph = Cast(_EdGraph); + check(EdGraph != nullptr); + + EdGraph->RebuildGenericGraph(); + Graph = EdGraph->GetGenericGraph(); + check(Graph != nullptr); + + if (Settings != nullptr) + { + OptimalDistance = Settings->OptimalDistance; + MaxIteration = Settings->MaxIteration; + bRandomInit = Settings->bRandomInit; + } + + FBox2D PreTreeBound(ForceInitToZero); + for (int32 i = 0; i < Graph->RootNodes.Num(); ++i) + { + PreTreeBound = LayoutOneTree(Graph->RootNodes[i], PreTreeBound); + } +} + +FBox2D UForceDirectedLayoutStrategy::LayoutOneTree(UGenericGraphNode* RootNode, const FBox2D& PreTreeBound) +{ + float Temp = InitTemperature; + FBox2D TreeBound = GetActualBounds(RootNode); + TreeBound.Min.X += PreTreeBound.Max.X + OptimalDistance; + TreeBound.Max.X += PreTreeBound.Max.X + OptimalDistance; + + if (bRandomInit) + { + RandomLayoutOneTree(RootNode, TreeBound); + } + + float RepulseForce, AttractForce, Distance; + FVector2D Diff; + + TMap NodeToDisplacement; + + for (int32 i = 0; i < EdGraph->Nodes.Num(); ++i) + { + NodeToDisplacement.Add(EdGraph->Nodes[i], FVector2D(0.f, 0.f)); + } + + for (int32 IterrationNum = 0; IterrationNum < MaxIteration; ++IterrationNum) + { + // Calculate the repulsive forces. + for (int32 i = 0; i < EdGraph->Nodes.Num(); ++i) + { + for (int32 j = 0; j < EdGraph->Nodes.Num(); ++j) + { + if (i == j) + continue; + Diff.X = EdGraph->Nodes[i]->NodePosX - EdGraph->Nodes[j]->NodePosX; + Diff.Y = EdGraph->Nodes[i]->NodePosY - EdGraph->Nodes[j]->NodePosY; + Distance = Diff.Size(); + Diff.Normalize(); + + RepulseForce = Distance > 2 * OptimalDistance ? 0 : GetRepulseForce(Distance, OptimalDistance); + + NodeToDisplacement[EdGraph->Nodes[i]] += Diff * RepulseForce; + } + } + + // Calculate the attractive forces. + int Level = 0; + TArray CurrLevelNodes = { RootNode }; + TArray NextLevelNodes; + + while (CurrLevelNodes.Num() != 0) + { + for (int32 i = 0; i < CurrLevelNodes.Num(); ++i) + { + UGenericGraphNode* Node = CurrLevelNodes[i]; + check(Node != nullptr); + + UEdNode_GenericGraphNode* EdNode_ParentNode = EdGraph->NodeMap[Node]; + + for (int32 j = 0; j < Node->ChildrenNodes.Num(); ++j) + { + NextLevelNodes.Add(Node->ChildrenNodes[j]); + + UEdNode_GenericGraphNode* EdNode_ChildNode = EdGraph->NodeMap[Node->ChildrenNodes[j]]; + + Diff.X = EdNode_ChildNode->NodePosX - EdNode_ParentNode->NodePosY; + Diff.Y = EdNode_ChildNode->NodePosY - EdNode_ParentNode->NodePosY; + Distance = Diff.Size(); + Diff.Normalize(); + + AttractForce = GetAttractForce(Distance, OptimalDistance); + + NodeToDisplacement[EdNode_ParentNode] += Distance * Diff; + NodeToDisplacement[EdNode_ChildNode] -= Distance * Diff; + } + } + + CurrLevelNodes = NextLevelNodes; + NextLevelNodes.Reset(); + ++Level; + } + + for (int32 i = 0; i < EdGraph->Nodes.Num(); ++i) + { + UEdGraphNode* EdNode = EdGraph->Nodes[i]; + Distance = NodeToDisplacement[EdNode].Size(); + NodeToDisplacement[EdNode].Normalize(); + + float Minimum = Distance < Temp ? Distance : Temp; + EdNode->NodePosX += NodeToDisplacement[EdNode].X * Minimum; + EdNode->NodePosY += NodeToDisplacement[EdNode].Y * Minimum; + } + + Temp = CoolDown(Temp, CoolDownRate); + } + + FBox2D ActualBound = GetActualBounds(RootNode); + + FVector2D Center = ActualBound.GetCenter(); + FVector2D TreeCenter = TreeBound.GetCenter(); + + FVector2D Scale = (TreeBound.Max - TreeBound.Min) / (ActualBound.Max - ActualBound.Min); + + for (int32 i = 0; i < EdGraph->Nodes.Num(); ++i) + { + UEdGraphNode* EdNode = EdGraph->Nodes[i]; + EdNode->NodePosX = TreeCenter.X + Scale.X * (EdNode->NodePosX - Center.X); + EdNode->NodePosY = TreeCenter.Y + Scale.Y * (EdNode->NodePosY - Center.Y); + } + + return TreeBound; +} diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/TreeLayoutStrategy.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/TreeLayoutStrategy.cpp new file mode 100644 index 00000000..93163208 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/AutoLayout/TreeLayoutStrategy.cpp @@ -0,0 +1,241 @@ +#include "AutoLayout/TreeLayoutStrategy.h" +#include "GenericGraphEditorPCH.h" +#include "GenericGraphAssetEditor/SEdNode_GenericGraphNode.h" + +UTreeLayoutStrategy::UTreeLayoutStrategy() +{ +} + +UTreeLayoutStrategy::~UTreeLayoutStrategy() +{ + +} + +void UTreeLayoutStrategy::Layout(UEdGraph* _EdGraph) +{ + EdGraph = Cast(_EdGraph); + check(EdGraph != nullptr); + + EdGraph->RebuildGenericGraph(); + Graph = EdGraph->GetGenericGraph(); + check(Graph != nullptr); + + bool bFirstPassOnly = false; + + if (Settings != nullptr) + { + OptimalDistance = Settings->OptimalDistance; + MaxIteration = Settings->MaxIteration; + bFirstPassOnly = Settings->bFirstPassOnly; + } + + FVector2D Anchor(0.f, 0.f); + for (int32 i = 0; i < Graph->RootNodes.Num(); ++i) + { + UGenericGraphNode* RootNode = Graph->RootNodes[i]; + InitPass(RootNode, Anchor); + + if (!bFirstPassOnly) + { + for (int32 j = 0; j < MaxIteration; ++j) + { + bool HasConflict = ResolveConflictPass(RootNode); + if (!HasConflict) + { + break; + } + } + } + } + + for (int32 i = 0; i < Graph->RootNodes.Num(); ++i) + { + for (int32 j = 0; j < i; ++j) + { + ResolveConflict(Graph->RootNodes[j], Graph->RootNodes[i]); + } + } +} + +void UTreeLayoutStrategy::InitPass(UGenericGraphNode* RootNode, const FVector2D& Anchor) +{ + UEdNode_GenericGraphNode* EdNode_RootNode = EdGraph->NodeMap[RootNode]; + + FVector2D ChildAnchor(FVector2D(0.f, GetNodeHeight(EdNode_RootNode) + OptimalDistance + Anchor.Y)); + for (int32 i = 0; i < RootNode->ChildrenNodes.Num(); ++i) + { + UGenericGraphNode* Child = RootNode->ChildrenNodes[i]; + UEdNode_GenericGraphNode* EdNode_ChildNode = EdGraph->NodeMap[Child]; + if (i > 0) + { + UGenericGraphNode* PreChild = RootNode->ChildrenNodes[i - 1]; + UEdNode_GenericGraphNode* EdNode_PreChildNode = EdGraph->NodeMap[PreChild]; + ChildAnchor.X += OptimalDistance + GetNodeWidth(EdNode_PreChildNode) / 2; + } + ChildAnchor.X += GetNodeWidth(EdNode_ChildNode) / 2; + InitPass(Child, ChildAnchor); + } + + float NodeWidth = GetNodeWidth(EdNode_RootNode); + + EdNode_RootNode->NodePosY = Anchor.Y; + if (RootNode->ChildrenNodes.Num() == 0) + { + EdNode_RootNode->NodePosX = Anchor.X - NodeWidth / 2; + } + else + { + UpdateParentNodePosition(RootNode); + } +} + +bool UTreeLayoutStrategy::ResolveConflictPass(UGenericGraphNode* Node) +{ + bool HasConflict = false; + for (int32 i = 0; i < Node->ChildrenNodes.Num(); ++i) + { + UGenericGraphNode* Child = Node->ChildrenNodes[i]; + if (ResolveConflictPass(Child)) + { + HasConflict = true; + } + } + + for (int32 i = 0; i < Node->ParentNodes.Num(); ++i) + { + UGenericGraphNode* ParentNode = Node->ParentNodes[i]; + for (int32 j = 0; j < ParentNode->ChildrenNodes.Num(); ++j) + { + UGenericGraphNode* LeftSibling = ParentNode->ChildrenNodes[j]; + if (LeftSibling == Node) + break; + if (ResolveConflict(LeftSibling, Node)) + { + HasConflict = true; + } + } + } + + return HasConflict; +} + +bool UTreeLayoutStrategy::ResolveConflict(UGenericGraphNode* LRoot, UGenericGraphNode* RRoot) +{ + TArray RightContour, LeftContour; + + GetRightContour(LRoot, 0, RightContour); + GetLeftContour(RRoot, 0, LeftContour); + + int32 MaxOverlapDistance = 0; + int32 Num = FMath::Min(LeftContour.Num(), RightContour.Num()); + for (int32 i = 0; i < Num; ++i) + { + if (RightContour.Contains(LeftContour[i]) || LeftContour.Contains(RightContour[i])) + break; + + int32 RightBound = RightContour[i]->NodePosX + GetNodeWidth(RightContour[i]); + int32 LeftBound = LeftContour[i]->NodePosX; + int32 Distance = RightBound + OptimalDistance - LeftBound; + if (Distance > MaxOverlapDistance) + { + MaxOverlapDistance = Distance; + } + } + + if (MaxOverlapDistance > 0) + { + ShiftSubTree(RRoot, FVector2D(MaxOverlapDistance, 0.f)); + + TArray ParentNodes = RRoot->ParentNodes; + TArray NextParentNodes; + while (ParentNodes.Num() != 0) + { + for (int32 i = 0; i < ParentNodes.Num(); ++i) + { + UpdateParentNodePosition(ParentNodes[i]); + + NextParentNodes.Append(ParentNodes[i]->ParentNodes); + } + + ParentNodes = NextParentNodes; + NextParentNodes.Reset(); + } + + return true; + } + else + { + return false; + } +} + +void UTreeLayoutStrategy::GetLeftContour(UGenericGraphNode* RootNode, int32 Level, TArray& Contour) +{ + UEdNode_GenericGraphNode* EdNode_Node = EdGraph->NodeMap[RootNode]; + if (Level >= Contour.Num()) + { + Contour.Add(EdNode_Node); + } + else if (EdNode_Node->NodePosX < Contour[Level]->NodePosX) + { + Contour[Level] = EdNode_Node; + } + + for (int32 i = 0; i < RootNode->ChildrenNodes.Num(); ++i) + { + GetLeftContour(RootNode->ChildrenNodes[i], Level + 1, Contour); + } +} + +void UTreeLayoutStrategy::GetRightContour(UGenericGraphNode* RootNode, int32 Level, TArray& Contour) +{ + UEdNode_GenericGraphNode* EdNode_Node = EdGraph->NodeMap[RootNode]; + if (Level >= Contour.Num()) + { + Contour.Add(EdNode_Node); + } + else if (EdNode_Node->NodePosX + GetNodeWidth(EdNode_Node) > Contour[Level]->NodePosX + GetNodeWidth(Contour[Level])) + { + Contour[Level] = EdNode_Node; + } + + for (int32 i = 0; i < RootNode->ChildrenNodes.Num(); ++i) + { + GetRightContour(RootNode->ChildrenNodes[i], Level + 1, Contour); + } +} + +void UTreeLayoutStrategy::ShiftSubTree(UGenericGraphNode* RootNode, const FVector2D& Offset) +{ + UEdNode_GenericGraphNode* EdNode_Node = EdGraph->NodeMap[RootNode]; + EdNode_Node->NodePosX += Offset.X; + EdNode_Node->NodePosY += Offset.Y; + + for (int32 i = 0; i < RootNode->ChildrenNodes.Num(); ++i) + { + UGenericGraphNode* Child = RootNode->ChildrenNodes[i]; + + if (Child->ParentNodes[0] == RootNode) + { + ShiftSubTree(RootNode->ChildrenNodes[i], Offset); + } + } +} + +void UTreeLayoutStrategy::UpdateParentNodePosition(UGenericGraphNode* ParentNode) +{ + UEdNode_GenericGraphNode* EdNode_ParentNode = EdGraph->NodeMap[ParentNode]; + if (ParentNode->ChildrenNodes.Num() % 2 == 0) + { + UEdNode_GenericGraphNode* FirstChild = EdGraph->NodeMap[ParentNode->ChildrenNodes[0]]; + UEdNode_GenericGraphNode* LastChild = EdGraph->NodeMap[ParentNode->ChildrenNodes.Last()]; + float LeftBound = FirstChild->NodePosX; + float RightBound = LastChild->NodePosX + GetNodeWidth(LastChild); + EdNode_ParentNode->NodePosX = (LeftBound + RightBound) / 2 - GetNodeWidth(EdNode_ParentNode) / 2; + } + else + { + UEdNode_GenericGraphNode* MidChild = EdGraph->NodeMap[ParentNode->ChildrenNodes[ParentNode->ChildrenNodes.Num() / 2]]; + EdNode_ParentNode->NodePosX = MidChild->NodePosX + GetNodeWidth(MidChild) / 2 - GetNodeWidth(EdNode_ParentNode) / 2; + } +} diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetEditorToolbar_GenericGraph.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetEditorToolbar_GenericGraph.cpp new file mode 100644 index 00000000..1d9127cc --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetEditorToolbar_GenericGraph.cpp @@ -0,0 +1,46 @@ +#include "GenericGraphAssetEditor/AssetEditorToolbar_GenericGraph.h" +#include "GenericGraphAssetEditor/AssetEditor_GenericGraph.h" +#include "GenericGraphAssetEditor/EditorCommands_GenericGraph.h" +#include "GenericGraphAssetEditor/GenericGraphEditorStyle.h" + +#define LOCTEXT_NAMESPACE "AssetEditorToolbar_GenericGraph" + +void FAssetEditorToolbar_GenericGraph::AddGenericGraphToolbar(TSharedPtr Extender) +{ + check(GenericGraphEditor.IsValid()); + TSharedPtr GenericGraphEditorPtr = GenericGraphEditor.Pin(); + + TSharedPtr ToolbarExtender = MakeShareable(new FExtender); + ToolbarExtender->AddToolBarExtension("Asset", EExtensionHook::After, GenericGraphEditorPtr->GetToolkitCommands(), FToolBarExtensionDelegate::CreateSP( this, &FAssetEditorToolbar_GenericGraph::FillGenericGraphToolbar )); + GenericGraphEditorPtr->AddToolbarExtender(ToolbarExtender); +} + +void FAssetEditorToolbar_GenericGraph::FillGenericGraphToolbar(FToolBarBuilder& ToolbarBuilder) +{ + check(GenericGraphEditor.IsValid()); + TSharedPtr GenericGraphEditorPtr = GenericGraphEditor.Pin(); + + ToolbarBuilder.BeginSection("Generic Graph"); + { + ToolbarBuilder.AddToolBarButton(FEditorCommands_GenericGraph::Get().GraphSettings, + NAME_None, + LOCTEXT("GraphSettings_Label", "Graph Settings"), + LOCTEXT("GraphSettings_ToolTip", "Show the Graph Settings"), + FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.GameSettings")); + } + ToolbarBuilder.EndSection(); + + ToolbarBuilder.BeginSection("Util"); + { + ToolbarBuilder.AddToolBarButton(FEditorCommands_GenericGraph::Get().AutoArrange, + NAME_None, + LOCTEXT("AutoArrange_Label", "Auto Arrange"), + LOCTEXT("AutoArrange_ToolTip", "Auto arrange nodes, not perfect, but still handy"), + FSlateIcon(FGenericGraphEditorStyle::GetStyleSetName(), "GenericGraphEditor.AutoArrange")); + } + ToolbarBuilder.EndSection(); + +} + + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetEditor_GenericGraph.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetEditor_GenericGraph.cpp new file mode 100644 index 00000000..68507d39 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetEditor_GenericGraph.cpp @@ -0,0 +1,819 @@ +#include "GenericGraphAssetEditor/AssetEditor_GenericGraph.h" +#include "GenericGraphEditorPCH.h" +#include "GenericGraphAssetEditor/AssetEditorToolbar_GenericGraph.h" +#include "GenericGraphAssetEditor/AssetGraphSchema_GenericGraph.h" +#include "GenericGraphAssetEditor/EditorCommands_GenericGraph.h" +#include "GenericGraphAssetEditor/EdGraph_GenericGraph.h" +#include "AssetToolsModule.h" +#include "HAL/PlatformApplicationMisc.h" +#include "Framework/Commands/GenericCommands.h" +#include "GraphEditorActions.h" +#include "IDetailsView.h" +#include "PropertyEditorModule.h" +#include "Editor/UnrealEd/Public/Kismet2/BlueprintEditorUtils.h" +#include "Kismet2/KismetEditorUtilities.h" +#include "EdGraphUtilities.h" +#include "GenericGraphAssetEditor/EdGraph_GenericGraph.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphNode.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphEdge.h" +#include "AutoLayout/TreeLayoutStrategy.h" +#include "AutoLayout/ForceDirectedLayoutStrategy.h" + +#define LOCTEXT_NAMESPACE "AssetEditor_GenericGraph" + +const FName GenericGraphEditorAppName = FName(TEXT("GenericGraphEditorApp")); + +struct FGenericGraphAssetEditorTabs +{ + // Tab identifiers + static const FName GenericGraphPropertyID; + static const FName ViewportID; + static const FName GenericGraphEditorSettingsID; +}; + +////////////////////////////////////////////////////////////////////////// + +const FName FGenericGraphAssetEditorTabs::GenericGraphPropertyID(TEXT("GenericGraphProperty")); +const FName FGenericGraphAssetEditorTabs::ViewportID(TEXT("Viewport")); +const FName FGenericGraphAssetEditorTabs::GenericGraphEditorSettingsID(TEXT("GenericGraphEditorSettings")); + +////////////////////////////////////////////////////////////////////////// + +FAssetEditor_GenericGraph::FAssetEditor_GenericGraph() +{ + EditingGraph = nullptr; + + GenricGraphEditorSettings = NewObject(UGenericGraphEditorSettings::StaticClass()); + +#if ENGINE_MAJOR_VERSION < 5 + OnPackageSavedDelegateHandle = UPackage::PackageSavedEvent.AddRaw(this, &FAssetEditor_GenericGraph::OnPackageSaved); +#else // #if ENGINE_MAJOR_VERSION < 5 + OnPackageSavedDelegateHandle = UPackage::PackageSavedWithContextEvent.AddRaw(this, &FAssetEditor_GenericGraph::OnPackageSavedWithContext); +#endif // #else // #if ENGINE_MAJOR_VERSION < 5 +} + +FAssetEditor_GenericGraph::~FAssetEditor_GenericGraph() +{ +#if ENGINE_MAJOR_VERSION < 5 + UPackage::PackageSavedEvent.Remove(OnPackageSavedDelegateHandle); +#else // #if ENGINE_MAJOR_VERSION < 5 + UPackage::PackageSavedWithContextEvent.Remove(OnPackageSavedDelegateHandle); +#endif // #else // #if ENGINE_MAJOR_VERSION < 5 +} + +void FAssetEditor_GenericGraph::InitGenericGraphAssetEditor(const EToolkitMode::Type Mode, const TSharedPtr< IToolkitHost >& InitToolkitHost, UGenericGraph* Graph) +{ + EditingGraph = Graph; + CreateEdGraph(); + + FGenericCommands::Register(); + FGraphEditorCommands::Register(); + FEditorCommands_GenericGraph::Register(); + + if (!ToolbarBuilder.IsValid()) + { + ToolbarBuilder = MakeShareable(new FAssetEditorToolbar_GenericGraph(SharedThis(this))); + } + + BindCommands(); + + CreateInternalWidgets(); + + TSharedPtr ToolbarExtender = MakeShareable(new FExtender); + + ToolbarBuilder->AddGenericGraphToolbar(ToolbarExtender); + + // Layout + const TSharedRef StandaloneDefaultLayout = FTabManager::NewLayout("Standalone_GenericGraphEditor_Layout_v1") + ->AddArea + ( + FTabManager::NewPrimaryArea()->SetOrientation(Orient_Vertical) +#if ENGINE_MAJOR_VERSION < 5 + ->Split + ( + FTabManager::NewStack() + ->SetSizeCoefficient(0.1f) + ->AddTab(GetToolbarTabId(), ETabState::OpenedTab)->SetHideTabWell(true) + ) +#endif // #if ENGINE_MAJOR_VERSION < 5 + ->Split + ( + FTabManager::NewSplitter()->SetOrientation(Orient_Horizontal)->SetSizeCoefficient(0.9f) + ->Split + ( + FTabManager::NewStack() + ->SetSizeCoefficient(0.65f) + ->AddTab(FGenericGraphAssetEditorTabs::ViewportID, ETabState::OpenedTab)->SetHideTabWell(true) + ) + ->Split + ( + FTabManager::NewSplitter()->SetOrientation(Orient_Vertical) + ->Split + ( + FTabManager::NewStack() + ->SetSizeCoefficient(0.7f) + ->AddTab(FGenericGraphAssetEditorTabs::GenericGraphPropertyID, ETabState::OpenedTab)->SetHideTabWell(true) + ) + ->Split + ( + FTabManager::NewStack() + ->SetSizeCoefficient(0.3f) + ->AddTab(FGenericGraphAssetEditorTabs::GenericGraphEditorSettingsID, ETabState::OpenedTab) + ) + ) + ) + ); + + const bool bCreateDefaultStandaloneMenu = true; + const bool bCreateDefaultToolbar = true; + FAssetEditorToolkit::InitAssetEditor(Mode, InitToolkitHost, GenericGraphEditorAppName, StandaloneDefaultLayout, bCreateDefaultStandaloneMenu, bCreateDefaultToolbar, EditingGraph, false); + + RegenerateMenusAndToolbars(); +} + +void FAssetEditor_GenericGraph::RegisterTabSpawners(const TSharedRef& InTabManager) +{ + WorkspaceMenuCategory = InTabManager->AddLocalWorkspaceMenuCategory(LOCTEXT("WorkspaceMenu_GenericGraphEditor", "Generic Graph Editor")); + auto WorkspaceMenuCategoryRef = WorkspaceMenuCategory.ToSharedRef(); + + FAssetEditorToolkit::RegisterTabSpawners(InTabManager); + + InTabManager->RegisterTabSpawner(FGenericGraphAssetEditorTabs::ViewportID, FOnSpawnTab::CreateSP(this, &FAssetEditor_GenericGraph::SpawnTab_Viewport)) + .SetDisplayName(LOCTEXT("GraphCanvasTab", "Viewport")) + .SetGroup(WorkspaceMenuCategoryRef) + .SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "GraphEditor.EventGraph_16x")); + + InTabManager->RegisterTabSpawner(FGenericGraphAssetEditorTabs::GenericGraphPropertyID, FOnSpawnTab::CreateSP(this, &FAssetEditor_GenericGraph::SpawnTab_Details)) + .SetDisplayName(LOCTEXT("DetailsTab", "Property")) + .SetGroup(WorkspaceMenuCategoryRef) + .SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Details")); + + InTabManager->RegisterTabSpawner(FGenericGraphAssetEditorTabs::GenericGraphEditorSettingsID, FOnSpawnTab::CreateSP(this, &FAssetEditor_GenericGraph::SpawnTab_EditorSettings)) + .SetDisplayName(LOCTEXT("EditorSettingsTab", "Generic Graph Editor Setttings")) + .SetGroup(WorkspaceMenuCategoryRef) + .SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Details")); +} + +void FAssetEditor_GenericGraph::UnregisterTabSpawners(const TSharedRef& InTabManager) +{ + FAssetEditorToolkit::UnregisterTabSpawners(InTabManager); + + InTabManager->UnregisterTabSpawner(FGenericGraphAssetEditorTabs::ViewportID); + InTabManager->UnregisterTabSpawner(FGenericGraphAssetEditorTabs::GenericGraphPropertyID); + InTabManager->UnregisterTabSpawner(FGenericGraphAssetEditorTabs::GenericGraphEditorSettingsID); +} + +FName FAssetEditor_GenericGraph::GetToolkitFName() const +{ + return FName("FGenericGraphEditor"); +} + +FText FAssetEditor_GenericGraph::GetBaseToolkitName() const +{ + return LOCTEXT("GenericGraphEditorAppLabel", "Generic Graph Editor"); +} + +FText FAssetEditor_GenericGraph::GetToolkitName() const +{ + const bool bDirtyState = EditingGraph->GetOutermost()->IsDirty(); + + FFormatNamedArguments Args; + Args.Add(TEXT("GenericGraphName"), FText::FromString(EditingGraph->GetName())); + Args.Add(TEXT("DirtyState"), bDirtyState ? FText::FromString(TEXT("*")) : FText::GetEmpty()); + return FText::Format(LOCTEXT("GenericGraphEditorToolkitName", "{GenericGraphName}{DirtyState}"), Args); +} + +FText FAssetEditor_GenericGraph::GetToolkitToolTipText() const +{ + return FAssetEditorToolkit::GetToolTipTextForObject(EditingGraph); +} + +FLinearColor FAssetEditor_GenericGraph::GetWorldCentricTabColorScale() const +{ + return FLinearColor::White; +} + +FString FAssetEditor_GenericGraph::GetWorldCentricTabPrefix() const +{ + return TEXT("GenericGraphEditor"); +} + +FString FAssetEditor_GenericGraph::GetDocumentationLink() const +{ + return TEXT(""); +} + +void FAssetEditor_GenericGraph::SaveAsset_Execute() +{ + if (EditingGraph != nullptr) + { + RebuildGenericGraph(); + } + + FAssetEditorToolkit::SaveAsset_Execute(); +} + +void FAssetEditor_GenericGraph::AddReferencedObjects(FReferenceCollector& Collector) +{ + Collector.AddReferencedObject(EditingGraph); + Collector.AddReferencedObject(EditingGraph->EdGraph); +} + +UGenericGraphEditorSettings* FAssetEditor_GenericGraph::GetSettings() const +{ + return GenricGraphEditorSettings; +} + +TSharedRef FAssetEditor_GenericGraph::SpawnTab_Viewport(const FSpawnTabArgs& Args) +{ + check(Args.GetTabId() == FGenericGraphAssetEditorTabs::ViewportID); + + TSharedRef SpawnedTab = SNew(SDockTab) + .Label(LOCTEXT("ViewportTab_Title", "Viewport")); + + if (ViewportWidget.IsValid()) + { + SpawnedTab->SetContent(ViewportWidget.ToSharedRef()); + } + + return SpawnedTab; +} + +TSharedRef FAssetEditor_GenericGraph::SpawnTab_Details(const FSpawnTabArgs& Args) +{ + check(Args.GetTabId() == FGenericGraphAssetEditorTabs::GenericGraphPropertyID); + + return SNew(SDockTab) +#if ENGINE_MAJOR_VERSION < 5 + .Icon(FAppStyle::GetBrush("LevelEditor.Tabs.Details")) +#endif // #if ENGINE_MAJOR_VERSION < 5 + .Label(LOCTEXT("Details_Title", "Property")) + [ + PropertyWidget.ToSharedRef() + ]; +} + +TSharedRef FAssetEditor_GenericGraph::SpawnTab_EditorSettings(const FSpawnTabArgs& Args) +{ + check(Args.GetTabId() == FGenericGraphAssetEditorTabs::GenericGraphEditorSettingsID); + + return SNew(SDockTab) +#if ENGINE_MAJOR_VERSION < 5 + .Icon(FAppStyle::GetBrush("LevelEditor.Tabs.Details")) +#endif // #if ENGINE_MAJOR_VERSION < 5 + .Label(LOCTEXT("EditorSettings_Title", "Generic Graph Editor Setttings")) + [ + EditorSettingsWidget.ToSharedRef() + ]; +} + +void FAssetEditor_GenericGraph::CreateInternalWidgets() +{ + ViewportWidget = CreateViewportWidget(); + + FDetailsViewArgs Args; + Args.bHideSelectionTip = true; + Args.NotifyHook = this; + + FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked("PropertyEditor"); + PropertyWidget = PropertyModule.CreateDetailView(Args); + PropertyWidget->SetObject(EditingGraph); + PropertyWidget->OnFinishedChangingProperties().AddSP(this, &FAssetEditor_GenericGraph::OnFinishedChangingProperties); + + EditorSettingsWidget = PropertyModule.CreateDetailView(Args); + EditorSettingsWidget->SetObject(GenricGraphEditorSettings); +} + +TSharedRef FAssetEditor_GenericGraph::CreateViewportWidget() +{ + FGraphAppearanceInfo AppearanceInfo; + AppearanceInfo.CornerText = LOCTEXT("AppearanceCornerText_GenericGraph", "Generic Graph"); + + CreateCommandList(); + + SGraphEditor::FGraphEditorEvents InEvents; + InEvents.OnSelectionChanged = SGraphEditor::FOnSelectionChanged::CreateSP(this, &FAssetEditor_GenericGraph::OnSelectedNodesChanged); + InEvents.OnNodeDoubleClicked = FSingleNodeEvent::CreateSP(this, &FAssetEditor_GenericGraph::OnNodeDoubleClicked); + + return SNew(SGraphEditor) + .AdditionalCommands(GraphEditorCommands) + .IsEditable(true) + .Appearance(AppearanceInfo) + .GraphToEdit(EditingGraph->EdGraph) + .GraphEvents(InEvents) + .AutoExpandActionMenu(true) + .ShowGraphStateOverlay(false); +} + +void FAssetEditor_GenericGraph::BindCommands() +{ + ToolkitCommands->MapAction(FEditorCommands_GenericGraph::Get().GraphSettings, + FExecuteAction::CreateSP(this, &FAssetEditor_GenericGraph::GraphSettings), + FCanExecuteAction::CreateSP(this, &FAssetEditor_GenericGraph::CanGraphSettings) + ); + + ToolkitCommands->MapAction(FEditorCommands_GenericGraph::Get().AutoArrange, + FExecuteAction::CreateSP(this, &FAssetEditor_GenericGraph::AutoArrange), + FCanExecuteAction::CreateSP(this, &FAssetEditor_GenericGraph::CanAutoArrange) + ); +} + +void FAssetEditor_GenericGraph::CreateEdGraph() +{ + if (EditingGraph->EdGraph == nullptr) + { + EditingGraph->EdGraph = CastChecked(FBlueprintEditorUtils::CreateNewGraph(EditingGraph, NAME_None, UEdGraph_GenericGraph::StaticClass(), UAssetGraphSchema_GenericGraph::StaticClass())); + EditingGraph->EdGraph->bAllowDeletion = false; + + // Give the schema a chance to fill out any required nodes (like the results node) + const UEdGraphSchema* Schema = EditingGraph->EdGraph->GetSchema(); + Schema->CreateDefaultNodesForGraph(*EditingGraph->EdGraph); + } +} + +void FAssetEditor_GenericGraph::CreateCommandList() +{ + if (GraphEditorCommands.IsValid()) + { + return; + } + + GraphEditorCommands = MakeShareable(new FUICommandList); + + // Can't use CreateSP here because derived editor are already implementing TSharedFromThis + // however it should be safe, since commands are being used only within this editor + // if it ever crashes, this function will have to go away and be reimplemented in each derived class + + GraphEditorCommands->MapAction(FEditorCommands_GenericGraph::Get().GraphSettings, + FExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::GraphSettings), + FCanExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::CanGraphSettings)); + + GraphEditorCommands->MapAction(FEditorCommands_GenericGraph::Get().AutoArrange, + FExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::AutoArrange), + FCanExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::CanAutoArrange)); + + GraphEditorCommands->MapAction(FGenericCommands::Get().SelectAll, + FExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::SelectAllNodes), + FCanExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::CanSelectAllNodes) + ); + + GraphEditorCommands->MapAction(FGenericCommands::Get().Delete, + FExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::DeleteSelectedNodes), + FCanExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::CanDeleteNodes) + ); + + GraphEditorCommands->MapAction(FGenericCommands::Get().Copy, + FExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::CopySelectedNodes), + FCanExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::CanCopyNodes) + ); + + GraphEditorCommands->MapAction(FGenericCommands::Get().Cut, + FExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::CutSelectedNodes), + FCanExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::CanCutNodes) + ); + + GraphEditorCommands->MapAction(FGenericCommands::Get().Paste, + FExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::PasteNodes), + FCanExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::CanPasteNodes) + ); + + GraphEditorCommands->MapAction(FGenericCommands::Get().Duplicate, + FExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::DuplicateNodes), + FCanExecuteAction::CreateRaw(this, &FAssetEditor_GenericGraph::CanDuplicateNodes) + ); + + GraphEditorCommands->MapAction(FGenericCommands::Get().Rename, + FExecuteAction::CreateSP(this, &FAssetEditor_GenericGraph::OnRenameNode), + FCanExecuteAction::CreateSP(this, &FAssetEditor_GenericGraph::CanRenameNodes) + ); +} + +TSharedPtr FAssetEditor_GenericGraph::GetCurrGraphEditor() const +{ + return ViewportWidget; +} + +FGraphPanelSelectionSet FAssetEditor_GenericGraph::GetSelectedNodes() const +{ + FGraphPanelSelectionSet CurrentSelection; + TSharedPtr FocusedGraphEd = GetCurrGraphEditor(); + if (FocusedGraphEd.IsValid()) + { + CurrentSelection = FocusedGraphEd->GetSelectedNodes(); + } + + return CurrentSelection; +} + +void FAssetEditor_GenericGraph::RebuildGenericGraph() +{ + if (EditingGraph == nullptr) + { + LOG_WARNING(TEXT("FGenericGraphAssetEditor::RebuildGenericGraph EditingGraph is nullptr")); + return; + } + + UEdGraph_GenericGraph* EdGraph = Cast(EditingGraph->EdGraph); + check(EdGraph != nullptr); + + EdGraph->RebuildGenericGraph(); +} + +void FAssetEditor_GenericGraph::SelectAllNodes() +{ + TSharedPtr CurrentGraphEditor = GetCurrGraphEditor(); + if (CurrentGraphEditor.IsValid()) + { + CurrentGraphEditor->SelectAllNodes(); + } +} + +bool FAssetEditor_GenericGraph::CanSelectAllNodes() +{ + return true; +} + +void FAssetEditor_GenericGraph::DeleteSelectedNodes() +{ + TSharedPtr CurrentGraphEditor = GetCurrGraphEditor(); + if (!CurrentGraphEditor.IsValid()) + { + return; + } + + const FScopedTransaction Transaction(FGenericCommands::Get().Delete->GetDescription()); + + CurrentGraphEditor->GetCurrentGraph()->Modify(); + + const FGraphPanelSelectionSet SelectedNodes = CurrentGraphEditor->GetSelectedNodes(); + CurrentGraphEditor->ClearSelectionSet(); + + for (FGraphPanelSelectionSet::TConstIterator NodeIt(SelectedNodes); NodeIt; ++NodeIt) + { + UEdGraphNode* EdNode = Cast(*NodeIt); + if (EdNode == nullptr || !EdNode->CanUserDeleteNode()) + continue;; + + if (UEdNode_GenericGraphNode* EdNode_Node = Cast(EdNode)) + { + EdNode_Node->Modify(); + + const UEdGraphSchema* Schema = EdNode_Node->GetSchema(); + if (Schema != nullptr) + { + Schema->BreakNodeLinks(*EdNode_Node); + } + + EdNode_Node->DestroyNode(); + } + else + { + EdNode->Modify(); + EdNode->DestroyNode(); + } + } +} + +bool FAssetEditor_GenericGraph::CanDeleteNodes() +{ + // If any of the nodes can be deleted then we should allow deleting + const FGraphPanelSelectionSet SelectedNodes = GetSelectedNodes(); + for (FGraphPanelSelectionSet::TConstIterator SelectedIter(SelectedNodes); SelectedIter; ++SelectedIter) + { + UEdGraphNode* Node = Cast(*SelectedIter); + if (Node != nullptr && Node->CanUserDeleteNode()) + { + return true; + } + } + + return false; +} + +void FAssetEditor_GenericGraph::DeleteSelectedDuplicatableNodes() +{ + TSharedPtr CurrentGraphEditor = GetCurrGraphEditor(); + if (!CurrentGraphEditor.IsValid()) + { + return; + } + + const FGraphPanelSelectionSet OldSelectedNodes = CurrentGraphEditor->GetSelectedNodes(); + CurrentGraphEditor->ClearSelectionSet(); + + for (FGraphPanelSelectionSet::TConstIterator SelectedIter(OldSelectedNodes); SelectedIter; ++SelectedIter) + { + UEdGraphNode* Node = Cast(*SelectedIter); + if (Node && Node->CanDuplicateNode()) + { + CurrentGraphEditor->SetNodeSelection(Node, true); + } + } + + // Delete the duplicatable nodes + DeleteSelectedNodes(); + + CurrentGraphEditor->ClearSelectionSet(); + + for (FGraphPanelSelectionSet::TConstIterator SelectedIter(OldSelectedNodes); SelectedIter; ++SelectedIter) + { + if (UEdGraphNode* Node = Cast(*SelectedIter)) + { + CurrentGraphEditor->SetNodeSelection(Node, true); + } + } +} + +void FAssetEditor_GenericGraph::CutSelectedNodes() +{ + CopySelectedNodes(); + DeleteSelectedDuplicatableNodes(); +} + +bool FAssetEditor_GenericGraph::CanCutNodes() +{ + return CanCopyNodes() && CanDeleteNodes(); +} + +void FAssetEditor_GenericGraph::CopySelectedNodes() +{ + // Export the selected nodes and place the text on the clipboard + FGraphPanelSelectionSet SelectedNodes = GetSelectedNodes(); + + FString ExportedText; + + for (FGraphPanelSelectionSet::TIterator SelectedIter(SelectedNodes); SelectedIter; ++SelectedIter) + { + UEdGraphNode* Node = Cast(*SelectedIter); + if (Node == nullptr) + { + SelectedIter.RemoveCurrent(); + continue; + } + + if (UEdNode_GenericGraphEdge* EdNode_Edge = Cast(*SelectedIter)) + { + UEdNode_GenericGraphNode* StartNode = EdNode_Edge->GetStartNode(); + UEdNode_GenericGraphNode* EndNode = EdNode_Edge->GetEndNode(); + + if (!SelectedNodes.Contains(StartNode) || !SelectedNodes.Contains(EndNode)) + { + SelectedIter.RemoveCurrent(); + continue; + } + } + + Node->PrepareForCopying(); + } + + FEdGraphUtilities::ExportNodesToText(SelectedNodes, ExportedText); + FPlatformApplicationMisc::ClipboardCopy(*ExportedText); +} + +bool FAssetEditor_GenericGraph::CanCopyNodes() +{ + // If any of the nodes can be duplicated then we should allow copying + const FGraphPanelSelectionSet SelectedNodes = GetSelectedNodes(); + for (FGraphPanelSelectionSet::TConstIterator SelectedIter(SelectedNodes); SelectedIter; ++SelectedIter) + { + UEdGraphNode* Node = Cast(*SelectedIter); + if (Node && Node->CanDuplicateNode()) + { + return true; + } + } + + return false; +} + +void FAssetEditor_GenericGraph::PasteNodes() +{ + TSharedPtr CurrentGraphEditor = GetCurrGraphEditor(); + if (CurrentGraphEditor.IsValid()) + { + PasteNodesHere(CurrentGraphEditor->GetPasteLocation()); + } +} + +void FAssetEditor_GenericGraph::PasteNodesHere(const FVector2D& Location) +{ + // Find the graph editor with focus + TSharedPtr CurrentGraphEditor = GetCurrGraphEditor(); + if (!CurrentGraphEditor.IsValid()) + { + return; + } + // Select the newly pasted stuff + UEdGraph* EdGraph = CurrentGraphEditor->GetCurrentGraph(); + + { + const FScopedTransaction Transaction(FGenericCommands::Get().Paste->GetDescription()); + EdGraph->Modify(); + + // Clear the selection set (newly pasted stuff will be selected) + CurrentGraphEditor->ClearSelectionSet(); + + // Grab the text to paste from the clipboard. + FString TextToImport; + FPlatformApplicationMisc::ClipboardPaste(TextToImport); + + // Import the nodes + TSet PastedNodes; + FEdGraphUtilities::ImportNodesFromText(EdGraph, TextToImport, PastedNodes); + + //Average position of nodes so we can move them while still maintaining relative distances to each other + FVector2D AvgNodePosition(0.0f, 0.0f); + + for (TSet::TIterator It(PastedNodes); It; ++It) + { + UEdGraphNode* Node = *It; + AvgNodePosition.X += Node->NodePosX; + AvgNodePosition.Y += Node->NodePosY; + } + + float InvNumNodes = 1.0f / float(PastedNodes.Num()); + AvgNodePosition.X *= InvNumNodes; + AvgNodePosition.Y *= InvNumNodes; + + for (TSet::TIterator It(PastedNodes); It; ++It) + { + UEdGraphNode* Node = *It; + CurrentGraphEditor->SetNodeSelection(Node, true); + + Node->NodePosX = (Node->NodePosX - AvgNodePosition.X) + Location.X; + Node->NodePosY = (Node->NodePosY - AvgNodePosition.Y) + Location.Y; + + Node->SnapToGrid(16); + + // Give new node a different Guid from the old one + Node->CreateNewGuid(); + } + } + + // Update UI + CurrentGraphEditor->NotifyGraphChanged(); + + UObject* GraphOwner = EdGraph->GetOuter(); + if (GraphOwner) + { + GraphOwner->PostEditChange(); + GraphOwner->MarkPackageDirty(); + } +} + +bool FAssetEditor_GenericGraph::CanPasteNodes() +{ + TSharedPtr CurrentGraphEditor = GetCurrGraphEditor(); + if (!CurrentGraphEditor.IsValid()) + { + return false; + } + + FString ClipboardContent; + FPlatformApplicationMisc::ClipboardPaste(ClipboardContent); + + return FEdGraphUtilities::CanImportNodesFromText(CurrentGraphEditor->GetCurrentGraph(), ClipboardContent); +} + +void FAssetEditor_GenericGraph::DuplicateNodes() +{ + CopySelectedNodes(); + PasteNodes(); +} + +bool FAssetEditor_GenericGraph::CanDuplicateNodes() +{ + return CanCopyNodes(); +} + +void FAssetEditor_GenericGraph::GraphSettings() +{ + PropertyWidget->SetObject(EditingGraph); +} + +bool FAssetEditor_GenericGraph::CanGraphSettings() const +{ + return true; +} + +void FAssetEditor_GenericGraph::AutoArrange() +{ + UEdGraph_GenericGraph* EdGraph = Cast(EditingGraph->EdGraph); + check(EdGraph != nullptr); + + const FScopedTransaction Transaction(LOCTEXT("GenericGraphEditorAutoArrange", "Generic Graph Editor: Auto Arrange")); + + EdGraph->Modify(); + + UAutoLayoutStrategy* LayoutStrategy = nullptr; + switch (GenricGraphEditorSettings->AutoLayoutStrategy) + { + case EAutoLayoutStrategy::Tree: + LayoutStrategy = NewObject(EdGraph, UTreeLayoutStrategy::StaticClass()); + break; + case EAutoLayoutStrategy::ForceDirected: + LayoutStrategy = NewObject(EdGraph, UForceDirectedLayoutStrategy::StaticClass()); + break; + default: + break; + } + + if (LayoutStrategy != nullptr) + { + LayoutStrategy->Settings = GenricGraphEditorSettings; + LayoutStrategy->Layout(EdGraph); + LayoutStrategy->ConditionalBeginDestroy(); + } + else + { + LOG_ERROR(TEXT("FAssetEditor_GenericGraph::AutoArrange LayoutStrategy is null.")); + } +} + +bool FAssetEditor_GenericGraph::CanAutoArrange() const +{ + return EditingGraph != nullptr && Cast(EditingGraph->EdGraph) != nullptr; +} + +void FAssetEditor_GenericGraph::OnRenameNode() +{ + TSharedPtr CurrentGraphEditor = GetCurrGraphEditor(); + if (CurrentGraphEditor.IsValid()) + { + const FGraphPanelSelectionSet SelectedNodes = GetSelectedNodes(); + for (FGraphPanelSelectionSet::TConstIterator NodeIt(SelectedNodes); NodeIt; ++NodeIt) + { + UEdGraphNode* SelectedNode = Cast(*NodeIt); + if (SelectedNode != NULL && SelectedNode->bCanRenameNode) + { + CurrentGraphEditor->IsNodeTitleVisible(SelectedNode, true); + break; + } + } + } +} + +bool FAssetEditor_GenericGraph::CanRenameNodes() const +{ + UEdGraph_GenericGraph* EdGraph = Cast(EditingGraph->EdGraph); + check(EdGraph != nullptr); + + UGenericGraph* Graph = EdGraph->GetGenericGraph(); + check(Graph != nullptr) + + return Graph->bCanRenameNode && GetSelectedNodes().Num() == 1; +} + +void FAssetEditor_GenericGraph::OnSelectedNodesChanged(const TSet& NewSelection) +{ + TArray Selection; + + for (UObject* SelectionEntry : NewSelection) + { + Selection.Add(SelectionEntry); + } + + if (Selection.Num() == 0) + { + PropertyWidget->SetObject(EditingGraph); + + } + else + { + PropertyWidget->SetObjects(Selection); + } +} + +void FAssetEditor_GenericGraph::OnNodeDoubleClicked(UEdGraphNode* Node) +{ + +} + +void FAssetEditor_GenericGraph::OnFinishedChangingProperties(const FPropertyChangedEvent& PropertyChangedEvent) +{ + if (EditingGraph == nullptr) + return; + + EditingGraph->EdGraph->GetSchema()->ForceVisualizationCacheClear(); +} + +#if ENGINE_MAJOR_VERSION < 5 +void FAssetEditor_GenericGraph::OnPackageSaved(const FString& PackageFileName, UObject* Outer) +{ + RebuildGenericGraph(); +} +#else // #if ENGINE_MAJOR_VERSION < 5 +void FAssetEditor_GenericGraph::OnPackageSavedWithContext(const FString& PackageFileName, UPackage* Package, FObjectPostSaveContext ObjectSaveContext) +{ + RebuildGenericGraph(); +} +#endif // #else // #if ENGINE_MAJOR_VERSION < 5 + +void FAssetEditor_GenericGraph::RegisterToolbarTab(const TSharedRef& InTabManager) +{ + FAssetEditorToolkit::RegisterTabSpawners(InTabManager); +} + + +#undef LOCTEXT_NAMESPACE + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetGraphSchema_GenericGraph.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetGraphSchema_GenericGraph.cpp new file mode 100644 index 00000000..8c873f8d --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/AssetGraphSchema_GenericGraph.cpp @@ -0,0 +1,476 @@ +#include "GenericGraphAssetEditor/AssetGraphSchema_GenericGraph.h" +#include "ToolMenus.h" +#include "GenericGraphEditorPCH.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphNode.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphEdge.h" +#include "GenericGraphAssetEditor/ConnectionDrawingPolicy_GenericGraph.h" +#include "GraphEditorActions.h" +#include "Framework/Commands/GenericCommands.h" +#include "AutoLayout/ForceDirectedLayoutStrategy.h" +#include "AutoLayout/TreeLayoutStrategy.h" + +#define LOCTEXT_NAMESPACE "AssetSchema_GenericGraph" + +int32 UAssetGraphSchema_GenericGraph::CurrentCacheRefreshID = 0; + + +class FNodeVisitorCycleChecker +{ +public: + /** Check whether a loop in the graph would be caused by linking the passed-in nodes */ + bool CheckForLoop(UEdGraphNode* StartNode, UEdGraphNode* EndNode) + { + + VisitedNodes.Add(StartNode); + + return TraverseNodes(EndNode); + } + +private: + bool TraverseNodes(UEdGraphNode* Node) + { + VisitedNodes.Add(Node); + + for (auto MyPin : Node->Pins) + { + if (MyPin->Direction == EGPD_Output) + { + for (auto OtherPin : MyPin->LinkedTo) + { + UEdGraphNode* OtherNode = OtherPin->GetOwningNode(); + if (VisitedNodes.Contains(OtherNode)) + { + // Only an issue if this is a back-edge + return false; + } + else if (!FinishedNodes.Contains(OtherNode)) + { + // Only should traverse if this node hasn't been traversed + if (!TraverseNodes(OtherNode)) + return false; + } + } + } + } + + VisitedNodes.Remove(Node); + FinishedNodes.Add(Node); + return true; + }; + + + TSet VisitedNodes; + TSet FinishedNodes; +}; + +UEdGraphNode* FAssetSchemaAction_GenericGraph_NewNode::PerformAction(class UEdGraph* ParentGraph, UEdGraphPin* FromPin, const FVector2D Location, bool bSelectNewNode /*= true*/) +{ + UEdGraphNode* ResultNode = nullptr; + + if (NodeTemplate != nullptr) + { + const FScopedTransaction Transaction(LOCTEXT("GenericGraphEditorNewNode", "Generic Graph Editor: New Node")); + ParentGraph->Modify(); + if (FromPin != nullptr) + FromPin->Modify(); + + NodeTemplate->Rename(nullptr, ParentGraph); + ParentGraph->AddNode(NodeTemplate, true, bSelectNewNode); + + NodeTemplate->CreateNewGuid(); + NodeTemplate->PostPlacedNewNode(); + NodeTemplate->AllocateDefaultPins(); + NodeTemplate->AutowireNewNode(FromPin); + + NodeTemplate->NodePosX = Location.X; + NodeTemplate->NodePosY = Location.Y; + + NodeTemplate->GenericGraphNode->SetFlags(RF_Transactional); + NodeTemplate->SetFlags(RF_Transactional); + + ResultNode = NodeTemplate; + } + + return ResultNode; +} + +void FAssetSchemaAction_GenericGraph_NewNode::AddReferencedObjects(FReferenceCollector& Collector) +{ + FEdGraphSchemaAction::AddReferencedObjects(Collector); + Collector.AddReferencedObject(NodeTemplate); +} + +UEdGraphNode* FAssetSchemaAction_GenericGraph_NewEdge::PerformAction(class UEdGraph* ParentGraph, UEdGraphPin* FromPin, const FVector2D Location, bool bSelectNewNode /*= true*/) +{ + UEdGraphNode* ResultNode = nullptr; + + if (NodeTemplate != nullptr) + { + const FScopedTransaction Transaction(LOCTEXT("GenericGraphEditorNewEdge", "Generic Graph Editor: New Edge")); + ParentGraph->Modify(); + if (FromPin != nullptr) + FromPin->Modify(); + + NodeTemplate->Rename(nullptr, ParentGraph); + ParentGraph->AddNode(NodeTemplate, true, bSelectNewNode); + + NodeTemplate->CreateNewGuid(); + NodeTemplate->PostPlacedNewNode(); + NodeTemplate->AllocateDefaultPins(); + NodeTemplate->AutowireNewNode(FromPin); + + NodeTemplate->NodePosX = Location.X; + NodeTemplate->NodePosY = Location.Y; + + NodeTemplate->GenericGraphEdge->SetFlags(RF_Transactional); + NodeTemplate->SetFlags(RF_Transactional); + + ResultNode = NodeTemplate; + } + + return ResultNode; +} + +void FAssetSchemaAction_GenericGraph_NewEdge::AddReferencedObjects(FReferenceCollector& Collector) +{ + FEdGraphSchemaAction::AddReferencedObjects(Collector); + Collector.AddReferencedObject(NodeTemplate); +} + +void UAssetGraphSchema_GenericGraph::GetBreakLinkToSubMenuActions(UToolMenu* Menu, UEdGraphPin* InGraphPin) +{ + // Make sure we have a unique name for every entry in the list + TMap< FString, uint32 > LinkTitleCount; + + FToolMenuSection& Section = Menu->FindOrAddSection("GenericGraphAssetGraphSchemaPinActions"); + + // Add all the links we could break from + for (TArray::TConstIterator Links(InGraphPin->LinkedTo); Links; ++Links) + { + UEdGraphPin* Pin = *Links; + FString TitleString = Pin->GetOwningNode()->GetNodeTitle(ENodeTitleType::ListView).ToString(); + FText Title = FText::FromString(TitleString); + if (Pin->PinName != TEXT("")) + { + TitleString = FString::Printf(TEXT("%s (%s)"), *TitleString, *Pin->PinName.ToString()); + + // Add name of connection if possible + FFormatNamedArguments Args; + Args.Add(TEXT("NodeTitle"), Title); + Args.Add(TEXT("PinName"), Pin->GetDisplayName()); + Title = FText::Format(LOCTEXT("BreakDescPin", "{NodeTitle} ({PinName})"), Args); + } + + uint32& Count = LinkTitleCount.FindOrAdd(TitleString); + + FText Description; + FFormatNamedArguments Args; + Args.Add(TEXT("NodeTitle"), Title); + Args.Add(TEXT("NumberOfNodes"), Count); + + if (Count == 0) + { + Description = FText::Format(LOCTEXT("BreakDesc", "Break link to {NodeTitle}"), Args); + } + else + { + Description = FText::Format(LOCTEXT("BreakDescMulti", "Break link to {NodeTitle} ({NumberOfNodes})"), Args); + } + ++Count; + + Section.AddMenuEntry(NAME_None, Description, Description, FSlateIcon(), FUIAction( + FExecuteAction::CreateUObject(this, &UAssetGraphSchema_GenericGraph::BreakSinglePinLink, const_cast(InGraphPin), *Links))); + } +} + +EGraphType UAssetGraphSchema_GenericGraph::GetGraphType(const UEdGraph* TestEdGraph) const +{ + return GT_StateMachine; +} + +void UAssetGraphSchema_GenericGraph::GetGraphContextActions(FGraphContextMenuBuilder& ContextMenuBuilder) const +{ + UGenericGraph* Graph = CastChecked(ContextMenuBuilder.CurrentGraph->GetOuter()); + + if (Graph->NodeType == nullptr) + { + return; + } + + const bool bNoParent = (ContextMenuBuilder.FromPin == NULL); + + const FText AddToolTip = LOCTEXT("NewGenericGraphNodeTooltip", "Add node here"); + + TSet > Visited; + + FText Desc = Graph->NodeType.GetDefaultObject()->ContextMenuName; + + if (Desc.IsEmpty()) + { + FString Title = Graph->NodeType->GetName(); + Title.RemoveFromEnd("_C"); + Desc = FText::FromString(Title); + } + + if (!Graph->NodeType->HasAnyClassFlags(CLASS_Abstract)) + { + TSharedPtr NewNodeAction(new FAssetSchemaAction_GenericGraph_NewNode(LOCTEXT("GenericGraphNodeAction", "Generic Graph Node"), Desc, AddToolTip, 0)); + NewNodeAction->NodeTemplate = NewObject(ContextMenuBuilder.OwnerOfTemporaries); + NewNodeAction->NodeTemplate->GenericGraphNode = NewObject(NewNodeAction->NodeTemplate, Graph->NodeType); + NewNodeAction->NodeTemplate->GenericGraphNode->Graph = Graph; + ContextMenuBuilder.AddAction(NewNodeAction); + + Visited.Add(Graph->NodeType); + } + + for (TObjectIterator It; It; ++It) + { + if (It->IsChildOf(Graph->NodeType) && !It->HasAnyClassFlags(CLASS_Abstract) && !Visited.Contains(*It)) + { + TSubclassOf NodeType = *It; + + if (It->GetName().StartsWith("REINST") || It->GetName().StartsWith("SKEL")) + continue; + + if (!Graph->GetClass()->IsChildOf(NodeType.GetDefaultObject()->CompatibleGraphType)) + continue; + + Desc = NodeType.GetDefaultObject()->ContextMenuName; + + if (Desc.IsEmpty()) + { + FString Title = NodeType->GetName(); + Title.RemoveFromEnd("_C"); + Desc = FText::FromString(Title); + } + + TSharedPtr Action(new FAssetSchemaAction_GenericGraph_NewNode(LOCTEXT("GenericGraphNodeAction", "Generic Graph Node"), Desc, AddToolTip, 0)); + Action->NodeTemplate = NewObject(ContextMenuBuilder.OwnerOfTemporaries); + Action->NodeTemplate->GenericGraphNode = NewObject(Action->NodeTemplate, NodeType); + Action->NodeTemplate->GenericGraphNode->Graph = Graph; + ContextMenuBuilder.AddAction(Action); + + Visited.Add(NodeType); + } + } +} + +void UAssetGraphSchema_GenericGraph::GetContextMenuActions(UToolMenu* Menu, UGraphNodeContextMenuContext* Context) const +{ + if (Context->Pin) + { + { + FToolMenuSection& Section = Menu->AddSection("GenericGraphAssetGraphSchemaNodeActions", LOCTEXT("PinActionsMenuHeader", "Pin Actions")); + // Only display the 'Break Links' option if there is a link to break! + if (Context->Pin->LinkedTo.Num() > 0) + { + Section.AddMenuEntry(FGraphEditorCommands::Get().BreakPinLinks); + + // add sub menu for break link to + if (Context->Pin->LinkedTo.Num() > 1) + { + Section.AddSubMenu( + "BreakLinkTo", + LOCTEXT("BreakLinkTo", "Break Link To..."), + LOCTEXT("BreakSpecificLinks", "Break a specific link..."), + FNewToolMenuDelegate::CreateUObject((UAssetGraphSchema_GenericGraph* const)this, &UAssetGraphSchema_GenericGraph::GetBreakLinkToSubMenuActions, const_cast(Context->Pin))); + } + else + { + ((UAssetGraphSchema_GenericGraph* const)this)->GetBreakLinkToSubMenuActions(Menu, const_cast(Context->Pin)); + } + } + } + } + else if (Context->Node) + { + { + FToolMenuSection& Section = Menu->AddSection("GenericGraphAssetGraphSchemaNodeActions", LOCTEXT("ClassActionsMenuHeader", "Node Actions")); + Section.AddMenuEntry(FGenericCommands::Get().Delete); + Section.AddMenuEntry(FGenericCommands::Get().Cut); + Section.AddMenuEntry(FGenericCommands::Get().Copy); + Section.AddMenuEntry(FGenericCommands::Get().Duplicate); + + Section.AddMenuEntry(FGraphEditorCommands::Get().BreakNodeLinks); + } + } + + Super::GetContextMenuActions(Menu, Context); +} + +const FPinConnectionResponse UAssetGraphSchema_GenericGraph::CanCreateConnection(const UEdGraphPin* A, const UEdGraphPin* B) const +{ + // Make sure the pins are not on the same node + if (A->GetOwningNode() == B->GetOwningNode()) + { + return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("PinErrorSameNode", "Can't connect node to itself")); + } + + const UEdGraphPin *Out = A; + const UEdGraphPin *In = B; + + UEdNode_GenericGraphNode* EdNode_Out = Cast(Out->GetOwningNode()); + UEdNode_GenericGraphNode* EdNode_In = Cast(In->GetOwningNode()); + + if (EdNode_Out == nullptr || EdNode_In == nullptr) + { + return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("PinError", "Not a valid UGenericGraphEdNode")); + } + + //Determine if we can have cycles or not + bool bAllowCycles = false; + auto EdGraph = Cast(Out->GetOwningNode()->GetGraph()); + if (EdGraph != nullptr) + { + bAllowCycles = EdGraph->GetGenericGraph()->bCanBeCyclical; + } + + // check for cycles + FNodeVisitorCycleChecker CycleChecker; + if (!bAllowCycles && !CycleChecker.CheckForLoop(Out->GetOwningNode(), In->GetOwningNode())) + { + return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("PinErrorCycle", "Can't create a graph cycle")); + } + + FText ErrorMessage; + if (!EdNode_Out->GenericGraphNode->CanCreateConnectionTo(EdNode_In->GenericGraphNode, EdNode_Out->GetOutputPin()->LinkedTo.Num(), ErrorMessage)) + { + return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, ErrorMessage); + } + if (!EdNode_In->GenericGraphNode->CanCreateConnectionFrom(EdNode_Out->GenericGraphNode, EdNode_In->GetInputPin()->LinkedTo.Num(), ErrorMessage)) + { + return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, ErrorMessage); + } + + + if (EdNode_Out->GenericGraphNode->GetGraph()->bEdgeEnabled) + { + return FPinConnectionResponse(CONNECT_RESPONSE_MAKE_WITH_CONVERSION_NODE, LOCTEXT("PinConnect", "Connect nodes with edge")); + } + else + { + return FPinConnectionResponse(CONNECT_RESPONSE_MAKE, LOCTEXT("PinConnect", "Connect nodes")); + } +} + +bool UAssetGraphSchema_GenericGraph::TryCreateConnection(UEdGraphPin* A, UEdGraphPin* B) const +{ + // We don't actually care about the pin, we want the node that is being dragged between + UEdNode_GenericGraphNode* NodeA = Cast(A->GetOwningNode()); + UEdNode_GenericGraphNode* NodeB = Cast(B->GetOwningNode()); + + // Check that this edge doesn't already exist + for (UEdGraphPin *TestPin : NodeA->GetOutputPin()->LinkedTo) + { + UEdGraphNode* ChildNode = TestPin->GetOwningNode(); + if (UEdNode_GenericGraphEdge* EdNode_Edge = Cast(ChildNode)) + { + ChildNode = EdNode_Edge->GetEndNode(); + } + + if (ChildNode == NodeB) + return false; + } + + if (NodeA && NodeB) + { + // Always create connections from node A to B, don't allow adding in reverse + Super::TryCreateConnection(NodeA->GetOutputPin(), NodeB->GetInputPin()); + return true; + } + else + { + return false; + } +} + +bool UAssetGraphSchema_GenericGraph::CreateAutomaticConversionNodeAndConnections(UEdGraphPin* A, UEdGraphPin* B) const +{ + UEdNode_GenericGraphNode* NodeA = Cast(A->GetOwningNode()); + UEdNode_GenericGraphNode* NodeB = Cast(B->GetOwningNode()); + + // Are nodes and pins all valid? + if (!NodeA || !NodeA->GetOutputPin() || !NodeB || !NodeB->GetInputPin()) + return false; + + UGenericGraph* Graph = NodeA->GenericGraphNode->GetGraph(); + + FVector2D InitPos((NodeA->NodePosX + NodeB->NodePosX) / 2, (NodeA->NodePosY + NodeB->NodePosY) / 2); + + FAssetSchemaAction_GenericGraph_NewEdge Action; + Action.NodeTemplate = NewObject(NodeA->GetGraph()); + Action.NodeTemplate->SetEdge(NewObject(Action.NodeTemplate, Graph->EdgeType)); + UEdNode_GenericGraphEdge* EdgeNode = Cast(Action.PerformAction(NodeA->GetGraph(), nullptr, InitPos, false)); + + // Always create connections from node A to B, don't allow adding in reverse + EdgeNode->CreateConnections(NodeA, NodeB); + + return true; +} + +class FConnectionDrawingPolicy* UAssetGraphSchema_GenericGraph::CreateConnectionDrawingPolicy(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, class FSlateWindowElementList& InDrawElements, class UEdGraph* InGraphObj) const +{ + return new FConnectionDrawingPolicy_GenericGraph(InBackLayerID, InFrontLayerID, InZoomFactor, InClippingRect, InDrawElements, InGraphObj); +} + +FLinearColor UAssetGraphSchema_GenericGraph::GetPinTypeColor(const FEdGraphPinType& PinType) const +{ + return FColor::White; +} + +void UAssetGraphSchema_GenericGraph::BreakNodeLinks(UEdGraphNode& TargetNode) const +{ + const FScopedTransaction Transaction(NSLOCTEXT("UnrealEd", "GraphEd_BreakNodeLinks", "Break Node Links")); + + Super::BreakNodeLinks(TargetNode); +} + +void UAssetGraphSchema_GenericGraph::BreakPinLinks(UEdGraphPin& TargetPin, bool bSendsNodeNotifcation) const +{ + const FScopedTransaction Transaction(NSLOCTEXT("UnrealEd", "GraphEd_BreakPinLinks", "Break Pin Links")); + + Super::BreakPinLinks(TargetPin, bSendsNodeNotifcation); +} + +void UAssetGraphSchema_GenericGraph::BreakSinglePinLink(UEdGraphPin* SourcePin, UEdGraphPin* TargetPin) const +{ + const FScopedTransaction Transaction(NSLOCTEXT("UnrealEd", "GraphEd_BreakSinglePinLink", "Break Pin Link")); + + Super::BreakSinglePinLink(SourcePin, TargetPin); +} + +UEdGraphPin* UAssetGraphSchema_GenericGraph::DropPinOnNode(UEdGraphNode* InTargetNode, const FName& InSourcePinName, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection) const +{ + UEdNode_GenericGraphNode* EdNode = Cast(InTargetNode); + switch (InSourcePinDirection) + { + case EGPD_Input: + return EdNode->GetOutputPin(); + case EGPD_Output: + return EdNode->GetInputPin(); + default: + return nullptr; + } +} + +bool UAssetGraphSchema_GenericGraph::SupportsDropPinOnNode(UEdGraphNode* InTargetNode, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection, FText& OutErrorMessage) const +{ + return Cast(InTargetNode) != nullptr; +} + +bool UAssetGraphSchema_GenericGraph::IsCacheVisualizationOutOfDate(int32 InVisualizationCacheID) const +{ + return CurrentCacheRefreshID != InVisualizationCacheID; +} + +int32 UAssetGraphSchema_GenericGraph::GetCurrentVisualizationCacheID() const +{ + return CurrentCacheRefreshID; +} + +void UAssetGraphSchema_GenericGraph::ForceVisualizationCacheClear() const +{ + ++CurrentCacheRefreshID; +} + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/ConnectionDrawingPolicy_GenericGraph.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/ConnectionDrawingPolicy_GenericGraph.cpp new file mode 100644 index 00000000..a727293d --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/ConnectionDrawingPolicy_GenericGraph.cpp @@ -0,0 +1,149 @@ +#include "GenericGraphAssetEditor/ConnectionDrawingPolicy_GenericGraph.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphNode.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphEdge.h" + +FConnectionDrawingPolicy_GenericGraph::FConnectionDrawingPolicy_GenericGraph(int32 InBackLayerID, int32 InFrontLayerID, float ZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements, UEdGraph* InGraphObj) + : FConnectionDrawingPolicy(InBackLayerID, InFrontLayerID, ZoomFactor, InClippingRect, InDrawElements) + , GraphObj(InGraphObj) +{ +} + +void FConnectionDrawingPolicy_GenericGraph::DetermineWiringStyle(UEdGraphPin* OutputPin, UEdGraphPin* InputPin, /*inout*/ FConnectionParams& Params) +{ + Params.AssociatedPin1 = OutputPin; + Params.AssociatedPin2 = InputPin; + Params.WireThickness = 1.5f; + + const bool bDeemphasizeUnhoveredPins = HoveredPins.Num() > 0; + if (bDeemphasizeUnhoveredPins) + { + ApplyHoverDeemphasis(OutputPin, InputPin, /*inout*/ Params.WireThickness, /*inout*/ Params.WireColor); + } +} + +void FConnectionDrawingPolicy_GenericGraph::Draw(TMap, FArrangedWidget>& InPinGeometries, FArrangedChildren& ArrangedNodes) +{ + // Build an acceleration structure to quickly find geometry for the nodes + NodeWidgetMap.Empty(); + for (int32 NodeIndex = 0; NodeIndex < ArrangedNodes.Num(); ++NodeIndex) + { + FArrangedWidget& CurWidget = ArrangedNodes[NodeIndex]; + TSharedRef ChildNode = StaticCastSharedRef(CurWidget.Widget); + NodeWidgetMap.Add(ChildNode->GetNodeObj(), NodeIndex); + } + + // Now draw + FConnectionDrawingPolicy::Draw(InPinGeometries, ArrangedNodes); +} + +void FConnectionDrawingPolicy_GenericGraph::DrawPreviewConnector(const FGeometry& PinGeometry, const FVector2D& StartPoint, const FVector2D& EndPoint, UEdGraphPin* Pin) +{ + FConnectionParams Params; + DetermineWiringStyle(Pin, nullptr, /*inout*/ Params); + + if (Pin->Direction == EEdGraphPinDirection::EGPD_Output) + { + DrawSplineWithArrow(FGeometryHelper::FindClosestPointOnGeom(PinGeometry, EndPoint), EndPoint, Params); + } + else + { + DrawSplineWithArrow(FGeometryHelper::FindClosestPointOnGeom(PinGeometry, StartPoint), StartPoint, Params); + } +} + +void FConnectionDrawingPolicy_GenericGraph::DrawSplineWithArrow(const FVector2D& StartAnchorPoint, const FVector2D& EndAnchorPoint, const FConnectionParams& Params) +{ + // bUserFlag1 indicates that we need to reverse the direction of connection (used by debugger) + const FVector2D& P0 = Params.bUserFlag1 ? EndAnchorPoint : StartAnchorPoint; + const FVector2D& P1 = Params.bUserFlag1 ? StartAnchorPoint : EndAnchorPoint; + + Internal_DrawLineWithArrow(P0, P1, Params); +} + +void FConnectionDrawingPolicy_GenericGraph::Internal_DrawLineWithArrow(const FVector2D& StartAnchorPoint, const FVector2D& EndAnchorPoint, const FConnectionParams& Params) +{ + //@TODO: Should this be scaled by zoom factor? + 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; + + // Draw a line/spline + DrawConnection(WireLayerID, StartPoint, EndPoint, Params); + + // Draw the arrow + const FVector2D ArrowDrawPos = EndPoint - ArrowRadius; + const float AngleInRadians = FMath::Atan2(DeltaPos.Y, DeltaPos.X); + + FSlateDrawElement::MakeRotatedBox( + DrawElementsList, + ArrowLayerID, + FPaintGeometry(ArrowDrawPos, ArrowImage->ImageSize * ZoomFactor, ZoomFactor), + ArrowImage, + ESlateDrawEffect::None, + AngleInRadians, + TOptional(), + FSlateDrawElement::RelativeToElement, + Params.WireColor + ); +} + +void FConnectionDrawingPolicy_GenericGraph::DrawSplineWithArrow(const FGeometry& StartGeom, const FGeometry& EndGeom, const FConnectionParams& Params) +{ + // Get a reasonable seed point (halfway between the boxes) + const FVector2D StartCenter = FGeometryHelper::CenterOf(StartGeom); + const FVector2D EndCenter = FGeometryHelper::CenterOf(EndGeom); + const FVector2D SeedPoint = (StartCenter + EndCenter) * 0.5f; + + // Find the (approximate) closest points between the two boxes + const FVector2D StartAnchorPoint = FGeometryHelper::FindClosestPointOnGeom(StartGeom, SeedPoint); + const FVector2D EndAnchorPoint = FGeometryHelper::FindClosestPointOnGeom(EndGeom, SeedPoint); + + DrawSplineWithArrow(StartAnchorPoint, EndAnchorPoint, Params); +} + +FVector2D FConnectionDrawingPolicy_GenericGraph::ComputeSplineTangent(const FVector2D& Start, const FVector2D& End) const +{ + const FVector2D Delta = End - Start; + const FVector2D NormDelta = Delta.GetSafeNormal(); + + return NormDelta; +} + +void FConnectionDrawingPolicy_GenericGraph::DetermineLinkGeometry(FArrangedChildren& ArrangedNodes, TSharedRef& OutputPinWidget, + UEdGraphPin* OutputPin, UEdGraphPin* InputPin, FArrangedWidget*& StartWidgetGeometry, FArrangedWidget*& EndWidgetGeometry) +{ + if (UEdNode_GenericGraphEdge* EdgeNode = Cast(InputPin->GetOwningNode())) + { + UEdNode_GenericGraphNode* Start = EdgeNode->GetStartNode(); + UEdNode_GenericGraphNode* End = EdgeNode->GetEndNode(); + if (Start != nullptr && End != nullptr) + { + int32* StartNodeIndex = NodeWidgetMap.Find(Start); + int32* EndNodeIndex = NodeWidgetMap.Find(End); + if (StartNodeIndex != nullptr && EndNodeIndex != nullptr) + { + StartWidgetGeometry = &(ArrangedNodes[*StartNodeIndex]); + EndWidgetGeometry = &(ArrangedNodes[*EndNodeIndex]); + } + } + } + else + { + StartWidgetGeometry = PinGeometries->Find(OutputPinWidget); + + if (TSharedPtr* pTargetWidget = PinToPinWidgetMap.Find(InputPin)) + { + TSharedRef InputWidget = (*pTargetWidget).ToSharedRef(); + EndWidgetGeometry = PinGeometries->Find(InputWidget); + } + } +} + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdGraph_GenericGraph.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdGraph_GenericGraph.cpp new file mode 100644 index 00000000..f730756f --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdGraph_GenericGraph.cpp @@ -0,0 +1,205 @@ +#include "GenericGraphAssetEditor/EdGraph_GenericGraph.h" +#include "GenericGraphEditorPCH.h" +#include "GenericGraph.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphNode.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphEdge.h" + +UEdGraph_GenericGraph::UEdGraph_GenericGraph() +{ + +} + +UEdGraph_GenericGraph::~UEdGraph_GenericGraph() +{ + +} + +void UEdGraph_GenericGraph::RebuildGenericGraph() +{ + LOG_INFO(TEXT("UGenericGraphEdGraph::RebuildGenericGraph has been called")); + + UGenericGraph* Graph = GetGenericGraph(); + + Clear(); + + for (int i = 0; i < Nodes.Num(); ++i) + { + if (UEdNode_GenericGraphNode* EdNode = Cast(Nodes[i])) + { + if (EdNode->GenericGraphNode == nullptr) + continue; + + UGenericGraphNode* GenericGraphNode = EdNode->GenericGraphNode; + + NodeMap.Add(GenericGraphNode, EdNode); + + Graph->AllNodes.Add(GenericGraphNode); + + for (int PinIdx = 0; PinIdx < EdNode->Pins.Num(); ++PinIdx) + { + UEdGraphPin* Pin = EdNode->Pins[PinIdx]; + + if (Pin->Direction != EEdGraphPinDirection::EGPD_Output) + continue; + + for (int LinkToIdx = 0; LinkToIdx < Pin->LinkedTo.Num(); ++LinkToIdx) + { + UGenericGraphNode* ChildNode = nullptr; + if (UEdNode_GenericGraphNode* EdNode_Child = Cast(Pin->LinkedTo[LinkToIdx]->GetOwningNode())) + { + ChildNode = EdNode_Child->GenericGraphNode; + } + else if (UEdNode_GenericGraphEdge* EdNode_Edge = Cast(Pin->LinkedTo[LinkToIdx]->GetOwningNode())) + { + UEdNode_GenericGraphNode* Child = EdNode_Edge->GetEndNode();; + if (Child != nullptr) + { + ChildNode = Child->GenericGraphNode; + } + } + + if (ChildNode != nullptr) + { + GenericGraphNode->ChildrenNodes.Add(ChildNode); + + ChildNode->ParentNodes.Add(GenericGraphNode); + } + else + { + LOG_ERROR(TEXT("UEdGraph_GenericGraph::RebuildGenericGraph can't find child node")); + } + } + } + } + else if (UEdNode_GenericGraphEdge* EdgeNode = Cast(Nodes[i])) + { + UEdNode_GenericGraphNode* StartNode = EdgeNode->GetStartNode(); + UEdNode_GenericGraphNode* EndNode = EdgeNode->GetEndNode(); + UGenericGraphEdge* Edge = EdgeNode->GenericGraphEdge; + + if (StartNode == nullptr || EndNode == nullptr || Edge == nullptr) + { + LOG_ERROR(TEXT("UEdGraph_GenericGraph::RebuildGenericGraph add edge failed.")); + continue; + } + + EdgeMap.Add(Edge, EdgeNode); + + Edge->Graph = Graph; + Edge->Rename(nullptr, Graph, REN_DontCreateRedirectors | REN_DoNotDirty); + Edge->StartNode = StartNode->GenericGraphNode; + Edge->EndNode = EndNode->GenericGraphNode; + Edge->StartNode->Edges.Add(Edge->EndNode, Edge); + } + } + + for (int i = 0; i < Graph->AllNodes.Num(); ++i) + { + UGenericGraphNode* Node = Graph->AllNodes[i]; + if (Node->ParentNodes.Num() == 0) + { + Graph->RootNodes.Add(Node); + + SortNodes(Node); + } + + Node->Graph = Graph; + Node->Rename(nullptr, Graph, REN_DontCreateRedirectors | REN_DoNotDirty); + } + + Graph->RootNodes.Sort([&](const UGenericGraphNode& L, const UGenericGraphNode& R) + { + UEdNode_GenericGraphNode* EdNode_LNode = NodeMap[&L]; + UEdNode_GenericGraphNode* EdNode_RNode = NodeMap[&R]; + return EdNode_LNode->NodePosX < EdNode_RNode->NodePosX; + }); +} + +UGenericGraph* UEdGraph_GenericGraph::GetGenericGraph() const +{ + return CastChecked(GetOuter()); +} + +bool UEdGraph_GenericGraph::Modify(bool bAlwaysMarkDirty /*= true*/) +{ + bool Rtn = Super::Modify(bAlwaysMarkDirty); + + GetGenericGraph()->Modify(); + + for (int32 i = 0; i < Nodes.Num(); ++i) + { + Nodes[i]->Modify(); + } + + return Rtn; +} + +void UEdGraph_GenericGraph::Clear() +{ + UGenericGraph* Graph = GetGenericGraph(); + + Graph->ClearGraph(); + NodeMap.Reset(); + EdgeMap.Reset(); + + for (int i = 0; i < Nodes.Num(); ++i) + { + if (UEdNode_GenericGraphNode* EdNode = Cast(Nodes[i])) + { + UGenericGraphNode* GenericGraphNode = EdNode->GenericGraphNode; + if (GenericGraphNode) + { + GenericGraphNode->ParentNodes.Reset(); + GenericGraphNode->ChildrenNodes.Reset(); + GenericGraphNode->Edges.Reset(); + } + } + } +} + +void UEdGraph_GenericGraph::SortNodes(UGenericGraphNode* RootNode) +{ + int Level = 0; + TArray CurrLevelNodes = { RootNode }; + TArray NextLevelNodes; + TSet Visited; + + while (CurrLevelNodes.Num() != 0) + { + int32 LevelWidth = 0; + for (int i = 0; i < CurrLevelNodes.Num(); ++i) + { + UGenericGraphNode* Node = CurrLevelNodes[i]; + Visited.Add(Node); + + auto Comp = [&](const UGenericGraphNode& L, const UGenericGraphNode& R) + { + UEdNode_GenericGraphNode* EdNode_LNode = NodeMap[&L]; + UEdNode_GenericGraphNode* EdNode_RNode = NodeMap[&R]; + return EdNode_LNode->NodePosX < EdNode_RNode->NodePosX; + }; + + Node->ChildrenNodes.Sort(Comp); + Node->ParentNodes.Sort(Comp); + + for (int j = 0; j < Node->ChildrenNodes.Num(); ++j) + { + UGenericGraphNode* ChildNode = Node->ChildrenNodes[j]; + if(!Visited.Contains(ChildNode)) + NextLevelNodes.Add(Node->ChildrenNodes[j]); + } + } + + CurrLevelNodes = NextLevelNodes; + NextLevelNodes.Reset(); + ++Level; + } +} + +void UEdGraph_GenericGraph::PostEditUndo() +{ + Super::PostEditUndo(); + + NotifyGraphChanged(); +} + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdNode_GenericGraphEdge.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdNode_GenericGraphEdge.cpp new file mode 100644 index 00000000..636ce9c4 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdNode_GenericGraphEdge.cpp @@ -0,0 +1,97 @@ +#include "GenericGraphAssetEditor/EdNode_GenericGraphEdge.h" +#include "GenericGraphEdge.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphNode.h" + +#define LOCTEXT_NAMESPACE "EdNode_GenericGraphEdge" + +UEdNode_GenericGraphEdge::UEdNode_GenericGraphEdge() +{ + bCanRenameNode = true; +} + +void UEdNode_GenericGraphEdge::SetEdge(UGenericGraphEdge* Edge) +{ + GenericGraphEdge = Edge; +} + +void UEdNode_GenericGraphEdge::AllocateDefaultPins() +{ + UEdGraphPin* Inputs = CreatePin(EGPD_Input, TEXT("Edge"), FName(), TEXT("In")); + Inputs->bHidden = true; + UEdGraphPin* Outputs = CreatePin(EGPD_Output, TEXT("Edge"), FName(), TEXT("Out")); + Outputs->bHidden = true; +} + +FText UEdNode_GenericGraphEdge::GetNodeTitle(ENodeTitleType::Type TitleType) const +{ + if (GenericGraphEdge) + { + return GenericGraphEdge->GetNodeTitle(); + } + return FText(); +} + +void UEdNode_GenericGraphEdge::PinConnectionListChanged(UEdGraphPin* Pin) +{ + if (Pin->LinkedTo.Num() == 0) + { + // Commit suicide; transitions must always have an input and output connection + Modify(); + + // Our parent graph will have our graph in SubGraphs so needs to be modified to record that. + if (UEdGraph* ParentGraph = GetGraph()) + { + ParentGraph->Modify(); + } + + DestroyNode(); + } +} + +void UEdNode_GenericGraphEdge::PrepareForCopying() +{ + GenericGraphEdge->Rename(nullptr, this, REN_DontCreateRedirectors | REN_DoNotDirty); +} + +void UEdNode_GenericGraphEdge::CreateConnections(UEdNode_GenericGraphNode* Start, UEdNode_GenericGraphNode* End) +{ + Pins[0]->Modify(); + Pins[0]->LinkedTo.Empty(); + + Start->GetOutputPin()->Modify(); + Pins[0]->MakeLinkTo(Start->GetOutputPin()); + + // This to next + Pins[1]->Modify(); + Pins[1]->LinkedTo.Empty(); + + End->GetInputPin()->Modify(); + Pins[1]->MakeLinkTo(End->GetInputPin()); +} + +UEdNode_GenericGraphNode* UEdNode_GenericGraphEdge::GetStartNode() +{ + if (Pins[0]->LinkedTo.Num() > 0) + { + return Cast(Pins[0]->LinkedTo[0]->GetOwningNode()); + } + else + { + return nullptr; + } +} + +UEdNode_GenericGraphNode* UEdNode_GenericGraphEdge::GetEndNode() +{ + if (Pins[1]->LinkedTo.Num() > 0) + { + return Cast(Pins[1]->LinkedTo[0]->GetOwningNode()); + } + else + { + return nullptr; + } +} + +#undef LOCTEXT_NAMESPACE + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdNode_GenericGraphNode.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdNode_GenericGraphNode.cpp new file mode 100644 index 00000000..9a487cf6 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EdNode_GenericGraphNode.cpp @@ -0,0 +1,84 @@ +#include "GenericGraphAssetEditor/EdNode_GenericGraphNode.h" +#include "GenericGraphAssetEditor/EdGraph_GenericGraph.h" +#include "Kismet2/Kismet2NameValidators.h" +#include "Kismet2/BlueprintEditorUtils.h" + +#define LOCTEXT_NAMESPACE "EdNode_GenericGraph" + +UEdNode_GenericGraphNode::UEdNode_GenericGraphNode() +{ + bCanRenameNode = true; +} + +UEdNode_GenericGraphNode::~UEdNode_GenericGraphNode() +{ + +} + +void UEdNode_GenericGraphNode::AllocateDefaultPins() +{ + CreatePin(EGPD_Input, "MultipleNodes", FName(), TEXT("In")); + CreatePin(EGPD_Output, "MultipleNodes", FName(), TEXT("Out")); +} + +UEdGraph_GenericGraph* UEdNode_GenericGraphNode::GetGenericGraphEdGraph() +{ + return Cast(GetGraph()); +} + +FText UEdNode_GenericGraphNode::GetNodeTitle(ENodeTitleType::Type TitleType) const +{ + if (GenericGraphNode == nullptr) + { + return Super::GetNodeTitle(TitleType); + } + else + { + return GenericGraphNode->GetNodeTitle(); + } +} + +void UEdNode_GenericGraphNode::PrepareForCopying() +{ + GenericGraphNode->Rename(nullptr, this, REN_DontCreateRedirectors | REN_DoNotDirty); +} + +void UEdNode_GenericGraphNode::AutowireNewNode(UEdGraphPin* FromPin) +{ + Super::AutowireNewNode(FromPin); + + if (FromPin != nullptr) + { + if (GetSchema()->TryCreateConnection(FromPin, GetInputPin())) + { + FromPin->GetOwningNode()->NodeConnectionListChanged(); + } + } +} + +void UEdNode_GenericGraphNode::SetGenericGraphNode(UGenericGraphNode* InNode) +{ + GenericGraphNode = InNode; +} + +FLinearColor UEdNode_GenericGraphNode::GetBackgroundColor() const +{ + return GenericGraphNode == nullptr ? FLinearColor::Black : GenericGraphNode->GetBackgroundColor(); +} + +UEdGraphPin* UEdNode_GenericGraphNode::GetInputPin() const +{ + return Pins[0]; +} + +UEdGraphPin* UEdNode_GenericGraphNode::GetOutputPin() const +{ + return Pins[1]; +} + +void UEdNode_GenericGraphNode::PostEditUndo() +{ + UEdGraphNode::PostEditUndo(); +} + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EditorCommands_GenericGraph.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EditorCommands_GenericGraph.cpp new file mode 100644 index 00000000..8cd338f5 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/EditorCommands_GenericGraph.cpp @@ -0,0 +1,11 @@ +#include "GenericGraphAssetEditor/EditorCommands_GenericGraph.h" + +#define LOCTEXT_NAMESPACE "EditorCommands_GenericGraph" + +void FEditorCommands_GenericGraph::RegisterCommands() +{ + UI_COMMAND(GraphSettings, "Graph Settings", "Graph Settings", EUserInterfaceActionType::Button, FInputChord()); + UI_COMMAND(AutoArrange, "Auto Arrange", "Auto Arrange", EUserInterfaceActionType::Button, FInputChord()); +} + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/GenericGraphDragConnection.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/GenericGraphDragConnection.cpp new file mode 100644 index 00000000..c8c3999d --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/GenericGraphDragConnection.cpp @@ -0,0 +1,325 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + + +#include "GenericGraphAssetEditor/GenericGraphDragConnection.h" +#include "Widgets/SBoxPanel.h" +#include "Framework/Application/SlateApplication.h" +#include "Widgets/Images/SImage.h" +#include "EdGraph/EdGraph.h" +#include "SGraphPanel.h" +#include "ScopedTransaction.h" + +TSharedRef FGenericGraphDragConnection::New(const TSharedRef& GraphPanel, const FDraggedPinTable& DraggedPins) +{ + TSharedRef Operation = MakeShareable(new FGenericGraphDragConnection(GraphPanel, DraggedPins)); + Operation->Construct(); + + return Operation; +} + +void FGenericGraphDragConnection::OnDrop(bool bDropWasHandled, const FPointerEvent& MouseEvent) +{ + GraphPanel->OnStopMakingConnection(); + + Super::OnDrop(bDropWasHandled, MouseEvent); +} + +void FGenericGraphDragConnection::OnDragged(const class FDragDropEvent& DragDropEvent) +{ + FVector2D TargetPosition = DragDropEvent.GetScreenSpacePosition(); + + // Reposition the info window wrt to the drag + CursorDecoratorWindow->MoveWindowTo(DragDropEvent.GetScreenSpacePosition() + DecoratorAdjust); + // Request the active panel to scroll if required + GraphPanel->RequestDeferredPan(TargetPosition); +} + +void FGenericGraphDragConnection::HoverTargetChanged() +{ + TArray UniqueMessages; + + if (UEdGraphPin* TargetPinObj = GetHoveredPin()) + { + TArray ValidSourcePins; + ValidateGraphPinList(/*out*/ ValidSourcePins); + + // Check the schema for connection responses + for (UEdGraphPin* StartingPinObj : ValidSourcePins) + { + // The Graph object in which the pins reside. + UEdGraph* GraphObj = StartingPinObj->GetOwningNode()->GetGraph(); + + // Determine what the schema thinks about the wiring action + const FPinConnectionResponse Response = GraphObj->GetSchema()->CanCreateConnection(StartingPinObj, TargetPinObj); + + if (Response.Response == ECanCreateConnectionResponse::CONNECT_RESPONSE_DISALLOW) + { + TSharedPtr NodeWidget = TargetPinObj->GetOwningNode()->DEPRECATED_NodeWidget.Pin(); + if (NodeWidget.IsValid()) + { + NodeWidget->NotifyDisallowedPinConnection(StartingPinObj, TargetPinObj); + } + } + + UniqueMessages.AddUnique(Response); + } + } + else if (UEdNode_GenericGraphNode* TargetNodeObj = Cast(GetHoveredNode())) + { + TArray ValidSourcePins; + ValidateGraphPinList(/*out*/ ValidSourcePins); + + // Check the schema for connection responses + for (UEdGraphPin* StartingPinObj : ValidSourcePins) + { + FPinConnectionResponse Response; + FText ResponseText; + + const UEdGraphSchema *Schema = StartingPinObj->GetSchema(); + UEdGraphPin *TargetPin = TargetNodeObj->GetInputPin(); + + if (Schema && TargetPin) + { + Response = Schema->CanCreateConnection(StartingPinObj, TargetPin); + if (Response.Response == ECanCreateConnectionResponse::CONNECT_RESPONSE_DISALLOW) + { + TSharedPtr NodeWidget = TargetPin->GetOwningNode()->DEPRECATED_NodeWidget.Pin(); + if (NodeWidget.IsValid()) + { + NodeWidget->NotifyDisallowedPinConnection(StartingPinObj, TargetPinObj); + } + } + } + else + { +#define LOCTEXT_NAMESPACE "AssetSchema_GenericGraph" + Response = FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("PinError", "Not a valid UGenericGraphEdNode")); +#undef LOCTEXT_NAMESPACE + } + + UniqueMessages.AddUnique(Response); + } + } + else if (UEdGraph* CurrentHoveredGraph = GetHoveredGraph()) + { + TArray ValidSourcePins; + ValidateGraphPinList(/*out*/ ValidSourcePins); + + for (UEdGraphPin* StartingPinObj : ValidSourcePins) + { + // Let the schema describe the connection we might make + FPinConnectionResponse Response = CurrentHoveredGraph->GetSchema()->CanCreateNewNodes(StartingPinObj); + if (!Response.Message.IsEmpty()) + { + UniqueMessages.AddUnique(Response); + } + } + } + + // Let the user know the status of dropping now + if (UniqueMessages.Num() == 0) + { + // Display the place a new node icon, we're not over a valid pin and have no message from the schema + SetSimpleFeedbackMessage( + FAppStyle::GetBrush(TEXT("Graph.ConnectorFeedback.NewNode")), + FLinearColor::White, + NSLOCTEXT("GraphEditor.Feedback", "PlaceNewNode", "Place a new node.")); + } + else + { + // Take the unique responses and create visual feedback for it + TSharedRef FeedbackBox = SNew(SVerticalBox); + for (auto ResponseIt = UniqueMessages.CreateConstIterator(); ResponseIt; ++ResponseIt) + { + // Determine the icon + const FSlateBrush* StatusSymbol = NULL; + + switch (ResponseIt->Response) + { + case CONNECT_RESPONSE_MAKE: + case CONNECT_RESPONSE_BREAK_OTHERS_A: + case CONNECT_RESPONSE_BREAK_OTHERS_B: + case CONNECT_RESPONSE_BREAK_OTHERS_AB: + StatusSymbol = FAppStyle::GetBrush(TEXT("Graph.ConnectorFeedback.OK")); + break; + + case CONNECT_RESPONSE_MAKE_WITH_CONVERSION_NODE: + StatusSymbol = FAppStyle::GetBrush(TEXT("Graph.ConnectorFeedback.ViaCast")); + break; + + case CONNECT_RESPONSE_DISALLOW: + default: + StatusSymbol = FAppStyle::GetBrush(TEXT("Graph.ConnectorFeedback.Error")); + break; + } + + // Add a new message row + FeedbackBox->AddSlot() + .AutoHeight() + [ + SNew(SHorizontalBox) + + SHorizontalBox::Slot() + .AutoWidth() + .Padding(3.0f) + .VAlign(VAlign_Center) + [ + SNew(SImage).Image(StatusSymbol) + ] + + SHorizontalBox::Slot() + .AutoWidth() + .VAlign(VAlign_Center) + [ + SNew(STextBlock).Text(ResponseIt->Message) + ] + ]; + } + + SetFeedbackMessage(FeedbackBox); + } +} + +FGenericGraphDragConnection::FGenericGraphDragConnection(const TSharedRef& GraphPanelIn, const FDraggedPinTable& DraggedPinsIn) + : GraphPanel(GraphPanelIn) + , DraggingPins(DraggedPinsIn) + , DecoratorAdjust(FSlateApplication::Get().GetCursorSize()) +{ + if (DraggingPins.Num() > 0) + { + const UEdGraphPin* PinObj = FDraggedPinTable::TConstIterator(DraggedPinsIn)->GetPinObj(*GraphPanelIn); + if (PinObj && PinObj->Direction == EGPD_Input) + { + DecoratorAdjust *= FVector2D(-1.0f, 1.0f); + } + } + + for (const FGraphPinHandle& DraggedPin : DraggedPinsIn) + { + GraphPanelIn->OnBeginMakingConnection(DraggedPin); + } +} + +FReply FGenericGraphDragConnection::DroppedOnPin(FVector2D ScreenPosition, FVector2D GraphPosition) +{ + TArray ValidSourcePins; + ValidateGraphPinList(/*out*/ ValidSourcePins); + + const FScopedTransaction Transaction(NSLOCTEXT("UnrealEd", "GraphEd_CreateConnection", "Create Pin Link")); + + UEdGraphPin* PinB = GetHoveredPin(); + bool bError = false; + TSet NodeList; + + for (UEdGraphPin* PinA : ValidSourcePins) + { + if ((PinA != NULL) && (PinB != NULL)) + { + UEdGraph* MyGraphObj = PinA->GetOwningNode()->GetGraph(); + + if (MyGraphObj->GetSchema()->TryCreateConnection(PinA, PinB)) + { + if (!PinA->IsPendingKill()) + { + NodeList.Add(PinA->GetOwningNode()); + } + if (!PinB->IsPendingKill()) + { + NodeList.Add(PinB->GetOwningNode()); + } + } + } + else + { + bError = true; + } + } + + // Send all nodes that received a new pin connection a notification + for (auto It = NodeList.CreateConstIterator(); It; ++It) + { + UEdGraphNode* Node = (*It); + Node->NodeConnectionListChanged(); + } + + if (bError) + { + return FReply::Unhandled(); + } + + return FReply::Handled(); +} + +FReply FGenericGraphDragConnection::DroppedOnNode(FVector2D ScreenPosition, FVector2D GraphPosition) +{ + bool bHandledPinDropOnNode = false; + UEdGraphNode* NodeOver = GetHoveredNode(); + + if (NodeOver) + { + // Gather any source drag pins + TArray ValidSourcePins; + ValidateGraphPinList(/*out*/ ValidSourcePins); + + if (ValidSourcePins.Num()) + { + for (UEdGraphPin* SourcePin : ValidSourcePins) + { + // Check for pin drop support + FText ResponseText; + if (SourcePin->GetOwningNode() != NodeOver && SourcePin->GetSchema()->SupportsDropPinOnNode(NodeOver, SourcePin->PinType, SourcePin->Direction, ResponseText)) + { + bHandledPinDropOnNode = true; + + // Find which pin name to use and drop the pin on the node + const FName PinName = SourcePin->PinFriendlyName.IsEmpty() ? SourcePin->PinName : *SourcePin->PinFriendlyName.ToString(); + + const FScopedTransaction Transaction((SourcePin->Direction == EGPD_Output) ? NSLOCTEXT("UnrealEd", "AddInParam", "Add In Parameter") : NSLOCTEXT("UnrealEd", "AddOutParam", "Add Out Parameter")); + + UEdGraphPin* EdGraphPin = NodeOver->GetSchema()->DropPinOnNode(GetHoveredNode(), PinName, SourcePin->PinType, SourcePin->Direction); + + // This can invalidate the source pin due to node reconstruction, abort in that case + if (SourcePin->GetOwningNodeUnchecked() && EdGraphPin) + { + SourcePin->Modify(); + EdGraphPin->Modify(); + SourcePin->GetSchema()->TryCreateConnection(SourcePin, EdGraphPin); + } + } + + // If we have not handled the pin drop on node and there is an error message, do not let other actions occur. + if (!bHandledPinDropOnNode && !ResponseText.IsEmpty()) + { + bHandledPinDropOnNode = true; + } + } + } + } + return bHandledPinDropOnNode ? FReply::Handled() : FReply::Unhandled(); +} + +FReply FGenericGraphDragConnection::DroppedOnPanel(const TSharedRef< SWidget >& Panel, FVector2D ScreenPosition, FVector2D GraphPosition, UEdGraph& Graph) +{ + // Gather any source drag pins + TArray PinObjects; + ValidateGraphPinList(/*out*/ PinObjects); + + // Create a context menu + TSharedPtr WidgetToFocus = GraphPanel->SummonContextMenu(ScreenPosition, GraphPosition, NULL, NULL, PinObjects); + + // Give the context menu focus + return (WidgetToFocus.IsValid()) + ? FReply::Handled().SetUserFocus(WidgetToFocus.ToSharedRef(), EFocusCause::SetDirectly) + : FReply::Handled(); +} + + +void FGenericGraphDragConnection::ValidateGraphPinList(TArray& OutValidPins) +{ + OutValidPins.Empty(DraggingPins.Num()); + for (const FGraphPinHandle& PinHandle : DraggingPins) + { + if (UEdGraphPin* GraphPin = PinHandle.GetPinObj(*GraphPanel)) + { + OutValidPins.Add(GraphPin); + } + } +} diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/GenericGraphEditorStyle.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/GenericGraphEditorStyle.cpp new file mode 100644 index 00000000..6870128f --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/GenericGraphEditorStyle.cpp @@ -0,0 +1,54 @@ +#include "GenericGraphAssetEditor/GenericGraphEditorStyle.h" +#include "Styling/SlateStyleRegistry.h" +#include "Styling/SlateTypes.h" +#include "Misc/Paths.h" + +TSharedPtr FGenericGraphEditorStyle::StyleSet = nullptr; + +#define IMAGE_BRUSH( RelativePath, ... ) FSlateImageBrush( StyleSet->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) +#define BOX_BRUSH( RelativePath, ... ) FSlateBoxBrush( StyleSet->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) +#define BORDER_BRUSH( RelativePath, ... ) FSlateBorderBrush( StyleSet->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) +#define TTF_FONT( RelativePath, ... ) FSlateFontInfo( StyleSet->RootToContentDir( RelativePath, TEXT(".ttf") ), __VA_ARGS__ ) +#define OTF_FONT( RelativePath, ... ) FSlateFontInfo( StyleSet->RootToContentDir( RelativePath, TEXT(".otf") ), __VA_ARGS__ ) + +void FGenericGraphEditorStyle::Initialize() +{ + const FVector2D Icon20x20(20.0f, 20.0f); + const FVector2D Icon40x40(40.0f, 40.0f); + const FVector2D Icon64x64(64.0f, 64.0f); + + if (StyleSet.IsValid()) + { + return; + } + + StyleSet = MakeShareable(new FSlateStyleSet("GenericGraphEditorStyle")); + + StyleSet->SetContentRoot(FPaths::ProjectPluginsDir() / TEXT("GenericGraph/Resources")); + + StyleSet->Set("GenericGraphEditor.AutoArrange", new IMAGE_BRUSH("AutoArrangeIcon", Icon40x40)); + StyleSet->Set("GenericGraphEditor.AutoArrange.Small", new IMAGE_BRUSH( "AutoArrangeIcon", Icon20x20 ) ); + + FSlateStyleRegistry::RegisterSlateStyle(*StyleSet.Get()); +} + +void FGenericGraphEditorStyle::Shutdown() +{ + if (StyleSet.IsValid()) + { + FSlateStyleRegistry::UnRegisterSlateStyle(*StyleSet.Get()); + ensure(StyleSet.IsUnique()); + StyleSet.Reset(); + } +} + +const FName& FGenericGraphEditorStyle::GetStyleSetName() +{ + return StyleSet->GetStyleSetName(); +} + +#undef IMAGE_BRUSH +#undef BOX_BRUSH +#undef BORDER_BRUSH +#undef TTF_FONT +#undef OTF_FONT diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/SEdNode_GenericGraphEdge.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/SEdNode_GenericGraphEdge.cpp new file mode 100644 index 00000000..d46b0777 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/SEdNode_GenericGraphEdge.cpp @@ -0,0 +1,199 @@ +#include "GenericGraphAssetEditor/SEdNode_GenericGraphEdge.h" +#include "Widgets/SBoxPanel.h" +#include "Widgets/Images/SImage.h" +#include "Widgets/Text/SInlineEditableTextBlock.h" +#include "Widgets/SToolTip.h" +#include "SGraphPanel.h" +#include "EdGraphSchema_K2.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphNode.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphEdge.h" +#include "GenericGraphAssetEditor/ConnectionDrawingPolicy_GenericGraph.h" + +#define LOCTEXT_NAMESPACE "SGenericGraphEdge" + +void SEdNode_GenericGraphEdge::Construct(const FArguments& InArgs, UEdNode_GenericGraphEdge* InNode) +{ + this->GraphNode = InNode; + this->UpdateGraphNode(); +} + +bool SEdNode_GenericGraphEdge::RequiresSecondPassLayout() const +{ + return true; +} + +void SEdNode_GenericGraphEdge::PerformSecondPassLayout(const TMap< UObject*, TSharedRef >& NodeToWidgetLookup) const +{ + UEdNode_GenericGraphEdge* EdgeNode = CastChecked(GraphNode); + + FGeometry StartGeom; + FGeometry EndGeom; + + UEdNode_GenericGraphNode* Start = EdgeNode->GetStartNode(); + UEdNode_GenericGraphNode* End = EdgeNode->GetEndNode(); + if (Start != nullptr && End != nullptr) + { + const TSharedRef* pFromWidget = NodeToWidgetLookup.Find(Start); + const TSharedRef* pToWidget = NodeToWidgetLookup.Find(End); + if (pFromWidget != nullptr && pToWidget != nullptr) + { + const TSharedRef& FromWidget = *pFromWidget; + const TSharedRef& ToWidget = *pToWidget; + + StartGeom = FGeometry(FVector2D(Start->NodePosX, Start->NodePosY), FVector2D::ZeroVector, FromWidget->GetDesiredSize(), 1.0f); + EndGeom = FGeometry(FVector2D(End->NodePosX, End->NodePosY), FVector2D::ZeroVector, ToWidget->GetDesiredSize(), 1.0f); + } + } + + PositionBetweenTwoNodesWithOffset(StartGeom, EndGeom, 0, 1); +} + +void SEdNode_GenericGraphEdge::OnNameTextCommited(const FText& InText, ETextCommit::Type CommitInfo) +{ + SGraphNode::OnNameTextCommited(InText, CommitInfo); + + UEdNode_GenericGraphEdge* MyNode = CastChecked(GraphNode); + + if (MyNode != nullptr && MyNode->GenericGraphEdge != nullptr) + { + const FScopedTransaction Transaction(LOCTEXT("GenericGraphEditorRenameEdge", "Generic Graph Editor: Rename Edge")); + MyNode->Modify(); + MyNode->GenericGraphEdge->SetNodeTitle(InText); + UpdateGraphNode(); + } +} + +void SEdNode_GenericGraphEdge::UpdateGraphNode() +{ + InputPins.Empty(); + OutputPins.Empty(); + + RightNodeBox.Reset(); + LeftNodeBox.Reset(); + + TSharedPtr NodeTitle = SNew(SNodeTitle, GraphNode); + + this->ContentScale.Bind( this, &SGraphNode::GetContentScale ); + this->GetOrAddSlot( ENodeZone::Center ) + .HAlign(HAlign_Center) + .VAlign(VAlign_Center) + [ + SNew(SOverlay) + + SOverlay::Slot() + [ + SNew(SImage) + .Image(FAppStyle::GetBrush("Graph.TransitionNode.ColorSpill")) + .ColorAndOpacity(this, &SEdNode_GenericGraphEdge::GetEdgeColor) + ] + + SOverlay::Slot() + [ + SNew(SImage) + .Image(this, &SEdNode_GenericGraphEdge::GetEdgeImage) + .Visibility(this, &SEdNode_GenericGraphEdge::GetEdgeImageVisibility) + ] + + + SOverlay::Slot() + .Padding(FMargin(4.0f, 4.0f, 4.0f, 4.0f)) + [ + SNew(SVerticalBox) + + SVerticalBox::Slot() + .HAlign(HAlign_Center) + .AutoHeight() + [ + SAssignNew(InlineEditableText, SInlineEditableTextBlock) + .ColorAndOpacity(FLinearColor::Black) + .Visibility(this, &SEdNode_GenericGraphEdge::GetEdgeTitleVisbility) + .Font(FCoreStyle::GetDefaultFontStyle("Regular", 12)) + .Text(NodeTitle.Get(), &SNodeTitle::GetHeadTitle) + .OnTextCommitted(this, &SEdNode_GenericGraphEdge::OnNameTextCommited) + ] + + SVerticalBox::Slot() + .AutoHeight() + [ + NodeTitle.ToSharedRef() + ] + + ] + ]; +} + +void SEdNode_GenericGraphEdge::PositionBetweenTwoNodesWithOffset(const FGeometry& StartGeom, const FGeometry& EndGeom, int32 NodeIndex, int32 MaxNodes) const +{ + // Get a reasonable seed point (halfway between the boxes) + const FVector2D StartCenter = FGeometryHelper::CenterOf(StartGeom); + const FVector2D EndCenter = FGeometryHelper::CenterOf(EndGeom); + const FVector2D SeedPoint = (StartCenter + EndCenter) * 0.5f; + + // Find the (approximate) closest points between the two boxes + const FVector2D StartAnchorPoint = FGeometryHelper::FindClosestPointOnGeom(StartGeom, SeedPoint); + const FVector2D EndAnchorPoint = FGeometryHelper::FindClosestPointOnGeom(EndGeom, SeedPoint); + + // Position ourselves halfway along the connecting line between the nodes, elevated away perpendicular to the direction of the line + const float Height = 30.0f; + + const FVector2D DesiredNodeSize = GetDesiredSize(); + + FVector2D DeltaPos(EndAnchorPoint - StartAnchorPoint); + + if (DeltaPos.IsNearlyZero()) + { + DeltaPos = FVector2D(10.0f, 0.0f); + } + + const FVector2D Normal = FVector2D(DeltaPos.Y, -DeltaPos.X).GetSafeNormal(); + + const FVector2D NewCenter = StartAnchorPoint + (0.5f * DeltaPos) + (Height * Normal); + + FVector2D DeltaNormal = DeltaPos.GetSafeNormal(); + + // Calculate node offset in the case of multiple transitions between the same two nodes + // MultiNodeOffset: the offset where 0 is the centre of the transition, -1 is 1 + // towards the PrevStateNode and +1 is 1 towards the NextStateNode. + + const float MutliNodeSpace = 0.2f; // Space between multiple transition nodes (in units of ) + const float MultiNodeStep = (1.f + MutliNodeSpace); //Step between node centres (Size of node + size of node spacer) + + const float MultiNodeStart = -((MaxNodes - 1) * MultiNodeStep) / 2.f; + const float MultiNodeOffset = MultiNodeStart + (NodeIndex * MultiNodeStep); + + // Now we need to adjust the new center by the node size, zoom factor and multi node offset + const FVector2D NewCorner = NewCenter - (0.5f * DesiredNodeSize) + (DeltaNormal * MultiNodeOffset * DesiredNodeSize.Size()); + + GraphNode->NodePosX = NewCorner.X; + GraphNode->NodePosY = NewCorner.Y; +} + +FSlateColor SEdNode_GenericGraphEdge::GetEdgeColor() const +{ + UEdNode_GenericGraphEdge* EdgeNode = CastChecked(GraphNode); + if (EdgeNode != nullptr && EdgeNode->GenericGraphEdge != nullptr) + { + return EdgeNode->GenericGraphEdge->GetEdgeColour(); + } + return FLinearColor(0.9f, 0.9f, 0.9f, 1.0f); +} + +const FSlateBrush* SEdNode_GenericGraphEdge::GetEdgeImage() const +{ + return FAppStyle::GetBrush("Graph.TransitionNode.Icon"); +} + +EVisibility SEdNode_GenericGraphEdge::GetEdgeImageVisibility() const +{ + UEdNode_GenericGraphEdge* EdgeNode = CastChecked(GraphNode); + if (EdgeNode && EdgeNode->GenericGraphEdge && EdgeNode->GenericGraphEdge->bShouldDrawTitle) + return EVisibility::Hidden; + + return EVisibility::Visible; +} + +EVisibility SEdNode_GenericGraphEdge::GetEdgeTitleVisbility() const +{ + UEdNode_GenericGraphEdge* EdgeNode = CastChecked(GraphNode); + if (EdgeNode && EdgeNode->GenericGraphEdge && EdgeNode->GenericGraphEdge->bShouldDrawTitle) + return EVisibility::Visible; + + return EVisibility::Collapsed; +} + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/SEdNode_GenericGraphNode.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/SEdNode_GenericGraphNode.cpp new file mode 100644 index 00000000..d69e7eea --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/SEdNode_GenericGraphNode.cpp @@ -0,0 +1,336 @@ +#include "GenericGraphAssetEditor/SEdNode_GenericGraphNode.h" +#include "GenericGraphEditorPCH.h" +#include "GenericGraphAssetEditor/Colors_GenericGraph.h" +#include "SLevelOfDetailBranchNode.h" +#include "Widgets/Text/SInlineEditableTextBlock.h" +#include "SCommentBubble.h" +#include "SlateOptMacros.h" +#include "SGraphPin.h" +#include "GraphEditorSettings.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphNode.h" +#include "GenericGraphAssetEditor/GenericGraphDragConnection.h" + +#define LOCTEXT_NAMESPACE "EdNode_GenericGraph" + +////////////////////////////////////////////////////////////////////////// +class SGenericGraphPin : public SGraphPin +{ +public: + SLATE_BEGIN_ARGS(SGenericGraphPin) {} + SLATE_END_ARGS() + + void Construct(const FArguments& InArgs, UEdGraphPin* InPin) + { + this->SetCursor(EMouseCursor::Default); + + bShowLabel = true; + + GraphPinObj = InPin; + check(GraphPinObj != nullptr); + + const UEdGraphSchema* Schema = GraphPinObj->GetSchema(); + check(Schema); + + SBorder::Construct(SBorder::FArguments() + .BorderImage(this, &SGenericGraphPin::GetPinBorder) + .BorderBackgroundColor(this, &SGenericGraphPin::GetPinColor) + .OnMouseButtonDown(this, &SGenericGraphPin::OnPinMouseDown) + .Cursor(this, &SGenericGraphPin::GetPinCursor) + .Padding(FMargin(5.0f)) + ); + } + +protected: + virtual FSlateColor GetPinColor() const override + { + return GenericGraphColors::Pin::Default; + } + + virtual TSharedRef GetDefaultValueWidget() override + { + return SNew(STextBlock); + } + + const FSlateBrush* GetPinBorder() const + { + return FAppStyle::GetBrush(TEXT("Graph.StateNode.Body")); + } + + virtual TSharedRef SpawnPinDragEvent(const TSharedRef& InGraphPanel, const TArray< TSharedRef >& InStartingPins) override + { + FGenericGraphDragConnection::FDraggedPinTable PinHandles; + PinHandles.Reserve(InStartingPins.Num()); + // since the graph can be refreshed and pins can be reconstructed/replaced + // behind the scenes, the DragDropOperation holds onto FGraphPinHandles + // instead of direct widgets/graph-pins + for (const TSharedRef& PinWidget : InStartingPins) + { + PinHandles.Add(PinWidget->GetPinObj()); + } + + return FGenericGraphDragConnection::New(InGraphPanel, PinHandles); + } + +}; + + +////////////////////////////////////////////////////////////////////////// +void SEdNode_GenericGraphNode::Construct(const FArguments& InArgs, UEdNode_GenericGraphNode* InNode) +{ + GraphNode = InNode; + UpdateGraphNode(); + InNode->SEdNode = this; +} + +BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION +void SEdNode_GenericGraphNode::UpdateGraphNode() +{ + const FMargin NodePadding = FMargin(5); + const FMargin NamePadding = FMargin(2); + + InputPins.Empty(); + OutputPins.Empty(); + + // Reset variables that are going to be exposed, in case we are refreshing an already setup node. + RightNodeBox.Reset(); + LeftNodeBox.Reset(); + + const FSlateBrush *NodeTypeIcon = GetNameIcon(); + + FLinearColor TitleShadowColor(0.6f, 0.6f, 0.6f); + TSharedPtr ErrorText; + TSharedPtr NodeBody; + TSharedPtr NodeTitle = SNew(SNodeTitle, GraphNode); + + this->ContentScale.Bind(this, &SGraphNode::GetContentScale); + this->GetOrAddSlot(ENodeZone::Center) + .HAlign(HAlign_Fill) + .VAlign(VAlign_Center) + [ + SNew(SBorder) + .BorderImage(FAppStyle::GetBrush("Graph.StateNode.Body")) + .Padding(0.0f) + .BorderBackgroundColor(this, &SEdNode_GenericGraphNode::GetBorderBackgroundColor) + [ + SNew(SOverlay) + + + SOverlay::Slot() + .HAlign(HAlign_Fill) + .VAlign(VAlign_Fill) + [ + SNew(SVerticalBox) + + // Input Pin Area + + SVerticalBox::Slot() + .FillHeight(1) + [ + SAssignNew(LeftNodeBox, SVerticalBox) + ] + + // Output Pin Area + + SVerticalBox::Slot() + .FillHeight(1) + [ + SAssignNew(RightNodeBox, SVerticalBox) + ] + ] + + + SOverlay::Slot() + .HAlign(HAlign_Center) + .VAlign(VAlign_Center) + .Padding(8.0f) + [ + SNew(SBorder) + .BorderImage(FAppStyle::GetBrush("Graph.StateNode.ColorSpill")) + .BorderBackgroundColor(TitleShadowColor) + .HAlign(HAlign_Center) + .VAlign(VAlign_Center) + .Visibility(EVisibility::SelfHitTestInvisible) + .Padding(6.0f) + [ + SAssignNew(NodeBody, SVerticalBox) + + // Title + + SVerticalBox::Slot() + .AutoHeight() + [ + SNew(SHorizontalBox) + + // Error message + + SHorizontalBox::Slot() + .AutoWidth() + [ + SAssignNew(ErrorText, SErrorText) + .BackgroundColor(this, &SEdNode_GenericGraphNode::GetErrorColor) + .ToolTipText(this, &SEdNode_GenericGraphNode::GetErrorMsgToolTip) + ] + + // Icon + +SHorizontalBox::Slot() + .AutoWidth() + .VAlign(VAlign_Center) + [ + SNew(SImage) + .Image(NodeTypeIcon) + ] + + // Node Title + + SHorizontalBox::Slot() + .Padding(FMargin(4.0f, 0.0f, 4.0f, 0.0f)) + [ + SNew(SVerticalBox) + + SVerticalBox::Slot() + .AutoHeight() + [ + SAssignNew(InlineEditableText, SInlineEditableTextBlock) + .Style(FAppStyle::Get(), "Graph.StateNode.NodeTitleInlineEditableText") + .Text(NodeTitle.Get(), &SNodeTitle::GetHeadTitle) + .OnVerifyTextChanged(this, &SEdNode_GenericGraphNode::OnVerifyNameTextChanged) + .OnTextCommitted(this, &SEdNode_GenericGraphNode::OnNameTextCommited) + .IsReadOnly(this, &SEdNode_GenericGraphNode::IsNameReadOnly) + .IsSelected(this, &SEdNode_GenericGraphNode::IsSelectedExclusively) + ] + + SVerticalBox::Slot() + .AutoHeight() + [ + NodeTitle.ToSharedRef() + ] + ] + ] + ] + ] + ] + ]; + + // Create comment bubble + TSharedPtr CommentBubble; + const FSlateColor CommentColor = GetDefault()->DefaultCommentNodeTitleColor; + + SAssignNew(CommentBubble, SCommentBubble) + .GraphNode(GraphNode) + .Text(this, &SGraphNode::GetNodeComment) + .OnTextCommitted(this, &SGraphNode::OnCommentTextCommitted) + .ColorAndOpacity(CommentColor) + .AllowPinning(true) + .EnableTitleBarBubble(true) + .EnableBubbleCtrls(true) + .GraphLOD(this, &SGraphNode::GetCurrentLOD) + .IsGraphNodeHovered(this, &SGraphNode::IsHovered); + + GetOrAddSlot(ENodeZone::TopCenter) + .SlotOffset(TAttribute(CommentBubble.Get(), &SCommentBubble::GetOffset)) + .SlotSize(TAttribute(CommentBubble.Get(), &SCommentBubble::GetSize)) + .AllowScaling(TAttribute(CommentBubble.Get(), &SCommentBubble::IsScalingAllowed)) + .VAlign(VAlign_Top) + [ + CommentBubble.ToSharedRef() + ]; + + ErrorReporting = ErrorText; + ErrorReporting->SetError(ErrorMsg); + CreatePinWidgets(); +} + +void SEdNode_GenericGraphNode::CreatePinWidgets() +{ + UEdNode_GenericGraphNode* StateNode = CastChecked(GraphNode); + + for (int32 PinIdx = 0; PinIdx < StateNode->Pins.Num(); PinIdx++) + { + UEdGraphPin* MyPin = StateNode->Pins[PinIdx]; + if (!MyPin->bHidden) + { + TSharedPtr NewPin = SNew(SGenericGraphPin, MyPin); + + AddPin(NewPin.ToSharedRef()); + } + } +} + +void SEdNode_GenericGraphNode::AddPin(const TSharedRef& PinToAdd) +{ + PinToAdd->SetOwner(SharedThis(this)); + + const UEdGraphPin* PinObj = PinToAdd->GetPinObj(); + const bool bAdvancedParameter = PinObj && PinObj->bAdvancedView; + if (bAdvancedParameter) + { + PinToAdd->SetVisibility( TAttribute(PinToAdd, &SGraphPin::IsPinVisibleAsAdvanced) ); + } + + TSharedPtr PinBox; + if (PinToAdd->GetDirection() == EEdGraphPinDirection::EGPD_Input) + { + PinBox = LeftNodeBox; + InputPins.Add(PinToAdd); + } + else // Direction == EEdGraphPinDirection::EGPD_Output + { + PinBox = RightNodeBox; + OutputPins.Add(PinToAdd); + } + + if (PinBox) + { + PinBox->AddSlot() + .HAlign(HAlign_Fill) + .VAlign(VAlign_Fill) + .FillHeight(1.0f) + //.Padding(6.0f, 0.0f) + [ + PinToAdd + ]; + } +} + +bool SEdNode_GenericGraphNode::IsNameReadOnly() const +{ + UEdNode_GenericGraphNode* EdNode_Node = Cast(GraphNode); + check(EdNode_Node != nullptr); + + UGenericGraph* GenericGraph = EdNode_Node->GenericGraphNode->Graph; + check(GenericGraph != nullptr); + + return (!GenericGraph->bCanRenameNode || !EdNode_Node->GenericGraphNode->IsNameEditable()) || SGraphNode::IsNameReadOnly(); +} + +END_SLATE_FUNCTION_BUILD_OPTIMIZATION + +void SEdNode_GenericGraphNode::OnNameTextCommited(const FText& InText, ETextCommit::Type CommitInfo) +{ + SGraphNode::OnNameTextCommited(InText, CommitInfo); + + UEdNode_GenericGraphNode* MyNode = CastChecked(GraphNode); + + if (MyNode != nullptr && MyNode->GenericGraphNode != nullptr) + { + const FScopedTransaction Transaction(LOCTEXT("GenericGraphEditorRenameNode", "Generic Graph Editor: Rename Node")); + MyNode->Modify(); + MyNode->GenericGraphNode->Modify(); + MyNode->GenericGraphNode->SetNodeTitle(InText); + UpdateGraphNode(); + } +} + +FSlateColor SEdNode_GenericGraphNode::GetBorderBackgroundColor() const +{ + UEdNode_GenericGraphNode* MyNode = CastChecked(GraphNode); + return MyNode ? MyNode->GetBackgroundColor() : GenericGraphColors::NodeBorder::HighlightAbortRange0; +} + +FSlateColor SEdNode_GenericGraphNode::GetBackgroundColor() const +{ + return GenericGraphColors::NodeBody::Default; +} + +EVisibility SEdNode_GenericGraphNode::GetDragOverMarkerVisibility() const +{ + return EVisibility::Visible; +} + +const FSlateBrush* SEdNode_GenericGraphNode::GetNameIcon() const +{ + return FAppStyle::GetBrush(TEXT("BTEditor.Graph.BTNode.Icon")); +} + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/Settings_GenericGraphEditor.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/Settings_GenericGraphEditor.cpp new file mode 100644 index 00000000..a5180a8d --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphAssetEditor/Settings_GenericGraphEditor.cpp @@ -0,0 +1,24 @@ +#include "GenericGraphAssetEditor/Settings_GenericGraphEditor.h" + +UGenericGraphEditorSettings::UGenericGraphEditorSettings() +{ + AutoLayoutStrategy = EAutoLayoutStrategy::Tree; + + bFirstPassOnly = false; + + bRandomInit = false; + + OptimalDistance = 100.f; + + MaxIteration = 50; + + InitTemperature = 10.f; + + CoolDownRate = 10.f; +} + +UGenericGraphEditorSettings::~UGenericGraphEditorSettings() +{ + +} + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphEditor.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphEditor.cpp new file mode 100644 index 00000000..b83d1f6d --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphEditor.cpp @@ -0,0 +1,55 @@ +#include "GenericGraphEditor.h" +#include "GenericGraphNodeFactory.h" +#include "AssetTypeActions_GenericGraph.h" +#include "GenericGraphAssetEditor/GenericGraphEditorStyle.h" + +DEFINE_LOG_CATEGORY(GenericGraphEditor) + +#define LOCTEXT_NAMESPACE "Editor_GenericGraph" + +void FGenericGraphEditor::StartupModule() +{ + FGenericGraphEditorStyle::Initialize(); + + GraphPanelNodeFactory_GenericGraph = MakeShareable(new FGraphPanelNodeFactory_GenericGraph()); + FEdGraphUtilities::RegisterVisualNodeFactory(GraphPanelNodeFactory_GenericGraph); + + IAssetTools& AssetTools = FModuleManager::LoadModuleChecked("AssetTools").Get(); + + GenericGraphAssetCategoryBit = AssetTools.RegisterAdvancedAssetCategory(FName(TEXT("GenericGraph")), LOCTEXT("GenericGraphAssetCategory", "GenericGraph")); + + RegisterAssetTypeAction(AssetTools, MakeShareable(new FAssetTypeActions_GenericGraph(GenericGraphAssetCategoryBit))); +} + + +void FGenericGraphEditor::ShutdownModule() +{ + // Unregister all the asset types that we registered + if (FModuleManager::Get().IsModuleLoaded("AssetTools")) + { + IAssetTools& AssetTools = FModuleManager::GetModuleChecked("AssetTools").Get(); + for (int32 Index = 0; Index < CreatedAssetTypeActions.Num(); ++Index) + { + AssetTools.UnregisterAssetTypeActions(CreatedAssetTypeActions[Index].ToSharedRef()); + } + } + + if (GraphPanelNodeFactory_GenericGraph.IsValid()) + { + FEdGraphUtilities::UnregisterVisualNodeFactory(GraphPanelNodeFactory_GenericGraph); + GraphPanelNodeFactory_GenericGraph.Reset(); + } + + FGenericGraphEditorStyle::Shutdown(); +} + +void FGenericGraphEditor::RegisterAssetTypeAction(IAssetTools& AssetTools, TSharedRef Action) +{ + AssetTools.RegisterAssetTypeActions(Action); + CreatedAssetTypeActions.Add(Action); +} + +IMPLEMENT_MODULE(FGenericGraphEditor, GenericGraphEditor) + +#undef LOCTEXT_NAMESPACE + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphFactory.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphFactory.cpp new file mode 100644 index 00000000..4c9fc7bb --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphFactory.cpp @@ -0,0 +1,117 @@ +#include "GenericGraphFactory.h" +#include "GenericGraph.h" + +#include "ClassViewerModule.h" +#include "ClassViewerFilter.h" +#include "Kismet2/KismetEditorUtilities.h" +#include "Kismet2/SClassPickerDialog.h" + +#define LOCTEXT_NAMESPACE "GenericGraphFactory" + +class FAssetClassParentFilter : public IClassViewerFilter +{ +public: + FAssetClassParentFilter() + : DisallowedClassFlags(CLASS_None), bDisallowBlueprintBase(false) + {} + + /** All children of these classes will be included unless filtered out by another setting. */ + TSet< const UClass* > AllowedChildrenOfClasses; + + /** Disallowed class flags. */ + EClassFlags DisallowedClassFlags; + + /** Disallow blueprint base classes. */ + bool bDisallowBlueprintBase; + + virtual bool IsClassAllowed(const FClassViewerInitializationOptions& InInitOptions, const UClass* InClass, TSharedRef< FClassViewerFilterFuncs > InFilterFuncs) override + { + bool bAllowed= !InClass->HasAnyClassFlags(DisallowedClassFlags) + && InFilterFuncs->IfInChildOfClassesSet(AllowedChildrenOfClasses, InClass) != EFilterReturn::Failed; + + if (bAllowed && bDisallowBlueprintBase) + { + if (FKismetEditorUtilities::CanCreateBlueprintOfClass(InClass)) + { + return false; + } + } + + return bAllowed; + } + + virtual bool IsUnloadedClassAllowed(const FClassViewerInitializationOptions& InInitOptions, const TSharedRef< const IUnloadedBlueprintData > InUnloadedClassData, TSharedRef< FClassViewerFilterFuncs > InFilterFuncs) override + { + if (bDisallowBlueprintBase) + { + return false; + } + + return !InUnloadedClassData->HasAnyClassFlags(DisallowedClassFlags) + && InFilterFuncs->IfInChildOfClassesSet(AllowedChildrenOfClasses, InUnloadedClassData) != EFilterReturn::Failed; + } +}; + + +UGenericGraphFactory::UGenericGraphFactory() +{ + bCreateNew = true; + bEditAfterNew = true; + SupportedClass = UGenericGraph::StaticClass(); +} + +UGenericGraphFactory::~UGenericGraphFactory() +{ + +} + +bool UGenericGraphFactory::ConfigureProperties() +{ + // nullptr the GenericGraphClass so we can check for selection + GenericGraphClass = nullptr; + + // Load the classviewer module to display a class picker + FClassViewerModule& ClassViewerModule = FModuleManager::LoadModuleChecked("ClassViewer"); + + // Fill in options + FClassViewerInitializationOptions Options; + Options.Mode = EClassViewerMode::ClassPicker; + +#if ENGINE_MAJOR_VERSION < 5 + TSharedPtr Filter = MakeShareable(new FAssetClassParentFilter); + Options.ClassFilter = Filter; +#else // #if ENGINE_MAJOR_VERSION < 5 + TSharedRef Filter = MakeShareable(new FAssetClassParentFilter); + Options.ClassFilters.Add(Filter); +#endif // #else // #if ENGINE_MAJOR_VERSION < 5 + + Filter->DisallowedClassFlags = CLASS_Abstract | CLASS_Deprecated | CLASS_NewerVersionExists | CLASS_HideDropDown; + Filter->AllowedChildrenOfClasses.Add(UGenericGraph::StaticClass()); + + const FText TitleText = LOCTEXT("CreateGenericGraphAssetOptions", "Pick Generic Graph Class"); + UClass* ChosenClass = nullptr; + const bool bPressedOk = SClassPickerDialog::PickClass(TitleText, Options, ChosenClass, UGenericGraph::StaticClass()); + + if ( bPressedOk ) + { + GenericGraphClass = ChosenClass; + } + + return bPressedOk; +} + +UObject* UGenericGraphFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) +{ + if (GenericGraphClass != nullptr) + { + return NewObject(InParent, GenericGraphClass, Name, Flags | RF_Transactional); + } + else + { + check(Class->IsChildOf(UGenericGraph::StaticClass())); + return NewObject(InParent, Class, Name, Flags | RF_Transactional); + } + +} + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphNodeFactory.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphNodeFactory.cpp new file mode 100644 index 00000000..e79dd2cf --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Private/GenericGraphNodeFactory.cpp @@ -0,0 +1,20 @@ +#include "GenericGraphNodeFactory.h" +#include +#include "GenericGraphAssetEditor/SEdNode_GenericGraphEdge.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphNode.h" +#include "GenericGraphAssetEditor/SEdNode_GenericGraphNode.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphEdge.h" + +TSharedPtr FGraphPanelNodeFactory_GenericGraph::CreateNode(UEdGraphNode* Node) const +{ + if (UEdNode_GenericGraphNode* EdNode_GraphNode = Cast(Node)) + { + return SNew(SEdNode_GenericGraphNode, EdNode_GraphNode); + } + else if (UEdNode_GenericGraphEdge* EdNode_Edge = Cast(Node)) + { + return SNew(SEdNode_GenericGraphEdge, EdNode_Edge); + } + return nullptr; +} + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AssetTypeActions_GenericGraph.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AssetTypeActions_GenericGraph.h new file mode 100644 index 00000000..8d7ba935 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AssetTypeActions_GenericGraph.h @@ -0,0 +1,19 @@ +#pragma once + +#include "CoreMinimal.h" +#include "AssetTypeActions_Base.h" + +class GENERICGRAPHEDITOR_API FAssetTypeActions_GenericGraph : public FAssetTypeActions_Base +{ +public: + FAssetTypeActions_GenericGraph(EAssetTypeCategories::Type InAssetCategory); + + virtual FText GetName() const override; + virtual FColor GetTypeColor() const override; + virtual UClass* GetSupportedClass() const override; + virtual void OpenAssetEditor(const TArray& InObjects, TSharedPtr EditWithinLevelEditor = TSharedPtr()) override; + virtual uint32 GetCategories() override; + +private: + EAssetTypeCategories::Type MyAssetCategory; +}; \ No newline at end of file diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/AutoLayoutStrategy.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/AutoLayoutStrategy.h new file mode 100644 index 00000000..52a5efb3 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/AutoLayoutStrategy.h @@ -0,0 +1,40 @@ +#pragma once + +#include "CoreMinimal.h" +#include "EdGraph/EdGraph.h" +#include "GenericGraph.h" +#include "GenericGraphAssetEditor/EdGraph_GenericGraph.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphNode.h" +#include "GenericGraphAssetEditor/EdNode_GenericGraphEdge.h" +#include "GenericGraphAssetEditor/Settings_GenericGraphEditor.h" +#include "AutoLayoutStrategy.generated.h" + +UCLASS(abstract) +class GENERICGRAPHEDITOR_API UAutoLayoutStrategy : public UObject +{ + GENERATED_BODY() +public: + UAutoLayoutStrategy(); + virtual ~UAutoLayoutStrategy(); + + virtual void Layout(UEdGraph* G) {}; + + class UGenericGraphEditorSettings* Settings; + +protected: + int32 GetNodeWidth(UEdNode_GenericGraphNode* EdNode); + + int32 GetNodeHeight(UEdNode_GenericGraphNode* EdNode); + + FBox2D GetNodeBound(UEdGraphNode* EdNode); + + FBox2D GetActualBounds(UGenericGraphNode* RootNode); + + virtual void RandomLayoutOneTree(UGenericGraphNode* RootNode, const FBox2D& Bound); + +protected: + UGenericGraph* Graph; + UEdGraph_GenericGraph* EdGraph; + int32 MaxIteration; + int32 OptimalDistance; +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/ForceDirectedLayoutStrategy.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/ForceDirectedLayoutStrategy.h new file mode 100644 index 00000000..e5c40c95 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/ForceDirectedLayoutStrategy.h @@ -0,0 +1,24 @@ +#pragma once + +#include "CoreMinimal.h" +#include "AutoLayoutStrategy.h" +#include "ForceDirectedLayoutStrategy.generated.h" + +UCLASS() +class GENERICGRAPHEDITOR_API UForceDirectedLayoutStrategy : public UAutoLayoutStrategy +{ + GENERATED_BODY() +public: + UForceDirectedLayoutStrategy(); + virtual ~UForceDirectedLayoutStrategy(); + + virtual void Layout(UEdGraph* EdGraph) override; + +protected: + virtual FBox2D LayoutOneTree(UGenericGraphNode* RootNode, const FBox2D& PreTreeBound); + +protected: + bool bRandomInit; + float InitTemperature; + float CoolDownRate; +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/TreeLayoutStrategy.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/TreeLayoutStrategy.h new file mode 100644 index 00000000..27c7ff42 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/AutoLayout/TreeLayoutStrategy.h @@ -0,0 +1,29 @@ +#pragma once + +#include "CoreMinimal.h" +#include "AutoLayoutStrategy.h" +#include "TreeLayoutStrategy.generated.h" + +UCLASS() +class GENERICGRAPHEDITOR_API UTreeLayoutStrategy : public UAutoLayoutStrategy +{ + GENERATED_BODY() +public: + UTreeLayoutStrategy(); + virtual ~UTreeLayoutStrategy(); + + virtual void Layout(UEdGraph* EdGraph) override; + +protected: + void InitPass(UGenericGraphNode* RootNode, const FVector2D& Anchor); + bool ResolveConflictPass(UGenericGraphNode* Node); + + bool ResolveConflict(UGenericGraphNode* LRoot, UGenericGraphNode* RRoot); + + void GetLeftContour(UGenericGraphNode* RootNode, int32 Level, TArray& Contour); + void GetRightContour(UGenericGraphNode* RootNode, int32 Level, TArray& Contour); + + void ShiftSubTree(UGenericGraphNode* RootNode, const FVector2D& Offset); + + void UpdateParentNodePosition(UGenericGraphNode* RootNode); +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetEditorToolbar_GenericGraph.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetEditorToolbar_GenericGraph.h new file mode 100644 index 00000000..37e5d092 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetEditorToolbar_GenericGraph.h @@ -0,0 +1,24 @@ + +#pragma once + +#include "CoreMinimal.h" + +class FAssetEditor_GenericGraph; +class FExtender; +class FToolBarBuilder; + +class GENERICGRAPHEDITOR_API FAssetEditorToolbar_GenericGraph : public TSharedFromThis +{ +public: + FAssetEditorToolbar_GenericGraph(TSharedPtr InGenericGraphEditor) + : GenericGraphEditor(InGenericGraphEditor) {} + + void AddGenericGraphToolbar(TSharedPtr Extender); + +private: + void FillGenericGraphToolbar(FToolBarBuilder& ToolbarBuilder); + +protected: + /** Pointer back to the blueprint editor tool that owns us */ + TWeakPtr GenericGraphEditor; +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetEditor_GenericGraph.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetEditor_GenericGraph.h new file mode 100644 index 00000000..f1cc415b --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetEditor_GenericGraph.h @@ -0,0 +1,137 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Settings_GenericGraphEditor.h" +#include "GenericGraph.h" + +#if ENGINE_MAJOR_VERSION == 5 +#include "UObject/ObjectSaveContext.h" +#endif // #if ENGINE_MAJOR_VERSION == 5 + +class FGGAssetEditorToolbar; + +class GENERICGRAPHEDITOR_API FAssetEditor_GenericGraph : public FAssetEditorToolkit, public FNotifyHook, public FGCObject +{ +public: + FAssetEditor_GenericGraph(); + virtual ~FAssetEditor_GenericGraph(); + + void InitGenericGraphAssetEditor(const EToolkitMode::Type Mode, const TSharedPtr< IToolkitHost >& InitToolkitHost, UGenericGraph* Graph); + + // IToolkit interface + virtual void RegisterTabSpawners(const TSharedRef& TabManager) override; + virtual void UnregisterTabSpawners(const TSharedRef& TabManager) override; + // End of IToolkit interface + + // FAssetEditorToolkit + virtual FName GetToolkitFName() const override; + virtual FText GetBaseToolkitName() const override; + virtual FText GetToolkitName() const override; + virtual FText GetToolkitToolTipText() const override; + virtual FLinearColor GetWorldCentricTabColorScale() const override; + virtual FString GetWorldCentricTabPrefix() const override; + virtual FString GetDocumentationLink() const override; + virtual void SaveAsset_Execute() override; + // End of FAssetEditorToolkit + + //Toolbar + void UpdateToolbar(); + TSharedPtr GetToolbarBuilder() { return ToolbarBuilder; } + void RegisterToolbarTab(const TSharedRef& TabManager); + + + // FSerializableObject interface + virtual void AddReferencedObjects(FReferenceCollector& Collector) override; + // End of FSerializableObject interface + +#if ENGINE_MAJOR_VERSION == 5 + // FGCObject interface + virtual FString GetReferencerName() const + { + return TEXT("FAssetEditor_LTGenericGraph"); + } + // ~FGCObject interface +#endif // #if ENGINE_MAJOR_VERSION == 5 + + UGenericGraphEditorSettings* GetSettings() const; + +protected: + TSharedRef SpawnTab_Viewport(const FSpawnTabArgs& Args); + TSharedRef SpawnTab_Details(const FSpawnTabArgs& Args); + TSharedRef SpawnTab_EditorSettings(const FSpawnTabArgs& Args); + + void CreateInternalWidgets(); + TSharedRef CreateViewportWidget(); + + + void BindCommands(); + + void CreateEdGraph(); + + void CreateCommandList(); + + TSharedPtr GetCurrGraphEditor() const; + + FGraphPanelSelectionSet GetSelectedNodes() const; + + void RebuildGenericGraph(); + + // Delegates for graph editor commands + void SelectAllNodes(); + bool CanSelectAllNodes(); + void DeleteSelectedNodes(); + bool CanDeleteNodes(); + void DeleteSelectedDuplicatableNodes(); + void CutSelectedNodes(); + bool CanCutNodes(); + void CopySelectedNodes(); + bool CanCopyNodes(); + void PasteNodes(); + void PasteNodesHere(const FVector2D& Location); + bool CanPasteNodes(); + void DuplicateNodes(); + bool CanDuplicateNodes(); + + void GraphSettings(); + bool CanGraphSettings() const; + + void AutoArrange(); + bool CanAutoArrange() const; + + void OnRenameNode(); + bool CanRenameNodes() const; + + ////////////////////////////////////////////////////////////////////////// + // graph editor event + void OnSelectedNodesChanged(const TSet& NewSelection); + + void OnNodeDoubleClicked(UEdGraphNode* Node); + + void OnFinishedChangingProperties(const FPropertyChangedEvent& PropertyChangedEvent); + +#if ENGINE_MAJOR_VERSION < 5 + void OnPackageSaved(const FString& PackageFileName, UObject* Outer); +#else // #if ENGINE_MAJOR_VERSION < 5 + void OnPackageSavedWithContext(const FString& PackageFileName, UPackage* Package, FObjectPostSaveContext ObjectSaveContext); +#endif // #else // #if ENGINE_MAJOR_VERSION < 5 + +protected: + UGenericGraphEditorSettings* GenricGraphEditorSettings; + + UGenericGraph* EditingGraph; + + //Toolbar + TSharedPtr ToolbarBuilder; + + /** Handle to the registered OnPackageSave delegate */ + FDelegateHandle OnPackageSavedDelegateHandle; + + TSharedPtr ViewportWidget; + TSharedPtr PropertyWidget; + TSharedPtr EditorSettingsWidget; + + /** The command list for this editor */ + TSharedPtr GraphEditorCommands; +}; + + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetGraphSchema_GenericGraph.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetGraphSchema_GenericGraph.h new file mode 100644 index 00000000..faf74b9c --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/AssetGraphSchema_GenericGraph.h @@ -0,0 +1,90 @@ +#pragma once + +#include "CoreMinimal.h" +#include "GenericGraph.h" +#include "GenericGraphNode.h" +#include "GenericGraphEdge.h" +#include "AssetGraphSchema_GenericGraph.generated.h" + +class UEdNode_GenericGraphNode; +class UEdNode_GenericGraphEdge; +class UAutoLayoutStrategy; + +/** Action to add a node to the graph */ +USTRUCT() +struct GENERICGRAPHEDITOR_API FAssetSchemaAction_GenericGraph_NewNode : public FEdGraphSchemaAction +{ + GENERATED_USTRUCT_BODY(); + +public: + FAssetSchemaAction_GenericGraph_NewNode(): NodeTemplate(nullptr) {} + + FAssetSchemaAction_GenericGraph_NewNode(const FText& InNodeCategory, const FText& InMenuDesc, const FText& InToolTip, const int32 InGrouping) + : FEdGraphSchemaAction(InNodeCategory, InMenuDesc, InToolTip, InGrouping), NodeTemplate(nullptr) {} + + virtual UEdGraphNode* PerformAction(class UEdGraph* ParentGraph, UEdGraphPin* FromPin, const FVector2D Location, bool bSelectNewNode = true) override; + virtual void AddReferencedObjects(FReferenceCollector& Collector) override; + + UEdNode_GenericGraphNode* NodeTemplate; +}; + +USTRUCT() +struct GENERICGRAPHEDITOR_API FAssetSchemaAction_GenericGraph_NewEdge : public FEdGraphSchemaAction +{ + GENERATED_USTRUCT_BODY(); + +public: + FAssetSchemaAction_GenericGraph_NewEdge(): NodeTemplate(nullptr){} + + FAssetSchemaAction_GenericGraph_NewEdge(const FText& InNodeCategory, const FText& InMenuDesc, const FText& InToolTip, const int32 InGrouping) + : FEdGraphSchemaAction(InNodeCategory, InMenuDesc, InToolTip, InGrouping), NodeTemplate(nullptr) {} + + virtual UEdGraphNode* PerformAction(class UEdGraph* ParentGraph, UEdGraphPin* FromPin, const FVector2D Location, bool bSelectNewNode = true) override; + virtual void AddReferencedObjects(FReferenceCollector& Collector) override; + + UEdNode_GenericGraphEdge* NodeTemplate; +}; + +UCLASS(MinimalAPI) +class UAssetGraphSchema_GenericGraph : public UEdGraphSchema +{ + GENERATED_BODY() + +public: + void GetBreakLinkToSubMenuActions(class UToolMenu* Menu, class UEdGraphPin* InGraphPin); + + virtual EGraphType GetGraphType(const UEdGraph* TestEdGraph) const override; + + virtual void GetGraphContextActions(FGraphContextMenuBuilder& ContextMenuBuilder) const override; + + virtual void GetContextMenuActions(class UToolMenu* Menu, class UGraphNodeContextMenuContext* Context) const override; + + virtual const FPinConnectionResponse CanCreateConnection(const UEdGraphPin* A, const UEdGraphPin* B) const override; + + virtual bool TryCreateConnection(UEdGraphPin* A, UEdGraphPin* B) const override; + virtual bool CreateAutomaticConversionNodeAndConnections(UEdGraphPin* A, UEdGraphPin* B) const override; + + virtual class FConnectionDrawingPolicy* CreateConnectionDrawingPolicy(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, class FSlateWindowElementList& InDrawElements, class UEdGraph* InGraphObj) const override; + + virtual FLinearColor GetPinTypeColor(const FEdGraphPinType& PinType) const override; + + virtual void BreakNodeLinks(UEdGraphNode& TargetNode) const override; + + virtual void BreakPinLinks(UEdGraphPin& TargetPin, bool bSendsNodeNotifcation) const override; + + virtual void BreakSinglePinLink(UEdGraphPin* SourcePin, UEdGraphPin* TargetPin) const override; + + virtual UEdGraphPin* DropPinOnNode(UEdGraphNode* InTargetNode, const FName& InSourcePinName, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection) const override; + + virtual bool SupportsDropPinOnNode(UEdGraphNode* InTargetNode, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection, FText& OutErrorMessage) const override; + + virtual bool IsCacheVisualizationOutOfDate(int32 InVisualizationCacheID) const override; + + virtual int32 GetCurrentVisualizationCacheID() const override; + + virtual void ForceVisualizationCacheClear() const override; + +private: + static int32 CurrentCacheRefreshID; +}; + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/Colors_GenericGraph.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/Colors_GenericGraph.h new file mode 100644 index 00000000..5258d1a8 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/Colors_GenericGraph.h @@ -0,0 +1,45 @@ +#pragma once + +#include "CoreMinimal.h" + +namespace GenericGraphColors +{ + namespace NodeBody + { + const FLinearColor Default(0.1f, 0.1f, 0.1f); + const FLinearColor Root(0.5f, 0.5f, 0.5f, 0.1f); + const FLinearColor Error(1.0f, 0.0f, 0.0f); + } + + namespace NodeBorder + { + const FLinearColor Inactive(0.08f, 0.08f, 0.08f); + const FLinearColor Root(0.2f, 0.2f, 0.2f, 0.2f); + const FLinearColor Selected(1.00f, 0.08f, 0.08f); + const FLinearColor ActiveDebugging(1.0f, 1.0f, 0.0f); + const FLinearColor InactiveDebugging(0.4f, 0.4f, 0.0f); + const FLinearColor HighlightAbortRange0(0.0f, 0.22f, 0.4f); + const FLinearColor HighlightAbortRange1(0.0f, 0.4f, 0.22f); + const FLinearColor Disconnected(0.f, 0.f, 0.f); + const FLinearColor BrokenWithParent(1.f, 0.f, 1.f); + const FLinearColor QuickFind(0.f, 0.8f, 0.f); + } + + namespace Pin + { + const FLinearColor Diff(0.9f, 0.2f, 0.15f); + const FLinearColor Hover(1.0f, 0.7f, 0.0f); + const FLinearColor Default(0.02f, 0.02f, 0.02f); + const FLinearColor SingleNode(0.02f, 0.02f, 0.02f); + } + + namespace Connection + { + const FLinearColor Default(1.0f, 1.0f, 1.0f); + } + + namespace Action + { + const FLinearColor DragMarker(1.0f, 1.0f, 0.2f); + } +} diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/ConnectionDrawingPolicy_GenericGraph.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/ConnectionDrawingPolicy_GenericGraph.h new file mode 100644 index 00000000..e375e816 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/ConnectionDrawingPolicy_GenericGraph.h @@ -0,0 +1,27 @@ +#pragma once + +#include "CoreMinimal.h" +#include "ConnectionDrawingPolicy.h" + +class GENERICGRAPHEDITOR_API FConnectionDrawingPolicy_GenericGraph : public FConnectionDrawingPolicy +{ +protected: + UEdGraph* GraphObj; + TMap NodeWidgetMap; + +public: + FConnectionDrawingPolicy_GenericGraph(int32 InBackLayerID, int32 InFrontLayerID, float ZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements, UEdGraph* InGraphObj); + + // FConnectionDrawingPolicy interface + virtual void DetermineWiringStyle(UEdGraphPin* OutputPin, UEdGraphPin* InputPin, /*inout*/ FConnectionParams& Params) override; + virtual void Draw(TMap, FArrangedWidget>& PinGeometries, FArrangedChildren& ArrangedNodes) override; + virtual void DrawSplineWithArrow(const FGeometry& StartGeom, const FGeometry& EndGeom, const FConnectionParams& Params) override; + virtual void DrawSplineWithArrow(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params) override; + virtual void DrawPreviewConnector(const FGeometry& PinGeometry, const FVector2D& StartPoint, const FVector2D& EndPoint, UEdGraphPin* Pin) override; + virtual FVector2D ComputeSplineTangent(const FVector2D& Start, const FVector2D& End) const override; + virtual void DetermineLinkGeometry(FArrangedChildren& ArrangedNodes, TSharedRef& OutputPinWidget, UEdGraphPin* OutputPin, UEdGraphPin* InputPin, FArrangedWidget*& StartWidgetGeometry, FArrangedWidget*& EndWidgetGeometry) override; + // End of FConnectionDrawingPolicy interface + +protected: + void Internal_DrawLineWithArrow(const FVector2D& StartAnchorPoint, const FVector2D& EndAnchorPoint, const FConnectionParams& Params); +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdGraph_GenericGraph.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdGraph_GenericGraph.h new file mode 100644 index 00000000..5cb92af3 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdGraph_GenericGraph.h @@ -0,0 +1,39 @@ +#pragma once + +#include "CoreMinimal.h" +#include "EdGraph/EdGraph.h" +#include "EdGraph_GenericGraph.generated.h" + +class UGenericGraph; +class UGenericGraphNode; +class UGenericGraphEdge; +class UEdNode_GenericGraphNode; +class UEdNode_GenericGraphEdge; + +UCLASS() +class GENERICGRAPHEDITOR_API UEdGraph_GenericGraph : public UEdGraph +{ + GENERATED_BODY() + +public: + UEdGraph_GenericGraph(); + virtual ~UEdGraph_GenericGraph(); + + virtual void RebuildGenericGraph(); + + UGenericGraph* GetGenericGraph() const; + + virtual bool Modify(bool bAlwaysMarkDirty = true) override; + virtual void PostEditUndo() override; + + UPROPERTY(Transient) + TMap NodeMap; + + UPROPERTY(Transient) + TMap EdgeMap; + +protected: + void Clear(); + + void SortNodes(UGenericGraphNode* RootNode); +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdNode_GenericGraphEdge.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdNode_GenericGraphEdge.h new file mode 100644 index 00000000..ac480d8f --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdNode_GenericGraphEdge.h @@ -0,0 +1,42 @@ +#pragma once + +#include "CoreMinimal.h" +#include "EdGraph/EdGraphNode.h" +#include "EdNode_GenericGraphEdge.generated.h" + +class UGenericGraphNode; +class UGenericGraphEdge; +class UEdNode_GenericGraphNode; + +UCLASS(MinimalAPI) +class UEdNode_GenericGraphEdge : public UEdGraphNode +{ + GENERATED_BODY() + +public: + UEdNode_GenericGraphEdge(); + + UPROPERTY() + class UEdGraph* Graph; + + UPROPERTY(VisibleAnywhere, Instanced, Category = "GenericGraph") + UGenericGraphEdge* GenericGraphEdge; + + void SetEdge(UGenericGraphEdge* Edge); + + virtual void AllocateDefaultPins() override; + + virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; + + virtual void PinConnectionListChanged(UEdGraphPin* Pin) override; + + virtual void PrepareForCopying() override; + + virtual UEdGraphPin* GetInputPin() const { return Pins[0]; } + virtual UEdGraphPin* GetOutputPin() const { return Pins[1]; } + + void CreateConnections(UEdNode_GenericGraphNode* Start, UEdNode_GenericGraphNode* End); + + UEdNode_GenericGraphNode* GetStartNode(); + UEdNode_GenericGraphNode* GetEndNode(); +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdNode_GenericGraphNode.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdNode_GenericGraphNode.h new file mode 100644 index 00000000..258a089c --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EdNode_GenericGraphNode.h @@ -0,0 +1,42 @@ +#pragma once + +#include "CoreMinimal.h" +#include "EdGraph/EdGraphNode.h" +#include "GenericGraphNode.h" +#include "EdNode_GenericGraphNode.generated.h" + +class UEdNode_GenericGraphEdge; +class UEdGraph_GenericGraph; +class SEdNode_GenericGraphNode; + +UCLASS(MinimalAPI) +class UEdNode_GenericGraphNode : public UEdGraphNode +{ + GENERATED_BODY() + +public: + UEdNode_GenericGraphNode(); + virtual ~UEdNode_GenericGraphNode(); + + UPROPERTY(VisibleAnywhere, Instanced, Category = "GenericGraph") + UGenericGraphNode* GenericGraphNode; + + void SetGenericGraphNode(UGenericGraphNode* InNode); + UEdGraph_GenericGraph* GetGenericGraphEdGraph(); + + SEdNode_GenericGraphNode* SEdNode; + + virtual void AllocateDefaultPins() override; + virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; + virtual void PrepareForCopying() override; + virtual void AutowireNewNode(UEdGraphPin* FromPin) override; + + virtual FLinearColor GetBackgroundColor() const; + virtual UEdGraphPin* GetInputPin() const; + virtual UEdGraphPin* GetOutputPin() const; + +#if WITH_EDITOR + virtual void PostEditUndo() override; +#endif + +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EditorCommands_GenericGraph.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EditorCommands_GenericGraph.h new file mode 100644 index 00000000..ff6c5bd9 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/EditorCommands_GenericGraph.h @@ -0,0 +1,18 @@ +#pragma once + +#include "CoreMinimal.h" + +class GENERICGRAPHEDITOR_API FEditorCommands_GenericGraph : public TCommands +{ +public: + /** Constructor */ + FEditorCommands_GenericGraph() + : TCommands("GenericGraphEditor", NSLOCTEXT("Contexts", "GenericGraphEditor", "Generic Graph Editor"), NAME_None, FAppStyle::GetAppStyleSetName()) + { + } + + TSharedPtr GraphSettings; + TSharedPtr AutoArrange; + + virtual void RegisterCommands() override; +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/GenericGraphDragConnection.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/GenericGraphDragConnection.h new file mode 100644 index 00000000..bd0a91af --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/GenericGraphDragConnection.h @@ -0,0 +1,52 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Input/DragAndDrop.h" +#include "Input/Reply.h" +#include "Widgets/SWidget.h" +#include "SGraphPin.h" +#include "GraphEditorDragDropAction.h" + +class SGraphPanel; +class UEdGraph; + +class FGenericGraphDragConnection : public FGraphEditorDragDropAction +{ +public: + DRAG_DROP_OPERATOR_TYPE(FDragConnection, FGraphEditorDragDropAction) + + typedef TArray FDraggedPinTable; + static TSharedRef New(const TSharedRef& InGraphPanel, const FDraggedPinTable& InStartingPins); + + // FDragDropOperation interface + virtual void OnDrop(bool bDropWasHandled, const FPointerEvent& MouseEvent) override; + // End of FDragDropOperation interface + + // FGraphEditorDragDropAction interface + virtual void HoverTargetChanged() override; + virtual FReply DroppedOnPin(FVector2D ScreenPosition, FVector2D GraphPosition) override; + virtual FReply DroppedOnNode(FVector2D ScreenPosition, FVector2D GraphPosition) override; + virtual FReply DroppedOnPanel(const TSharedRef< SWidget >& Panel, FVector2D ScreenPosition, FVector2D GraphPosition, UEdGraph& Graph) override; + virtual void OnDragged(const class FDragDropEvent& DragDropEvent) override; + // End of FGraphEditorDragDropAction interface + + /* + * Function to check validity of graph pins in the StartPins list. This check helps to prevent processing graph pins which are outdated. + */ + virtual void ValidateGraphPinList(TArray& OutValidPins); + +protected: + typedef FGraphEditorDragDropAction Super; + + // Constructor: Make sure to call Construct() after factorying one of these + FGenericGraphDragConnection(const TSharedRef& GraphPanel, const FDraggedPinTable& DraggedPins); + +protected: + TSharedPtr GraphPanel; + FDraggedPinTable DraggingPins; + + /** Offset information for the decorator widget */ + FVector2D DecoratorAdjust; +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/GenericGraphEditorStyle.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/GenericGraphEditorStyle.h new file mode 100644 index 00000000..577312f3 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/GenericGraphEditorStyle.h @@ -0,0 +1,16 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Styling/SlateStyle.h" + +class GENERICGRAPHEDITOR_API FGenericGraphEditorStyle +{ +public: + static void Initialize(); + static void Shutdown(); + + static const FName& GetStyleSetName(); + +private: + static TSharedPtr StyleSet; +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/SEdNode_GenericGraphEdge.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/SEdNode_GenericGraphEdge.h new file mode 100644 index 00000000..8505a5f6 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/SEdNode_GenericGraphEdge.h @@ -0,0 +1,40 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Styling/SlateColor.h" +#include "Widgets/DeclarativeSyntaxSupport.h" +#include "Widgets/SWidget.h" +#include "SNodePanel.h" +#include "SGraphNode.h" + +class SToolTip; +class UEdNode_GenericGraphEdge; + +class GENERICGRAPHEDITOR_API SEdNode_GenericGraphEdge : public SGraphNode +{ +public: + SLATE_BEGIN_ARGS(SEdNode_GenericGraphEdge){} + SLATE_END_ARGS() + + void Construct(const FArguments& InArgs, UEdNode_GenericGraphEdge* InNode); + + virtual bool RequiresSecondPassLayout() const override; + virtual void PerformSecondPassLayout(const TMap< UObject*, TSharedRef >& NodeToWidgetLookup) const override; + + virtual void UpdateGraphNode() override; + + // Calculate position for multiple nodes to be placed between a start and end point, by providing this nodes index and max expected nodes + void PositionBetweenTwoNodesWithOffset(const FGeometry& StartGeom, const FGeometry& EndGeom, int32 NodeIndex, int32 MaxNodes) const; + + void OnNameTextCommited(const FText& InText, ETextCommit::Type CommitInfo); + +protected: + FSlateColor GetEdgeColor() const; + + const FSlateBrush* GetEdgeImage() const; + + EVisibility GetEdgeImageVisibility() const; + EVisibility GetEdgeTitleVisbility() const; +private: + TSharedPtr TextEntryWidget; +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/SEdNode_GenericGraphNode.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/SEdNode_GenericGraphNode.h new file mode 100644 index 00000000..1d4d9b99 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/SEdNode_GenericGraphNode.h @@ -0,0 +1,32 @@ +#pragma once + +#include "CoreMinimal.h" +#include "SGraphNode.h" + +class UEdNode_GenericGraphNode; + +class GENERICGRAPHEDITOR_API SEdNode_GenericGraphNode : public SGraphNode +{ +public: + SLATE_BEGIN_ARGS(SEdNode_GenericGraphNode) {} + SLATE_END_ARGS() + + void Construct(const FArguments& InArgs, UEdNode_GenericGraphNode* InNode); + + virtual void UpdateGraphNode() override; + virtual void CreatePinWidgets() override; + virtual void AddPin(const TSharedRef& PinToAdd) override; + virtual bool IsNameReadOnly() const override; + + void OnNameTextCommited(const FText& InText, ETextCommit::Type CommitInfo); + + virtual FSlateColor GetBorderBackgroundColor() const; + virtual FSlateColor GetBackgroundColor() const; + + virtual EVisibility GetDragOverMarkerVisibility() const; + + virtual const FSlateBrush* GetNameIcon() const; + +protected: +}; + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/Settings_GenericGraphEditor.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/Settings_GenericGraphEditor.h new file mode 100644 index 00000000..c1e39156 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphAssetEditor/Settings_GenericGraphEditor.h @@ -0,0 +1,42 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Settings_GenericGraphEditor.generated.h" + +UENUM(BlueprintType) +enum class EAutoLayoutStrategy : uint8 +{ + Tree, + ForceDirected, +}; + +UCLASS() +class GENERICGRAPHEDITOR_API UGenericGraphEditorSettings : public UObject +{ + GENERATED_BODY() + +public: + UGenericGraphEditorSettings(); + virtual ~UGenericGraphEditorSettings(); + + UPROPERTY(EditDefaultsOnly, Category = "AutoArrange") + float OptimalDistance; + + UPROPERTY(EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange") + EAutoLayoutStrategy AutoLayoutStrategy; + + UPROPERTY(EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange") + int32 MaxIteration; + + UPROPERTY(EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange") + bool bFirstPassOnly; + + UPROPERTY(EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange") + bool bRandomInit; + + UPROPERTY(EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange") + float InitTemperature; + + UPROPERTY(EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange") + float CoolDownRate; +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditor.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditor.h new file mode 100644 index 00000000..f710fc2c --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditor.h @@ -0,0 +1,23 @@ +#pragma once +#include "Modules/ModuleManager.h" +#include "GenericGraphEditorModule.h" +#include +#include + +class FGenericGraphEditor : public IGenericGraphEditor +{ + /** IModuleInterface implementation */ + virtual void StartupModule() override; + virtual void ShutdownModule() override; + + +private: + void RegisterAssetTypeAction(IAssetTools& AssetTools, TSharedRef Action); + +private: + TArray< TSharedPtr > CreatedAssetTypeActions; + + EAssetTypeCategories::Type GenericGraphAssetCategoryBit; + + TSharedPtr GraphPanelNodeFactory_GenericGraph; +}; \ No newline at end of file diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditorModule.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditorModule.h new file mode 100644 index 00000000..c042dc1f --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditorModule.h @@ -0,0 +1,34 @@ +#include"Modules/ModuleManager.h" + +DECLARE_LOG_CATEGORY_EXTERN(GenericGraphEditor, Log, All); + +/** + * The public interface to this module + */ +class IGenericGraphEditor : public IModuleInterface +{ + +public: + + /** + * Singleton-like access to this module's interface. This is just for convenience! + * Beware of calling this during the shutdown phase, though. Your module might have been unloaded already. + * + * @return Returns singleton instance, loading the module on demand if needed + */ + static IGenericGraphEditor& Get() + { + return FModuleManager::LoadModuleChecked< IGenericGraphEditor >("GenericGraphEditor"); + } + + /** + * Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true. + * + * @return True if the module is loaded and ready to use + */ + static bool IsAvailable() + { + return FModuleManager::Get().IsModuleLoaded("GenericGraphEditor"); + } +}; + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditorPCH.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditorPCH.h new file mode 100644 index 00000000..f0385f7d --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphEditorPCH.h @@ -0,0 +1,13 @@ +#pragma once + +#include "GenericGraph.h" +#include "GenericGraphNode.h" +#include "GenericGraphEdge.h" + +// You should place include statements to your module's private header files here. You only need to +// add includes for headers that are used in most of your module's source files though. +#include "GenericGraphEditor.h" + +#define LOG_INFO(FMT, ...) UE_LOG(GenericGraphEditor, Display, (FMT), ##__VA_ARGS__) +#define LOG_WARNING(FMT, ...) UE_LOG(GenericGraphEditor, Warning, (FMT), ##__VA_ARGS__) +#define LOG_ERROR(FMT, ...) UE_LOG(GenericGraphEditor, Error, (FMT), ##__VA_ARGS__) diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphFactory.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphFactory.h new file mode 100644 index 00000000..00cc44d4 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphFactory.h @@ -0,0 +1,22 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Factories/Factory.h" +#include "GenericGraph.h" +#include "GenericGraphFactory.generated.h" + +UCLASS() +class GENERICGRAPHEDITOR_API UGenericGraphFactory : public UFactory +{ + GENERATED_BODY() + +public: + UGenericGraphFactory(); + virtual ~UGenericGraphFactory(); + + UPROPERTY(EditAnywhere, Category=DataAsset) + TSubclassOf GenericGraphClass; + + virtual bool ConfigureProperties() override; + virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override; +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphNodeFactory.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphNodeFactory.h new file mode 100644 index 00000000..5feb3345 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphEditor/Public/GenericGraphNodeFactory.h @@ -0,0 +1,8 @@ +#pragma once +#include +#include + +class FGraphPanelNodeFactory_GenericGraph : public FGraphPanelNodeFactory +{ + virtual TSharedPtr CreateNode(UEdGraphNode* Node) const override; +}; \ No newline at end of file diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/GenericGraphRuntime.Build.cs b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/GenericGraphRuntime.Build.cs new file mode 100644 index 00000000..e3d5c5d9 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/GenericGraphRuntime.Build.cs @@ -0,0 +1,51 @@ +using UnrealBuildTool; + +public class GenericGraphRuntime : ModuleRules +{ + public GenericGraphRuntime(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + bLegacyPublicIncludePaths = false; + ShadowVariableWarningLevel = WarningLevel.Error; + + PublicIncludePaths.AddRange( + new string[] { + // ... add public include paths required here ... + } + ); + + PrivateIncludePaths.AddRange( + new string[] { + "GenericGraphRuntime/Private", + // ... add other private include paths required here ... + } + ); + + PublicDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "Engine", + // ... add other public dependencies that you statically link with here ... + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + // ... add private dependencies that you statically link with here ... + "Slate", + "SlateCore", + "GameplayTags" + } + ); + + DynamicallyLoadedModuleNames.AddRange( + new string[] + { + // ... add any modules that your module loads dynamically here ... + } + ); + } +} \ No newline at end of file diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraph.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraph.cpp new file mode 100644 index 00000000..c2bbb302 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraph.cpp @@ -0,0 +1,136 @@ +#include "GenericGraph.h" +#include "GenericGraphRuntimePCH.h" +#include "Engine/Engine.h" + +#define LOCTEXT_NAMESPACE "GenericGraph" + +UGenericGraph::UGenericGraph() +{ + NodeType = UGenericGraphNode::StaticClass(); + EdgeType = UGenericGraphEdge::StaticClass(); + + bEdgeEnabled = true; + +#if WITH_EDITORONLY_DATA + EdGraph = nullptr; + + bCanRenameNode = true; +#endif +} + +UGenericGraph::~UGenericGraph() +{ + +} + +void UGenericGraph::Print(bool ToConsole /*= true*/, bool ToScreen /*= true*/) +{ + int Level = 0; + TArray CurrLevelNodes = RootNodes; + TArray NextLevelNodes; + + while (CurrLevelNodes.Num() != 0) + { + for (int i = 0; i < CurrLevelNodes.Num(); ++i) + { + UGenericGraphNode* Node = CurrLevelNodes[i]; + check(Node != nullptr); + + FString Message = FString::Printf(TEXT("%s, Level %d"), *Node->GetDescription().ToString(), Level); + + if (ToConsole) + { + LOG_INFO(TEXT("%s"), *Message); + } + + if (ToScreen && GEngine != nullptr) + { + GEngine->AddOnScreenDebugMessage(-1, 15.f, FColor::Blue, Message); + } + + for (int j = 0; j < Node->ChildrenNodes.Num(); ++j) + { + NextLevelNodes.Add(Node->ChildrenNodes[j]); + } + } + + CurrLevelNodes = NextLevelNodes; + NextLevelNodes.Reset(); + ++Level; + } +} + +int UGenericGraph::GetLevelNum() const +{ + int Level = 0; + TArray CurrLevelNodes = RootNodes; + TArray NextLevelNodes; + + while (CurrLevelNodes.Num() != 0) + { + for (int i = 0; i < CurrLevelNodes.Num(); ++i) + { + UGenericGraphNode* Node = CurrLevelNodes[i]; + check(Node != nullptr); + + for (int j = 0; j < Node->ChildrenNodes.Num(); ++j) + { + NextLevelNodes.Add(Node->ChildrenNodes[j]); + } + } + + CurrLevelNodes = NextLevelNodes; + NextLevelNodes.Reset(); + ++Level; + } + + return Level; +} + +void UGenericGraph::GetNodesByLevel(int Level, TArray& Nodes) +{ + int CurrLEvel = 0; + TArray NextLevelNodes; + + Nodes = RootNodes; + + while (Nodes.Num() != 0) + { + if (CurrLEvel == Level) + break; + + for (int i = 0; i < Nodes.Num(); ++i) + { + UGenericGraphNode* Node = Nodes[i]; + check(Node != nullptr); + + for (int j = 0; j < Node->ChildrenNodes.Num(); ++j) + { + NextLevelNodes.Add(Node->ChildrenNodes[j]); + } + } + + Nodes = NextLevelNodes; + NextLevelNodes.Reset(); + ++CurrLEvel; + } +} + +void UGenericGraph::ClearGraph() +{ + for (int i = 0; i < AllNodes.Num(); ++i) + { + UGenericGraphNode* Node = AllNodes[i]; + if (Node) + { + Node->ParentNodes.Empty(); + Node->ChildrenNodes.Empty(); + Node->Edges.Empty(); + } + } + + AllNodes.Empty(); + RootNodes.Empty(); +} + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphEdge.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphEdge.cpp new file mode 100644 index 00000000..6d0118c7 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphEdge.cpp @@ -0,0 +1,23 @@ +#include "GenericGraphEdge.h" + +UGenericGraphEdge::UGenericGraphEdge() +{ + +} + +UGenericGraphEdge::~UGenericGraphEdge() +{ + +} + +UGenericGraph* UGenericGraphEdge::GetGraph() const +{ + return Graph; +} + +#if WITH_EDITOR +void UGenericGraphEdge::SetNodeTitle(const FText& NewTitle) +{ + NodeTitle = NewTitle; +} +#endif // #if WITH_EDITOR \ No newline at end of file diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphNode.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphNode.cpp new file mode 100644 index 00000000..548cdc3b --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphNode.cpp @@ -0,0 +1,90 @@ +#include "GenericGraphNode.h" +#include "GenericGraph.h" + +#define LOCTEXT_NAMESPACE "GenericGraphNode" + +UGenericGraphNode::UGenericGraphNode() +{ +#if WITH_EDITORONLY_DATA + CompatibleGraphType = UGenericGraph::StaticClass(); + + BackgroundColor = FLinearColor::Black; +#endif +} + +UGenericGraphNode::~UGenericGraphNode() +{ +} + +UGenericGraphEdge* UGenericGraphNode::GetEdge(UGenericGraphNode* ChildNode) +{ + return Edges.Contains(ChildNode) ? Edges.FindChecked(ChildNode) : nullptr; +} + +FText UGenericGraphNode::GetDescription_Implementation() const +{ + return LOCTEXT("NodeDesc", "Generic Graph Node"); +} + +#if WITH_EDITOR +bool UGenericGraphNode::IsNameEditable() const +{ + return true; +} + +FLinearColor UGenericGraphNode::GetBackgroundColor() const +{ + return BackgroundColor; +} + +FText UGenericGraphNode::GetNodeTitle() const +{ + return NodeTitle.IsEmpty() ? GetDescription() : NodeTitle; +} + +void UGenericGraphNode::SetNodeTitle(const FText& NewTitle) +{ + NodeTitle = NewTitle; +} + +bool UGenericGraphNode::CanCreateConnection(UGenericGraphNode* Other, FText& ErrorMessage) +{ + return true; +} + +bool UGenericGraphNode::CanCreateConnectionTo(UGenericGraphNode* Other, int32 NumberOfChildrenNodes, FText& ErrorMessage) +{ + if (ChildrenLimitType == ENodeLimit::Limited && NumberOfChildrenNodes >= ChildrenLimit) + { + ErrorMessage = FText::FromString("Children limit exceeded"); + return false; + } + + return CanCreateConnection(Other, ErrorMessage); +} + +bool UGenericGraphNode::CanCreateConnectionFrom(UGenericGraphNode* Other, int32 NumberOfParentNodes, FText& ErrorMessage) +{ + if (ParentLimitType == ENodeLimit::Limited && NumberOfParentNodes >= ParentLimit) + { + ErrorMessage = FText::FromString("Parent limit exceeded"); + return false; + } + + return true; +} + + +#endif + +bool UGenericGraphNode::IsLeafNode() const +{ + return ChildrenNodes.Num() == 0; +} + +UGenericGraph* UGenericGraphNode::GetGraph() const +{ + return Graph; +} + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphRuntime.cpp b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphRuntime.cpp new file mode 100644 index 00000000..bfc33a53 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphRuntime.cpp @@ -0,0 +1,29 @@ +#include "GenericGraphRuntimePCH.h" + +DEFINE_LOG_CATEGORY(GenericGraphRuntime) + +class FGenericGraphRuntime : public IGenericGraphRuntime +{ + /** IModuleInterface implementation */ + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; + +IMPLEMENT_MODULE( FGenericGraphRuntime, GenericGraphRuntime ) + + + +void FGenericGraphRuntime::StartupModule() +{ + // This code will execute after your module is loaded into memory (but after global variables are initialized, of course.) +} + + +void FGenericGraphRuntime::ShutdownModule() +{ + // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, + // we call this function before unloading the module. +} + + + diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphRuntimePCH.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphRuntimePCH.h new file mode 100644 index 00000000..18feed8f --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Private/GenericGraphRuntimePCH.h @@ -0,0 +1,12 @@ +#pragma once + +// #include "CoreUObject.h" +// #include "Engine.h" + +// You should place include statements to your module's private header files here. You only need to +// add includes for headers that are used in most of your module's source files though. +#include "IGenericGraphRuntime.h" + +#define LOG_INFO(FMT, ...) UE_LOG(GenericGraphRuntime, Display, (FMT), ##__VA_ARGS__) +#define LOG_WARNING(FMT, ...) UE_LOG(GenericGraphRuntime, Warning, (FMT), ##__VA_ARGS__) +#define LOG_ERROR(FMT, ...) UE_LOG(GenericGraphRuntime, Error, (FMT), ##__VA_ARGS__) diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraph.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraph.h new file mode 100644 index 00000000..1ac0d39d --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraph.h @@ -0,0 +1,60 @@ +#pragma once + +#include "CoreMinimal.h" +#include "GenericGraphNode.h" +#include "GenericGraphEdge.h" +#include "GameplayTagContainer.h" +#include "GenericGraph.generated.h" + +UCLASS(Blueprintable) +class GENERICGRAPHRUNTIME_API UGenericGraph : public UObject +{ + GENERATED_BODY() + +public: + UGenericGraph(); + virtual ~UGenericGraph(); + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraph") + FString Name; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraph") + TSubclassOf NodeType; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraph") + TSubclassOf EdgeType; + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "GenericGraph") + FGameplayTagContainer GraphTags; + + UPROPERTY(BlueprintReadOnly, Category = "GenericGraph") + TArray RootNodes; + + UPROPERTY(BlueprintReadOnly, Category = "GenericGraph") + TArray AllNodes; + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "GenericGraph") + bool bEdgeEnabled; + + UFUNCTION(BlueprintCallable, Category = "GenericGraph") + void Print(bool ToConsole = true, bool ToScreen = true); + + UFUNCTION(BlueprintCallable, Category = "GenericGraph") + int GetLevelNum() const; + + UFUNCTION(BlueprintCallable, Category = "GenericGraph") + void GetNodesByLevel(int Level, TArray& Nodes); + + void ClearGraph(); + +#if WITH_EDITORONLY_DATA + UPROPERTY() + class UEdGraph* EdGraph; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraph_Editor") + bool bCanRenameNode; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraph_Editor") + bool bCanBeCyclical; +#endif +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraphEdge.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraphEdge.h new file mode 100644 index 00000000..3df297b4 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraphEdge.h @@ -0,0 +1,48 @@ +#pragma once + +#include "CoreMinimal.h" +#include "GenericGraphNode.h" +#include "GenericGraphEdge.generated.h" + +class UGenericGraph; + +UCLASS(Blueprintable) +class GENERICGRAPHRUNTIME_API UGenericGraphEdge : public UObject +{ + GENERATED_BODY() + +public: + UGenericGraphEdge(); + virtual ~UGenericGraphEdge(); + + UPROPERTY(VisibleAnywhere, Category = "GenericGraphNode") + UGenericGraph* Graph; + + UPROPERTY(BlueprintReadOnly, Category = "GenericGraphEdge") + UGenericGraphNode* StartNode; + + UPROPERTY(BlueprintReadOnly, Category = "GenericGraphEdge") + UGenericGraphNode* EndNode; + + UFUNCTION(BlueprintPure, Category = "GenericGraphEdge") + UGenericGraph* GetGraph() const; + +#if WITH_EDITORONLY_DATA + UPROPERTY(EditDefaultsOnly, Category = "GenericGraphNode_Editor") + bool bShouldDrawTitle = false; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraphNode_Editor") + FText NodeTitle; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraphEdge") + FLinearColor EdgeColour = FLinearColor(0.9f, 0.9f, 0.9f, 1.0f); +#endif + +#if WITH_EDITOR + virtual FText GetNodeTitle() const { return NodeTitle; } + FLinearColor GetEdgeColour() { return EdgeColour; } + + virtual void SetNodeTitle(const FText& NewTitle); +#endif + +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraphNode.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraphNode.h new file mode 100644 index 00000000..965d109e --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/GenericGraphNode.h @@ -0,0 +1,94 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Templates/SubclassOf.h" +#include "GenericGraphNode.generated.h" + +class UGenericGraph; +class UGenericGraphEdge; + +UENUM(BlueprintType) +enum class ENodeLimit : uint8 +{ + Unlimited, + Limited +}; + + +UCLASS(Blueprintable) +class GENERICGRAPHRUNTIME_API UGenericGraphNode : public UObject +{ + GENERATED_BODY() + +public: + UGenericGraphNode(); + virtual ~UGenericGraphNode(); + + UPROPERTY(VisibleDefaultsOnly, Category = "GenericGraphNode") + UGenericGraph* Graph; + + UPROPERTY(BlueprintReadOnly, Category = "GenericGraphNode") + TArray ParentNodes; + + UPROPERTY(BlueprintReadOnly, Category = "GenericGraphNode") + TArray ChildrenNodes; + + UPROPERTY(BlueprintReadOnly, Category = "GenericGraphNode") + TMap Edges; + + UFUNCTION(BlueprintCallable, Category = "GenericGraphNode") + virtual UGenericGraphEdge* GetEdge(UGenericGraphNode* ChildNode); + + UFUNCTION(BlueprintCallable, Category = "GenericGraphNode") + bool IsLeafNode() const; + + UFUNCTION(BlueprintCallable, Category = "GenericGraphNode") + UGenericGraph* GetGraph() const; + + UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "GenericGraphNode") + FText GetDescription() const; + virtual FText GetDescription_Implementation() const; + + ////////////////////////////////////////////////////////////////////////// +#if WITH_EDITORONLY_DATA + UPROPERTY(EditDefaultsOnly, Category = "GenericGraphNode_Editor") + FText NodeTitle; + + UPROPERTY(VisibleDefaultsOnly, Category = "GenericGraphNode_Editor") + TSubclassOf CompatibleGraphType; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraphNode_Editor") + FLinearColor BackgroundColor; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraphNode_Editor") + FText ContextMenuName; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraphNode_Editor") + ENodeLimit ParentLimitType; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraphNode_Editor" ,meta = (ClampMin = "0",EditCondition = "ParentLimitType == ENodeLimit::Limited", EditConditionHides)) + int32 ParentLimit; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraphNode_Editor") + ENodeLimit ChildrenLimitType; + + UPROPERTY(EditDefaultsOnly, Category = "GenericGraphNode_Editor" ,meta = (ClampMin = "0",EditCondition = "ChildrenLimitType == ENodeLimit::Limited", EditConditionHides)) + int32 ChildrenLimit; + +#endif + +#if WITH_EDITOR + virtual bool IsNameEditable() const; + + virtual FLinearColor GetBackgroundColor() const; + + virtual FText GetNodeTitle() const; + + virtual void SetNodeTitle(const FText& NewTitle); + + virtual bool CanCreateConnection(UGenericGraphNode* Other, FText& ErrorMessage); + + virtual bool CanCreateConnectionTo(UGenericGraphNode* Other, int32 NumberOfChildrenNodes, FText& ErrorMessage); + virtual bool CanCreateConnectionFrom(UGenericGraphNode* Other, int32 NumberOfParentNodes, FText& ErrorMessage); +#endif +}; diff --git a/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/IGenericGraphRuntime.h b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/IGenericGraphRuntime.h new file mode 100644 index 00000000..f978a2b6 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/Source/GenericGraphRuntime/Public/IGenericGraphRuntime.h @@ -0,0 +1,36 @@ +#pragma once + +#include "Modules/ModuleManager.h" + +DECLARE_LOG_CATEGORY_EXTERN(GenericGraphRuntime, Log, All); + +/** + * The public interface to this module + */ +class IGenericGraphRuntime : public IModuleInterface +{ + +public: + + /** + * Singleton-like access to this module's interface. This is just for convenience! + * Beware of calling this during the shutdown phase, though. Your module might have been unloaded already. + * + * @return Returns singleton instance, loading the module on demand if needed + */ + static IGenericGraphRuntime& Get() + { + return FModuleManager::LoadModuleChecked< IGenericGraphRuntime >("GenericGraphRuntime"); + } + + /** + * Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true. + * + * @return True if the module is loaded and ready to use + */ + static bool IsAvailable() + { + return FModuleManager::Get().IsModuleLoaded( "GenericGraphRuntime" ); + } +}; + diff --git a/EndlessVendetta/Plugins/GenericGraph/docs/images/GenericGraph.png b/EndlessVendetta/Plugins/GenericGraph/docs/images/GenericGraph.png new file mode 100644 index 00000000..0d899979 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/docs/images/GenericGraph.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:092185ad7a9989a69ba9543793326cf0f893fcc1a0895de65db3ca24ee7c970a +size 89534 diff --git a/EndlessVendetta/Plugins/GenericGraph/docs/images/ability-graph.png b/EndlessVendetta/Plugins/GenericGraph/docs/images/ability-graph.png new file mode 100644 index 00000000..b65adf2a --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/docs/images/ability-graph.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e97bb76a079e7e37c685cfa0f480c4028be755577939d8ae3d51be6e5571112c +size 114519 diff --git a/EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue01.png b/EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue01.png new file mode 100644 index 00000000..7fbb5326 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue01.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95ab320c78c5ed1a79b78686a9e453bf459805b71ca6b855305f2ac328103d9e +size 98959 diff --git a/EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue02.png b/EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue02.png new file mode 100644 index 00000000..c03fde96 --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue02.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbbb01dc0b5af841164b8baeeebfb5aa769cb0710482f6accd984d02e0586eb9 +size 94706 diff --git a/EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue03.png b/EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue03.png new file mode 100644 index 00000000..ec53962e --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/docs/images/dialogue/dialogue03.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a51f6bd700c3346982c523d3c6e535cadb7ec8f0dc6c806bd5c481e961e8969c +size 95655 diff --git a/EndlessVendetta/Plugins/GenericGraph/readme.rst b/EndlessVendetta/Plugins/GenericGraph/readme.rst new file mode 100644 index 00000000..f76c40ba --- /dev/null +++ b/EndlessVendetta/Plugins/GenericGraph/readme.rst @@ -0,0 +1,51 @@ +GenericGraphPlugin +================== + +Generic graph data structure plugin for ue4 + +.. image:: docs/images/GenericGraph.png + +Feature +------- + +* Custom asset type +* UE4 BehaviorTree-like asset editor +* Extendable graph node type +* Extendable graph edge type +* Extendable graph type(new asset type with generic graph editor, C++ only) + +Usage +----- + +* Ability system +* Dialogue system +* Quest system +* Etc + +Install +------- + +#. Clone this project to ${YourProject}/Plugins/ +#. Generate project file +#. Compile + +Tutorial +-------- + +`Dialogue System`_ (WIP) + +Example +------- + +Dialogue System and ability system: SRPGTemplate_ + +.. image:: docs/images/dialogue/dialogue01.png + +.. image:: docs/images/dialogue/dialogue02.png + +.. image:: docs/images/dialogue/dialogue03.png + +.. image:: docs/images/ability-graph.png + +.. _Dialogue System: https://jinyuliao.github.io/blog/html/2017/12/15/ue4_dialogue_system_part1.html +.. _SRPGTemplate: https://github.com/jinyuliao/SRPGTemplate From d736224daa51c0c7ccead606c42386d4a2ee687b Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Mon, 20 Nov 2023 21:26:49 +0000 Subject: [PATCH 02/99] Add DialogueSystemEditor Module for Tree Factory --- .../DialogueSystemEditor.Build.cs | 36 +++++++++++++++++++ .../Private/DialogueSystemEditor.cpp | 17 +++++++++ .../Private/DialogueTreeFactory.cpp | 28 +++++++++++++++ .../Private/DialogueTreeFactory.h | 18 ++++++++++ .../Public/DialogueSystemEditor.h | 11 ++++++ 5 files changed, 110 insertions(+) create mode 100644 EndlessVendetta/Source/DialogueSystemEditor/DialogueSystemEditor.Build.cs create mode 100644 EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueSystemEditor.cpp create mode 100644 EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueTreeFactory.cpp create mode 100644 EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueTreeFactory.h create mode 100644 EndlessVendetta/Source/DialogueSystemEditor/Public/DialogueSystemEditor.h diff --git a/EndlessVendetta/Source/DialogueSystemEditor/DialogueSystemEditor.Build.cs b/EndlessVendetta/Source/DialogueSystemEditor/DialogueSystemEditor.Build.cs new file mode 100644 index 00000000..63486a00 --- /dev/null +++ b/EndlessVendetta/Source/DialogueSystemEditor/DialogueSystemEditor.Build.cs @@ -0,0 +1,36 @@ +using UnrealBuildTool; + +public class DialogueSystemEditor : ModuleRules +{ + public DialogueSystemEditor(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PublicIncludePaths.AddRange( + new string[] + { + "EndlessVendetta/DialogueSystem" + } + ); + + PublicDependencyModuleNames.AddRange( + new string[] + { + "Core", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "CoreUObject", + "Engine", + "Slate", + "SlateCore", + "UnrealEd", + "GenericGraphRuntime", + "EndlessVendetta" + } + ); + } +} \ No newline at end of file diff --git a/EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueSystemEditor.cpp b/EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueSystemEditor.cpp new file mode 100644 index 00000000..7a4fad39 --- /dev/null +++ b/EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueSystemEditor.cpp @@ -0,0 +1,17 @@ +#include "DialogueSystemEditor.h" + +#define LOCTEXT_NAMESPACE "FDialogueSystemEditorModule" + +void FDialogueSystemEditorModule::StartupModule() +{ + +} + +void FDialogueSystemEditorModule::ShutdownModule() +{ + +} + +#undef LOCTEXT_NAMESPACE + +IMPLEMENT_MODULE(FDialogueSystemEditorModule, DialogueSystemEditor) \ No newline at end of file diff --git a/EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueTreeFactory.cpp b/EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueTreeFactory.cpp new file mode 100644 index 00000000..a1f39692 --- /dev/null +++ b/EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueTreeFactory.cpp @@ -0,0 +1,28 @@ +#include "DialogueTreeFactory.h" +#include "DialogueTree.h" + +#define LOCTEXT_NAMESPACE "DialogueSessionFactory" + +UDialogueTreeFactory::UDialogueTreeFactory() +{ + bCreateNew = true; + bEditAfterNew = true; + SupportedClass = UDialogueTree::StaticClass(); +} + +UObject* UDialogueTreeFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) +{ + return NewObject(InParent, Class, Name, Flags | RF_Transactional); +} + +FText UDialogueTreeFactory::GetDisplayName() const +{ + return LOCTEXT("FactoryName", "Dialogue Tree"); +} + +FString UDialogueTreeFactory::GetDefaultNewAssetName() const +{ + return "DialogueTree"; +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueTreeFactory.h b/EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueTreeFactory.h new file mode 100644 index 00000000..80d6f49d --- /dev/null +++ b/EndlessVendetta/Source/DialogueSystemEditor/Private/DialogueTreeFactory.h @@ -0,0 +1,18 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Factories/Factory.h" +#include "DialogueTreeFactory.generated.h" + +UCLASS() +class UDialogueTreeFactory : public UFactory +{ + GENERATED_BODY() + +public: + UDialogueTreeFactory(); + + virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override; + virtual FText GetDisplayName() const override; + virtual FString GetDefaultNewAssetName() const override; +}; \ No newline at end of file diff --git a/EndlessVendetta/Source/DialogueSystemEditor/Public/DialogueSystemEditor.h b/EndlessVendetta/Source/DialogueSystemEditor/Public/DialogueSystemEditor.h new file mode 100644 index 00000000..3333f03a --- /dev/null +++ b/EndlessVendetta/Source/DialogueSystemEditor/Public/DialogueSystemEditor.h @@ -0,0 +1,11 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Modules/ModuleManager.h" + +class FDialogueSystemEditorModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; From 74ea72c76caf96b10072f8ccbd52176d24ca768c Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Mon, 20 Nov 2023 21:28:08 +0000 Subject: [PATCH 03/99] Add Custom Dialogue Graph for Dialogue Trees --- EndlessVendetta/EndlessVendetta.uproject | 5 ++ .../Source/EndlessVendetta.Target.cs | 6 +++ .../DialogueSystem/DialogueAddItemNode.cpp | 39 +++++++++++++++ .../DialogueSystem/DialogueAddItemNode.h | 24 ++++++++++ .../DialogueSystem/DialogueEdge.h | 16 +++++++ .../DialogueSystem/DialogueTextNode.cpp | 47 +++++++++++++++++++ .../DialogueSystem/DialogueTextNode.h | 34 ++++++++++++++ .../DialogueSystem/DialogueTree.cpp | 18 +++++++ .../DialogueSystem/DialogueTree.h | 20 ++++++++ .../EndlessVendetta/EndlessVendetta.Build.cs | 2 + .../Source/EndlessVendettaEditor.Target.cs | 6 +++ 11 files changed, 217 insertions(+) create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueAddItemNode.cpp create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueAddItemNode.h create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueEdge.h create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.h create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.h diff --git a/EndlessVendetta/EndlessVendetta.uproject b/EndlessVendetta/EndlessVendetta.uproject index 340e263e..52239fa2 100644 --- a/EndlessVendetta/EndlessVendetta.uproject +++ b/EndlessVendetta/EndlessVendetta.uproject @@ -14,6 +14,11 @@ "CoreUObject", "UMG" ] + }, + { + "Name": "DialogueSystemEditor", + "Type": "Editor", + "LoadingPhase": "PostEngineInit" } ], "Plugins": [ diff --git a/EndlessVendetta/Source/EndlessVendetta.Target.cs b/EndlessVendetta/Source/EndlessVendetta.Target.cs index b31c5112..0bfa1565 100644 --- a/EndlessVendetta/Source/EndlessVendetta.Target.cs +++ b/EndlessVendetta/Source/EndlessVendetta.Target.cs @@ -11,5 +11,11 @@ public class EndlessVendettaTarget : TargetRules DefaultBuildSettings = BuildSettingsVersion.V2; IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1; ExtraModuleNames.Add("EndlessVendetta"); + RegisterModulesCreatedByRider(); + } + + private void RegisterModulesCreatedByRider() + { + ExtraModuleNames.AddRange(new string[] { "DialogueSystemEditor" }); } } diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueAddItemNode.cpp b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueAddItemNode.cpp new file mode 100644 index 00000000..8adadbb7 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueAddItemNode.cpp @@ -0,0 +1,39 @@ +#include "DialogueAddItemNode.h" +#include "DialogueTree.h" + +#define LOCTEXT_NAMESPACE "UDialogueTextNode" + +UDialogueAddItemNode::UDialogueAddItemNode() +{ +#if WITH_EDITORONLY_DATA + CompatibleGraphType = UDialogueTree::StaticClass(); + + ContextMenuName = LOCTEXT("ConextMenuName", "Add Item Node"); +#endif +} + +#if WITH_EDITOR + +FText UDialogueAddItemNode::GetNodeTitle() const +{ + return Bruh; +} + +void UDialogueAddItemNode::SetNodeTitle(const FText& NewTitle) +{ + Bruh = NewTitle; +} + +FLinearColor UDialogueAddItemNode::GetBackgroundColor() const +{ + const UDialogueTree* DialogueTree = Cast(GetGraph()); + + if (DialogueTree == nullptr) + return Super::GetBackgroundColor(); + + return FLinearColor::Black; +} + +#endif + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueAddItemNode.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueAddItemNode.h new file mode 100644 index 00000000..b52856e6 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueAddItemNode.h @@ -0,0 +1,24 @@ +#pragma once + +#include "CoreMinimal.h" +#include "GenericGraphNode.h" +#include "DialogueAddItemNode.generated.h" + +UCLASS(Blueprintable) +class UDialogueAddItemNode : public UGenericGraphNode +{ + GENERATED_BODY() +public: + UDialogueAddItemNode(); + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue") + FText Bruh; + +#if WITH_EDITOR + virtual FText GetNodeTitle() const override; + + virtual void SetNodeTitle(const FText& NewTitle) override; + + virtual FLinearColor GetBackgroundColor() const override; +#endif +}; \ No newline at end of file diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueEdge.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueEdge.h new file mode 100644 index 00000000..72d6491b --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueEdge.h @@ -0,0 +1,16 @@ +#pragma once + +#include "CoreMinimal.h" +#include "GenericGraphEdge.h" +#include "DialogueEdge.generated.h" + + +UCLASS(Blueprintable) +class UDialogueEdge: public UGenericGraphEdge +{ + GENERATED_BODY() + +public: + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue") + FText Selection; +}; \ No newline at end of file diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp new file mode 100644 index 00000000..8b61bba0 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp @@ -0,0 +1,47 @@ +#include "DialogueTextNode.h" +#include "DialogueTree.h" + +#define LOCTEXT_NAMESPACE "UDialogueTextNode" + +UDialogueTextNode::UDialogueTextNode() +{ +#if WITH_EDITORONLY_DATA + CompatibleGraphType = UDialogueTree::StaticClass(); + + ContextMenuName = LOCTEXT("ConextMenuName", "Dialogue Node"); +#endif +} + +#if WITH_EDITOR + +FText UDialogueTextNode::GetNodeTitle() const +{ + return Text.IsEmpty() ? LOCTEXT("EmptyParagraph", "(Empty paragraph)") : Text; +} + +void UDialogueTextNode::SetNodeTitle(const FText& NewTitle) +{ + Text = NewTitle; +} + +FLinearColor UDialogueTextNode::GetBackgroundColor() const +{ + const UDialogueTree* DialogueTree = Cast(GetGraph()); + + if (DialogueTree == nullptr) + return Super::GetBackgroundColor(); + + switch (DialoguePosition) + { + case EDialoguePosition::Left: + return DialogueTree->LeftDialogueBgColor; + case EDialoguePosition::Right: + return DialogueTree->RightDialogueBgColor; + default: + return FLinearColor::Black; + } +} + +#endif + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.h new file mode 100644 index 00000000..6ff78b28 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.h @@ -0,0 +1,34 @@ +#pragma once + +#include "CoreMinimal.h" +#include "GenericGraphNode.h" +#include "DialogueTextNode.generated.h" + +UENUM(BlueprintType) +enum class EDialoguePosition : uint8 +{ + Left, + Right +}; + +UCLASS(Blueprintable) +class UDialogueTextNode : public UGenericGraphNode +{ + GENERATED_BODY() +public: + UDialogueTextNode(); + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue") + FText Text; + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue") + EDialoguePosition DialoguePosition; + +#if WITH_EDITOR + virtual FText GetNodeTitle() const override; + + virtual void SetNodeTitle(const FText& NewTitle) override; + + virtual FLinearColor GetBackgroundColor() const override; +#endif +}; \ No newline at end of file diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp new file mode 100644 index 00000000..903afba3 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp @@ -0,0 +1,18 @@ +#include "DialogueTree.h" +#include "DialogueTextNode.h" +#include "DialogueEdge.h" + +#define LOCTEXT_NAMESPACE "DialogueSession" + +UDialogueTree::UDialogueTree() +{ + NodeType = UGenericGraphNode::StaticClass(); + EdgeType = UDialogueEdge::StaticClass(); + + LeftDialogueBgColor = FLinearColor::Black; + RightDialogueBgColor = FLinearColor(0.93f, 0.93f, 0.93f, 1.f); + + Name = "Dialogue Tree"; +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.h new file mode 100644 index 00000000..8150ba61 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.h @@ -0,0 +1,20 @@ +#pragma once + +#include "CoreMinimal.h" +#include "GenericGraph.h" +#include "DialogueTree.generated.h" + +UCLASS(Blueprintable) +class ENDLESSVENDETTA_API UDialogueTree: public UGenericGraph +{ + GENERATED_BODY() + +public: + UDialogueTree(); + + UPROPERTY(EditDefaultsOnly, Category = "Dialogue") + FLinearColor LeftDialogueBgColor; + + UPROPERTY(EditDefaultsOnly, Category = "Dialogue") + FLinearColor RightDialogueBgColor; +}; \ No newline at end of file diff --git a/EndlessVendetta/Source/EndlessVendetta/EndlessVendetta.Build.cs b/EndlessVendetta/Source/EndlessVendetta/EndlessVendetta.Build.cs index 3149aa96..8edf6d38 100644 --- a/EndlessVendetta/Source/EndlessVendetta/EndlessVendetta.Build.cs +++ b/EndlessVendetta/Source/EndlessVendetta/EndlessVendetta.Build.cs @@ -13,5 +13,7 @@ public class EndlessVendetta : ModuleRules "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "EnhancedInput", "AIModule", "GameplayTasks", "NavigationSystem", "UMG", "Slate", "SlateCore", "Niagara", "NiagaraCore", "NiagaraShader" }); + + PrivateDependencyModuleNames.AddRange(new string[] { "GenericGraphRuntime" }); } } \ No newline at end of file diff --git a/EndlessVendetta/Source/EndlessVendettaEditor.Target.cs b/EndlessVendetta/Source/EndlessVendettaEditor.Target.cs index 2dc48be0..f57382d6 100644 --- a/EndlessVendetta/Source/EndlessVendettaEditor.Target.cs +++ b/EndlessVendetta/Source/EndlessVendettaEditor.Target.cs @@ -11,5 +11,11 @@ public class EndlessVendettaEditorTarget : TargetRules DefaultBuildSettings = BuildSettingsVersion.V2; IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1; ExtraModuleNames.Add("EndlessVendetta"); + RegisterModulesCreatedByRider(); + } + + private void RegisterModulesCreatedByRider() + { + ExtraModuleNames.AddRange(new string[] { "DialogueSystemEditor" }); } } From 88ce6876a6f40ad22219e7c0f66b11c04f99cbca Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Thu, 30 Nov 2023 11:10:05 +0000 Subject: [PATCH 04/99] Add Conthrax & Oxanium Fonts to Engine --- .../Content/Fonts/Conthrax/conthrax-sb.uasset | 3 + .../Fonts/Conthrax/conthrax-sb_Font.uasset | 3 + .../Content/Fonts/Oxanium/Oxanium-Bold.uasset | 3 + .../Fonts/Oxanium/Oxanium-Bold_Font.uasset | 3 + .../Fonts/Oxanium/Oxanium-ExtraBold.uasset | 3 + .../Oxanium/Oxanium-ExtraBold_Font.uasset | 3 + .../Fonts/Oxanium/Oxanium-ExtraLight.uasset | 3 + .../Oxanium/Oxanium-ExtraLight_Font.uasset | 3 + .../Fonts/Oxanium/Oxanium-Light.uasset | 3 + .../Fonts/Oxanium/Oxanium-Light_Font.uasset | 3 + .../Fonts/Oxanium/Oxanium-Medium.uasset | 3 + .../Fonts/Oxanium/Oxanium-Medium_Font.uasset | 3 + .../Fonts/Oxanium/Oxanium-Regular.uasset | 3 + .../Fonts/Oxanium/Oxanium-Regular_Font.uasset | 3 + .../Fonts/Oxanium/Oxanium-SemiBold.uasset | 3 + .../Oxanium/Oxanium-SemiBold_Font.uasset | 3 + .../conthrax/Typodermic Desktop EULA 2023.pdf | 3 + .../Fonts/conthrax/conthrax-sb.otf | 3 + External Assets/Fonts/conthrax/read-this.html | 1699 +++++++++++++++++ External Assets/Fonts/oxanium/FONTLOG.txt | 53 + External Assets/Fonts/oxanium/LICENSE.txt | 93 + .../Fonts/oxanium/Oxanium-Bold.ttf | 3 + .../Fonts/oxanium/Oxanium-ExtraBold.ttf | 3 + .../Fonts/oxanium/Oxanium-ExtraLight.ttf | 3 + .../Fonts/oxanium/Oxanium-Light.ttf | 3 + .../Fonts/oxanium/Oxanium-Medium.ttf | 3 + .../Fonts/oxanium/Oxanium-Regular.ttf | 3 + .../Fonts/oxanium/Oxanium-SemiBold.ttf | 3 + External Assets/Fonts/oxanium/Oxanium.png | 3 + 29 files changed, 1923 insertions(+) create mode 100644 EndlessVendetta/Content/Fonts/Conthrax/conthrax-sb.uasset create mode 100644 EndlessVendetta/Content/Fonts/Conthrax/conthrax-sb_Font.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Bold.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Bold_Font.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraBold.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraBold_Font.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraLight.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraLight_Font.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Light.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Light_Font.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Medium.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Medium_Font.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Regular.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Regular_Font.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-SemiBold.uasset create mode 100644 EndlessVendetta/Content/Fonts/Oxanium/Oxanium-SemiBold_Font.uasset create mode 100644 External Assets/Fonts/conthrax/Typodermic Desktop EULA 2023.pdf create mode 100644 External Assets/Fonts/conthrax/conthrax-sb.otf create mode 100644 External Assets/Fonts/conthrax/read-this.html create mode 100644 External Assets/Fonts/oxanium/FONTLOG.txt create mode 100644 External Assets/Fonts/oxanium/LICENSE.txt create mode 100644 External Assets/Fonts/oxanium/Oxanium-Bold.ttf create mode 100644 External Assets/Fonts/oxanium/Oxanium-ExtraBold.ttf create mode 100644 External Assets/Fonts/oxanium/Oxanium-ExtraLight.ttf create mode 100644 External Assets/Fonts/oxanium/Oxanium-Light.ttf create mode 100644 External Assets/Fonts/oxanium/Oxanium-Medium.ttf create mode 100644 External Assets/Fonts/oxanium/Oxanium-Regular.ttf create mode 100644 External Assets/Fonts/oxanium/Oxanium-SemiBold.ttf create mode 100644 External Assets/Fonts/oxanium/Oxanium.png diff --git a/EndlessVendetta/Content/Fonts/Conthrax/conthrax-sb.uasset b/EndlessVendetta/Content/Fonts/Conthrax/conthrax-sb.uasset new file mode 100644 index 00000000..61def072 --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Conthrax/conthrax-sb.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d48b68f103c839f484864e16b1c70825eca0272b7658887945efe190eb61a9a +size 154427 diff --git a/EndlessVendetta/Content/Fonts/Conthrax/conthrax-sb_Font.uasset b/EndlessVendetta/Content/Fonts/Conthrax/conthrax-sb_Font.uasset new file mode 100644 index 00000000..0df62046 --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Conthrax/conthrax-sb_Font.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c83f32cb77196ba00771af4c65bafda85ec8cefcc88b79f278623c7ba3c824a +size 6544 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Bold.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Bold.uasset new file mode 100644 index 00000000..6ccdae65 --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Bold.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b653e74a78e127d4fc9dd2b86bc02a6f3db120d8ceb5a19164e13dea5ae93b57 +size 57094 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Bold_Font.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Bold_Font.uasset new file mode 100644 index 00000000..592af238 --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Bold_Font.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d29c99ed7afe6a7a4ab39261a8a5d47962c510846c56d76499fa820fc4e2ee60 +size 6405 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraBold.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraBold.uasset new file mode 100644 index 00000000..161fff54 --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraBold.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dfc9c97c08173fe375d30d4f16ec209499c14a077136050883a4ae27985891b7 +size 57221 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraBold_Font.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraBold_Font.uasset new file mode 100644 index 00000000..4f762266 --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraBold_Font.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c4ed01d92f0b771b7bb4d906b094a4be893e4ed48a4a0c36f1a232fa4078a13 +size 6511 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraLight.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraLight.uasset new file mode 100644 index 00000000..57f022dc --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraLight.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2a0d57985ba024b3f880f2767ff8b875d70ad3419a6fc163db97435e271b265 +size 57352 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraLight_Font.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraLight_Font.uasset new file mode 100644 index 00000000..8343f26b --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-ExtraLight_Font.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32ead0bdec890960b8379909515ab973d1a72e8dcfddc1fb83951b0d978c07ac +size 6397 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Light.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Light.uasset new file mode 100644 index 00000000..c8e8d3c3 --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Light.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:523ae9c30e94afaec9568627e44082b9ceacecd2a88c3589a520e638b02a73f6 +size 57233 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Light_Font.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Light_Font.uasset new file mode 100644 index 00000000..f96aabbd --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Light_Font.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6361409472cd93b6bc9b06a061e275e3bb43e8fb90ac974a0ed279ba1a3c80b7 +size 6320 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Medium.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Medium.uasset new file mode 100644 index 00000000..13ce41e9 --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Medium.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b9fb607be1b5aeb2161da1ab2f77d237307e3e2cc2eb9a6bce2ca55a27c8b18 +size 57216 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Medium_Font.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Medium_Font.uasset new file mode 100644 index 00000000..0d52c0ba --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Medium_Font.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c764f1fa07a8736117f6c1a6c748cc7604f04b4980f7204b2e4915975e85e43 +size 6485 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Regular.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Regular.uasset new file mode 100644 index 00000000..83319abe --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Regular.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83bdf29373fca452a260331538560971cfc7770ca021cf312955b899f358cf13 +size 57155 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Regular_Font.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Regular_Font.uasset new file mode 100644 index 00000000..6bef215d --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-Regular_Font.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0981619a0267c6a381b1c9c18e4335ffdb52df11e0e77293771512ab33263aed +size 6479 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-SemiBold.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-SemiBold.uasset new file mode 100644 index 00000000..5db5b16c --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-SemiBold.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3fe22e46ed7b55f8eddab603d0619c96ef21afac64fff1f736c237ee1b37421 +size 57234 diff --git a/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-SemiBold_Font.uasset b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-SemiBold_Font.uasset new file mode 100644 index 00000000..ae0d41cc --- /dev/null +++ b/EndlessVendetta/Content/Fonts/Oxanium/Oxanium-SemiBold_Font.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:216d140f81e1f045143e623730dcf07185008cd2e3e800fd81d9149f5a8606e9 +size 6522 diff --git a/External Assets/Fonts/conthrax/Typodermic Desktop EULA 2023.pdf b/External Assets/Fonts/conthrax/Typodermic Desktop EULA 2023.pdf new file mode 100644 index 00000000..cefa23b5 --- /dev/null +++ b/External Assets/Fonts/conthrax/Typodermic Desktop EULA 2023.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bb2b43ff7702f56eda9db0e18890bcf65de62ab93ddbbe58107fcdd62949b68 +size 145707 diff --git a/External Assets/Fonts/conthrax/conthrax-sb.otf b/External Assets/Fonts/conthrax/conthrax-sb.otf new file mode 100644 index 00000000..163e9d96 --- /dev/null +++ b/External Assets/Fonts/conthrax/conthrax-sb.otf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09df8d015fbbe7e5e2cc2d0f1b1fba6b14d0ae318ce087621c868b2856ed7756 +size 152848 diff --git a/External Assets/Fonts/conthrax/read-this.html b/External Assets/Fonts/conthrax/read-this.html new file mode 100644 index 00000000..b5fca4eb --- /dev/null +++ b/External Assets/Fonts/conthrax/read-this.html @@ -0,0 +1,1699 @@ + + +Typodermic Fonts Inc. Free Font Instructions 2023 + + + + + +
+ +

+Deutsch +Español +Français +العربية +中国简体 +簡體字 +Čeština +Ελληνικά +עִבְרִית +हिन्दी +Magyar +Íslenska +Indonesia +Italiano +한국말 +日本語 +Norsk +Język Polski +Português +ਪੰਜਾਬੀ +Română +Русский +Svenska +தமிழ் +ภาษาไทย +Türkçe +Українська мова +Tiếng Việt +

+ +

Thank you

+ +

Thanks for downloading a free font from Typodermic Fonts Inc. These fonts included in this ZIP include a free desktop license agreement which permits commercial use. Read the included license agreement for details.

+ + +

Installation

+
  • Windows: Get the font out of the ZIP. Right-click on the font and Install
  • Mac OS X 10.3 or above: Double-click the font file and Install font
+ +

Allowed

+ +
    +
  • art
  • +
  • sign
  • +
  • poster
  • +
  • banner
  • +
  • book
  • +
  • business card
  • +
  • album
  • +
  • movie
  • +
  • television
  • +
  • video/streaming/channels
  • +
  • logo
  • +
  • trademarked logo
  • +
  • clothing
  • +
  • sticker
  • +
  • stamp
  • +
  • product label
  • +
  • web page (not embedded)
  • +
  • app (not embedded)
  • +
  • PDF
  • +
  • eBook cover or images (not embedded)
  • +
+ +

Not allowed

+ +
    +
  • app (embedded)
  • +
  • web page (embedded)
  • +
  • eBook (embedded)
  • +
  • product creation platform
  • +
  • alphabet stamps
  • +
  • advertisment server
  • +
  • web template
  • +
  • OEM
  • +
  • device embedding
  • +
+ +

It’s easy to get a different license agreement. Read the this page for details.

+ +

Other styles

+ +

Many of Typodermic's free fonts have other styles available. Please visit Typodermic Fonts and search for the name of this font in the search bar.

+ +
+ +

Danke dir

+ +

Vielen Dank, dass Sie eine kostenlose Schriftart von heruntergeladen haben Typodermic Fonts Inc. Diese in diesem ZIP enthaltenen Schriftarten beinhalten eine kostenlose Desktop-Lizenzvereinbarung, die eine kommerzielle Nutzung erlaubt. Lesen Sie die beigefügte Lizenzvereinbarung für Details.

+ + +

Installation

+
  • Windows: Holen Sie sich die Schriftart aus dem ZIP. Klicken Sie mit der rechten Maustaste auf die Schriftart und installieren Sie si
  • Mac OS X 10.3 oder höher: Doppelklicken Sie auf die Schriftartdatei und Schriftart installieren
+ +

Erlaubt

+ +
    +
  • Kunst
  • +
  • Zeichen
  • +
  • Poster
  • +
  • Banner
  • +
  • Buchen
  • +
  • Visitenkarte
  • +
  • Album
  • +
  • Film
  • +
  • Fernsehen
  • +
  • Video/Streaming/Kanäle
  • +
  • Logo
  • +
  • markenrechtlich geschütztes Logo
  • +
  • Kleidung
  • +
  • Aufkleber
  • +
  • Briefmarke
  • +
  • Produktetikett
  • +
  • Webseite (nicht eingebettet)
  • +
  • App (nicht eingebettet)
  • +
  • PDF
  • +
  • eBook-Cover oder Bilder (nicht eingebettet)
  • +
+ +

Nicht erlaubt

+ +
    +
  • App (eingebettet)
  • +
  • Webseite (eingebettet)
  • +
  • eBook (eingebettet)
  • +
  • Produkterstellungsplattform
  • +
  • Alphabet-Briefmarken
  • +
  • Werbeserver
  • +
  • Web-Vorlage
  • +
  • Erstausrüster
  • +
  • Geräteeinbettung
  • +
+ +

Es ist einfach, eine andere Lizenzvereinbarung zu erhalten. Lesen Sie diese Seite für Details.

+ +

Andere Stile

+ +

Für viele der kostenlosen Schriftarten von Typodermic sind andere Stile verfügbar. Bitte besuchen Sie Typodermic Fonts und suchen Sie in der Suchleiste nach dem Namen dieser Schriftart.

+ + +
+ +

Gracias

+ +

Gracias por descargar una fuente gratuita de Typodermic Fonts Inc. Estas fuentes incluidas en este ZIP incluyen un acuerdo de licencia de escritorio gratuito que permite el uso comercial. Lea el acuerdo de licencia incluido para más detalles.

+ + +

Instalación

+
  • Windows: Saque la fuente del ZIP. Haga clic derecho en la fuente e instalar
  • Mac OS X 10.3 o superior: haga doble clic en el archivo de fuente e instale la fuente
+ +

Permitido

+ +
    +
  • Arte
  • +
  • signo
  • +
  • póster
  • +
  • bandera
  • +
  • libro
  • +
  • tarjeta de visita
  • +
  • álbum
  • +
  • película
  • +
  • televisión
  • +
  • video/transmisión/canales
  • +
  • logo
  • +
  • logotipo de marca registrada
  • +
  • ropa
  • +
  • pegatina
  • +
  • estampilla
  • +
  • etiqueta del producto
  • +
  • página web (no incrustada)
  • +
  • aplicación (no incrustada)
  • +
  • PDF
  • +
  • Portada del libro electrónico o imágenes (no incrustadas)
  • +
+ + +

No permitido

+ +
    +
  • aplicación (incrustada)
  • +
  • página web (incrustada)
  • +
  • eBook (incrustado)
  • +
  • plataforma de creación de productos
  • +
  • sellos del alfabeto
  • +
  • servidor de anuncios
  • +
  • plantilla web
  • +
  • OEM
  • +
  • incrustación de dispositivo
  • +
+ +

Es fácil obtener un acuerdo de licencia diferente. Lea esta página para más detalles.

+ +

Otros estilos

+ +

Muchas de las fuentes gratuitas de Typodermic tienen otros estilos disponibles. Visite Typodermic Fonts y busque el nombre de esta fuente en la barra de búsqueda.

+ + +
+ +

Merci

+ +

Merci d'avoir téléchargé une police gratuite sur Typodermic Fonts Inc. Ces polices incluses dans ce ZIP incluent un accord de licence de bureau gratuit qui permet une utilisation commerciale. Lisez le contrat de licence inclus pour plus de détails.

+ + +

Installation

+
  • Windows : extrayez la police du ZIP. Faites un clic droit sur la police et installez
  • Mac OS X 10.3 ou supérieur : double-cliquez sur le fichier de police et installez la police
+ + + + +

Autorisé

+ +
    +
  • de l'art
  • +
  • pancarte
  • +
  • affiche
  • +
  • bannière
  • +
  • livre
  • +
  • carte de visite
  • +
  • album
  • +
  • film
  • +
  • télévision
  • +
  • vidéo/streaming/chaînes
  • +
  • logo
  • +
  • logo de marque
  • +
  • Vêtements
  • +
  • autocollant
  • +
  • timbre
  • +
  • étiquette du produit
  • +
  • page Web (non intégrée)
  • +
  • application (non intégrée)
  • +
  • PDF
  • +
  • Couverture ou images d'eBook (non intégrées)
  • +
+ + + +

Interdit

+ +
    +
  • application (intégrée)
  • +
  • page Web (intégrée)
  • +
  • eBook (intégré)
  • +
  • plateforme de création de produits
  • +
  • timbres alphabétiques
  • +
  • serveur de publicité
  • +
  • modèle web
  • +
  • FEO
  • +
  • intégration de l'appareil
  • +
+ +

Il est facile d'obtenir un autre contrat de licence. Lisez cette page pour plus de détails.

+ +

Autres modèles

+ +

De nombreuses polices gratuites de Typodermic proposent d'autres styles. Veuillez visiter Typodermic Fonts et rechercher le nom de cette police dans la barre de recherche.

+ + +
+ +

شكرًا لك

+ +

+ +شكرا لتحميل الخط المجاني من Typodermic Fonts Inc. تتضمن هذه الخطوط المضمنة في ملف ZIP هذا اتفاقية ترخيص سطح مكتب مجانية تسمح بالاستخدام التجاري. اقرأ اتفاقية الترخيص المضمنة للحصول على التفاصيل.

+ + +

التركيب

+
  • Windows: أخرج الخط من ملف ZIP. انقر بزر الماوس الأيمن فوق الخط وتثبيت + نظام التشغيل
  • Mac OS X 10.3 أو إصدار أحدث: انقر نقرًا مزدوجًا فوق ملف الخط وقم بتثبيت الخط
+ +

مسموح

+ +
    +
  • فن
  • +
  • لافتة
  • +
  • ملصق
  • +
  • لافتة
  • +
  • كتاب
  • +
  • بطاقة العمل
  • +
  • الألبوم
  • +
  • فيلم
  • +
  • التلفاز
  • +
  • فيديو / تدفق / قنوات
  • +
  • شعار
  • +
  • شعار مسجّل كعلامة تجارية
  • +
  • ملابس
  • +
  • ملصق
  • +
  • ختم
  • +
  • ملصق المنتج
  • +
  • صفحة ويب (غير مضمنة)
  • +
  • التطبيق (غير مضمن)
  • +
  • بي دي إف
  • +
  • غلاف الكتاب الإلكتروني أو الصور (غير مضمنة)
  • +
+ +

غير مسموح

+ +
    +
  • التطبيق (مضمن)
  • +
  • صفحة الويب (مضمنة)
  • +
  • كتاب إلكتروني (مضمن)
  • +
  • منصة إنشاء المنتجات
  • +
  • طوابع الأبجدية
  • +
  • خادم الإعلان
  • +
  • قالب الويب
  • +
  • OEM
  • +
  • تضمين الجهاز
  • +
+ +

من السهل للحصول على هذه الصفحة اقرأ هذه الصفحة للحصول على التفاصي

+ + +

أنماط أخرى

+ +

العديد من الخطوط المجانية في Typodermic لها أنماط أخرى متاحة. يرجى زيارة TTypodermic Fonts والبحث عن اسم هذا الخط في شريط البحث.

+ + +
+ +

谢谢

+ +

感谢您从以下位置下载免费字体Typodermic Fonts Inc.此 ZIP 中包含的这些字体包括允许商业使用的免费桌面许可协议。阅读随附的许可协议了解详细信息。

+ + +

安装

+
  • Windows:从 ZIP 中获取字体。右键单击字体并安装
  • Mac OS X 10.3 或更高版本:双击字体文件并安装字体
+ +

允许

+ + + + + +
    +
  • 艺术
  • +
  • 符号
  • +
  • 海报
  • +
  • 横幅
  • +
  • +
  • 名片
  • +
  • 专辑
  • +
  • 电影
  • +
  • 电视
  • +
  • 视频/流媒体/频道
  • +
  • 商标
  • +
  • 商标标志
  • +
  • 服装
  • +
  • 贴纸
  • +
  • 邮票
  • +
  • 产品标签
  • +
  • 网页(未嵌入)
  • +
  • 应用程序(未嵌入)
  • +
  • PDF
  • +
  • 电子书封面或图像(未嵌入)
  • +
+ +

不允许

+ +
    +
  • 应用程序(嵌入式)
  • +
  • 网页(嵌入式)
  • +
  • 电子书(嵌入式)
  • +
  • 产品创造平台
  • +
  • 字母邮票
  • +
  • 广告服务器
  • +
  • 网页模板
  • +
  • 贴牌生产
  • +
  • 设备嵌入
  • +
+ +

很容易获得不同的许可协议。阅读此页面了解详情。

+ +

其他款式

+ +

Typodermic 的许多免费字体都有其他可用的样式。请访问Typodermic Fonts并在搜索栏中搜索此字体的名称。

+ + +
+ +

謝謝

+ +

感謝您從以下位置下載免費字體Typodermic Fonts Inc。 此 ZIP 中包含的這些字體包括允許商業使用的免費桌面許可協議。閱讀隨附的許可協議了解詳細信息。

+ + +

安裝

+
  • Windows:從 ZIP 中獲取字體。右鍵單擊字體並安裝
  • Mac OS X 10.3 或更高版本:雙擊字體文件並安裝字體
+ +

允許

+ +
    +
  • 藝術
  • +
  • 符號
  • +
  • 海報
  • +
  • 橫幅
  • +
  • +
  • 名片
  • +
  • 專輯
  • +
  • 電影
  • +
  • 電視
  • +
  • 視頻/流媒體/頻道
  • +
  • 商標
  • +
  • 商標標誌
  • +
  • 服裝
  • +
  • 貼紙
  • +
  • 郵票
  • +
  • 產品標籤
  • +
  • 網頁(未嵌入)
  • +
  • 應用程序(未嵌入)
  • +
  • PDF
  • +
  • 電子書封面或圖像(未嵌入)
  • + + +
+ +

不允許

+ +
    +
  • 應用程序(嵌入式)
  • +
  • 網頁(嵌入式)
  • +
  • 電子書(嵌入式)
  • +
  • 產品創造平台
  • +
  • 字母郵票
  • +
  • 廣告服務器
  • +
  • 網頁模板
  • +
  • 貼牌生產
  • +
  • 設備嵌入
  • +
+ +

很容易獲得不同的許可協議。閱讀此頁面了解詳情。

+ +

其他款式

+ +

Typodermic 的許多免費字體都有其他可用的樣式。請訪問Typodermic Fonts並在搜索欄中搜索此字體的名稱。

+ + +
+ +

Děkuju

+ +

Děkujeme, že jste si zdarma stáhli písmo z Typodermic Fonts Inc. Tato písma obsažená v tomto ZIP zahrnují bezplatnou licenční smlouvu pro stolní počítače, která umožňuje komerční použití. Podrobnosti naleznete v přiložené licenční smlouvě.

+ + +

Instalace

+
  • Windows: Získejte písmo ze ZIP. Klepněte pravým tlačítkem myši na písmo a nainstalujte
  • Mac OS X 10.3 nebo vyšší: Poklepejte na soubor s písmem a vyberte Instalovat písmo
+ +

Povoleno

+ +
    +
  • umění
  • +
  • podepsat
  • +
  • plakát
  • +
  • prapor
  • +
  • rezervovat
  • +
  • vizitka
  • +
  • album
  • +
  • film
  • +
  • televize
  • +
  • video/streaming/kanály
  • +
  • logo
  • +
  • logo s ochrannou známkou
  • +
  • oblečení
  • +
  • nálepka
  • +
  • razítko
  • +
  • štítek produktu
  • +
  • webová stránka (není vložená)
  • +
  • aplikace (není vložená)
  • +
  • PDF
  • +
  • Obálka nebo obrázky elektronické knihy (nevložené)
  • +
+ +

Nepovoleno

+ +
    +
  • aplikace (vložená)
  • +
  • webová stránka (vložená)
  • +
  • e-kniha (vložená)
  • +
  • platforma pro tvorbu produktů
  • +
  • abecední razítka
  • +
  • reklamní server
  • +
  • webová šablona
  • +
  • OEM
  • +
  • zabudování zařízení
  • +
+ +

Je snadné získat jinou licenční smlouvu. Podrobnosti si přečtěte na této stránce. + +

Jiné styly

+ +

Mnoho bezplatných písem Typodermic má k dispozici další styly. Navštivte prosím Typodermic Fonts a vyhledejte název tohoto písma ve vyhledávací liště.

+ +
+ +

Σας ευχαριστώ

+ +

Ευχαριστούμε για τη λήψη μιας δωρεάν γραμματοσειράς από Typodermic Fonts Inc. Αυτές οι γραμματοσειρές που περιλαμβάνονται σε αυτό το ZIP περιλαμβάνουν μια δωρεάν άδεια χρήσης επιτραπέζιου υπολογιστή που επιτρέπει την εμπορική χρήση. Διαβάστε τη συμφωνία άδειας χρήσης που περιλαμβάνεται για λεπτομέρειες.

+ + +

Εγκατάσταση

+
  • Windows: Βγάλτε τη γραμματοσειρά από το ZIP. Κάντε δεξί κλικ στη γραμματοσειρά και Εγκαταστήστε
  • Mac OS X 10.3 ή νεότερη έκδοση: Κάντε διπλό κλικ στο αρχείο γραμματοσειράς και Εγκατάσταση γραμματοσειράς
+ +

Επιτρέπεται

+ +
    +
  • τέχνη
  • +
  • σημάδι
  • +
  • αφίσα
  • +
  • πανό
  • +
  • Βιβλίο
  • +
  • επαγγελματική κάρτα
  • +
  • άλμπουμ
  • +
  • ταινία
  • +
  • τηλεόραση
  • +
  • βίντεο/ροή/κανάλια
  • +
  • λογότυπο
  • +
  • λογότυπο με εμπορικό σήμα
  • +
  • είδη ένδυσης
  • +
  • αυτοκόλλητη ετικέτα
  • +
  • σφραγίδα
  • +
  • ετικέτα προϊόντος
  • +
  • ιστοσελίδα (μη ενσωματωμένη)
  • +
  • εφαρμογή (μη ενσωματωμένη)
  • +
  • PDF
  • +
  • Εξώφυλλο ή εικόνες ebook (όχι ενσωματωμένα)
  • +
+ +

Δεν επιτρέπεται

+ +
    +
  • εφαρμογή (ενσωματωμένη)
  • +
  • ιστοσελίδα (ενσωματωμένη)
  • +
  • eBook (ενσωματωμένο)
  • +
  • πλατφόρμα δημιουργίας προϊόντων
  • +
  • γραμματόσημα αλφαβήτου
  • +
  • διακομιστής διαφήμισης
  • +
  • πρότυπο ιστού
  • +
  • OEM
  • +
  • ενσωμάτωση συσκευής
  • +
+ +

Είναι εύκολο να αποκτήσετε μια διαφορετική συμφωνία άδειας χρήσης. Διαβάστε αυτήν τη σελίδα για λεπτομέρειες.

+ +

Άλλα στυλ

+ +

Πολλές από τις δωρεάν γραμματοσειρές του Typodermic έχουν άλλα στυλ διαθέσιμα. Επισκεφτείτε το Typodermic Fonts και αναζητήστε το όνομα αυτής της γραμματοσειράς στη γραμμή αναζήτησης.

+ + +
+ +

תודה

+ +

תודה שהורדת פונט בחינם מTypodermic Fonts Inc.גופנים אלה הכלולים ב-ZIP זה כוללים הסכם רישיון חינם לשולחן העבודה המאפשר שימוש מסחרי. קרא את הסכם הרישיון הכלול לפרטים.

+ + +

הַתקָנָה

+
  • Windows: הוצא את הגופן מה-ZIP. לחץ לחיצה ימנית על הגופן והתקן
  • Mac OS X 10.3 ומעלה: לחץ פעמיים על קובץ הגופן והתקן גופן
+ + +

מוּתָר

+ +
    +
  • אומנות
  • +
  • סִימָן
  • +
  • פּוֹסטֵר
  • +
  • דֶגֶל
  • +
  • סֵפֶר
  • +
  • כרטיס עסקים
  • +
  • אַלבּוֹם
  • +
  • סרט
  • +
  • טֵלֶוִיזִיָה
  • +
  • וידאו/סטרימינג/ערוצים
  • +
  • סֵמֶל
  • +
  • לוגו סימן מסחרי
  • +
  • הַלבָּשָׁה
  • +
  • מַדבֵּקָה
  • +
  • חותמת
  • +
  • תווית המוצר
  • +
  • דף אינטרנט (לא מוטבע)
  • +
  • אפליקציה (לא משובצת)
  • +
  • PDF
  • +
  • כריכה או תמונות של ספר אלקטרוני (לא משובצים)
  • +
+ +

לא מורשה

+ +
    +
  • אפליקציה (מוטבעת)
  • +
  • דף אינטרנט (מוטבע)
  • +
  • ספר אלקטרוני (מוטבע)
  • +
  • פלטפורמת יצירת מוצר
  • +
  • חותמות אלפבית
  • +
  • שרת פרסומות
  • +
  • תבנית אינטרנט
  • +
  • OEM
  • +
  • הטמעת מכשיר
  • +
+ +

קל להשיג הסכם רישיון אחר. קרא את הדף הזה לפרטים.

+ +

סגנונות אחרים

+ +

לרבים מהגופנים החינמיים של Typodermic יש סגנונות אחרים זמינים. אנא בקר בגופנים מסוג Typodermic וחפש את השם של גופן זה בשורת החיפוש.

+ +
+ +

शुक्रिया

+ +

से निःशुल्क फ़ॉन्ट डाउनलोड करने के लिए धन्यवादTypodermic Fonts Inc.इस जिप में शामिल इन फोंट में एक मुफ्त डेस्कटॉप लाइसेंस समझौता शामिल है जो व्यावसायिक उपयोग की अनुमति देता है। विवरण के लिए शामिल लाइसेंस समझौते को पढ़ें।

+ + +

इंस्टालेशन

+
  • Windows: जिप से फॉन्ट निकालें। फ़ॉन्ट पर राइट-क्लिक करें और इंस्टॉल करें
  • Mac OS X 10.3 या इसके बाद के संस्करण: फ़ॉन्ट फ़ाइल पर डबल-क्लिक करें और फ़ॉन्ट इंस्टॉल करें
+ +

अनुमत

+ +
    +
  • कला
  • +
  • संकेत
  • +
  • पोस्टर
  • +
  • बैनर
  • +
  • किताब
  • +
  • बिज़नेस कार्ड
  • +
  • एल्बम
  • +
  • चलचित्र
  • +
  • टेलीविजन
  • +
  • वीडियो/स्ट्रीमिंग/चैनल
  • +
  • प्रतीक चिन्ह
  • +
  • ट्रेडमार्क लोगो
  • +
  • कपड़े
  • +
  • कँटिया
  • +
  • टिकट
  • +
  • उत्पाद लेबल
  • +
  • वेब पेज (एम्बेडेड नहीं)
  • +
  • ऐप (एम्बेडेड नहीं)
  • +
  • पीडीएफ
  • +
  • ईबुक कवर या छवियां (एम्बेडेड नहीं)
  • +
+ +

अनुमति नहीं

+ +
    +
  • ऐप (एम्बेडेड)
  • +
  • वेब पेज (एम्बेडेड)
  • +
  • ईबुक (एम्बेडेड)
  • +
  • उत्पाद निर्माण मंच
  • +
  • वर्णमाला टिकटें
  • +
  • विज्ञापन सर्वर
  • +
  • वेब टेम्पलेट
  • +
  • ओईएम
  • +
  • डिवाइस एम्बेडिंग
  • +
+ +

एक अलग लाइसेंस अनुबंध प्राप्त करना आसान है। विवरण के लिए इस पेज को पढ़ें ।

+ +

अन्य शैलियाँ

+ +

टाइपोडर्मिक के कई मुफ्त फोंट में अन्य शैलियाँ उपलब्ध हैं। कृपया टाइपोडर्मिक फ़ॉन्ट्स पर जाएं और सर्च बार में इस फ़ॉन्ट का नाम खोजें।

+ + +
+ +

Köszönöm

+ +

Köszönjük, hogy letöltött egy ingyenes betűtípust innen Typodermic Fonts Inc. A ZIP-ben található betűtípusok ingyenes asztali licencszerződést tartalmaznak, amely lehetővé teszi a kereskedelmi felhasználást. A részletekért olvassa el a mellékelt licencszerződést.

+ + +

Telepítés

+
  • Windows: Vegye ki a fontot a ZIP-ből. Kattintson a jobb gombbal a betűtípusra, és telepítse
  • Mac OS X 10.3 vagy újabb: Kattintson duplán a betűtípusfájlra, és kattintson a betűtípus telepítésére
+ +

Engedélyezett

+ +
    +
  • Művészet
  • +
  • jel
  • +
  • poszter
  • +
  • transzparens
  • +
  • könyv
  • +
  • névjegykártya
  • +
  • album
  • +
  • film
  • +
  • televízió
  • +
  • videó/streaming/csatornák
  • +
  • logó
  • +
  • védjegyes logó
  • +
  • ruházat
  • +
  • matrica
  • +
  • bélyeg
  • +
  • termékcímkét
  • +
  • weboldal (nem beágyazott)
  • +
  • alkalmazás (nem beágyazott)
  • +
  • PDF
  • +
  • e-könyv borítója vagy képek (nem beágyazva)
  • +
+ +

Nem megengedett

+ +
    +
  • alkalmazás (beágyazott)
  • +
  • weboldal (beágyazott)
  • +
  • e-könyv (beágyazott)
  • +
  • termékkészítő platform
  • +
  • ábécé bélyegek
  • +
  • hirdetési szerver
  • +
  • web sablon
  • +
  • OEM
  • +
  • eszközbeágyazás
  • +
+ +

Könnyű más licencszerződést kötni. Olvassa el ezt az oldalt a részletekért.

+ +

Egyéb stílusok

+ +

A Typodermic ingyenes betűtípusai közül sok más stílus is elérhető. Kérjük, látogasson el a Typodermic Fonts oldalra , és keresse meg ennek a betűtípusnak a nevét a keresősávban.

+ + +
+ +

Þakka þér fyrir

+ +

Takk fyrir að hlaða niður ókeypis leturgerð frá Typodermic Fonts Inc. Þessar leturgerðir sem fylgja með í þessari ZIP innihalda ókeypis leyfissamning fyrir skrifborð sem leyfir notkun í atvinnuskyni. Lestu meðfylgjandi leyfissamning fyrir frekari upplýsingar.

+ +

Uppsetning

+
  • Windows: Fáðu leturgerðina úr ZIP. Hægrismelltu á leturgerðina og Settu upp
  • Mac OS X 10.3 eða nýrri: Tvísmelltu á leturgerðina og Settu upp leturgerð
+ +

Leyfilegt

+ +
    +
  • list
  • +
  • merki
  • +
  • plakat
  • +
  • borði
  • +
  • bók
  • +
  • nafnspjald
  • +
  • albúm
  • +
  • kvikmynd
  • +
  • sjónvarp
  • +
  • myndband/straumspilun/rásir
  • +
  • lógó
  • +
  • vörumerki
  • +
  • fatnað
  • +
  • límmiða
  • +
  • Stimpill
  • +
  • vörumerki
  • +
  • vefsíðu (ekki innbyggð)
  • +
  • app (ekki innbyggt)
  • +
  • PDF
  • +
  • Rafbókarkápa eða myndir (ekki innfelldar)
  • +
+ +

Ekki leyft

+ +
    +
  • app (innfellt)
  • +
  • vefsíða (innfelld)
  • +
  • Rafbók (innfelld)
  • +
  • vettvangur fyrir vörusköpun
  • +
  • stafrófsfrímerki
  • +
  • auglýsingaþjónn
  • +
  • vefsniðmát
  • +
  • OEM
  • +
  • innfelling tækis
  • +
+ +

Það er auðvelt að fá annan leyfissamning. Lestu þessa síðu fyrir nánari upplýsingar.

+ +

Aðrir stílar

+ +

Margar af ókeypis leturgerðum Typodermic eru með aðra stíla í boði. Vinsamlegast farðu á Typodermic Fonts og leitaðu að nafni þessarar leturgerðar í leitarstikunni.

+ + +
+ +

Terima kasih

+ +

Terima kasih telah mengunduh font gratis dari Typodermic Fonts Inc. Font-font yang disertakan dalam ZIP ini menyertakan perjanjian lisensi desktop gratis yang mengizinkan penggunaan komersial. Baca perjanjian lisensi yang disertakan untuk detailnya.

+ + +

Instalasi

+
  • Windows: Keluarkan font dari ZIP. Klik kanan pada font dan Instal
  • Mac OS X 10.3 atau lebih tinggi: Klik dua kali file font dan Instal font
+ +

Diizinkan

+ +
    +
  • seni
  • +
  • tanda
  • +
  • poster
  • +
  • spanduk
  • +
  • buku
  • +
  • kartu bisnis
  • +
  • album
  • +
  • film
  • +
  • televisi
  • +
  • video/streaming/saluran
  • +
  • logo
  • +
  • logo bermerek dagang
  • +
  • pakaian
  • +
  • stiker
  • +
  • stempel
  • +
  • label produk
  • +
  • halaman web (tidak disematkan)
  • +
  • aplikasi (tidak disematkan)
  • +
  • PDF
  • +
  • Sampul eBook atau gambar (tidak disematkan)
  • +
+ +

Tidak diizinkan

+ +
    +
  • aplikasi (tertanam)
  • +
  • halaman web (tertanam)
  • +
  • eBuku (tertanam)
  • +
  • platform pembuatan produk
  • +
  • perangko alfabet
  • +
  • server iklan
  • +
  • templat web
  • +
  • OEM
  • +
  • penyematan perangkat
  • +
+ +

Sangat mudah untuk mendapatkan perjanjian lisensi yang berbeda. Baca halaman ini untuk detailnya.

+ +

Gaya lain

+ +

Banyak font gratis Typodermic memiliki gaya lain yang tersedia. Silakan kunjungi Typodermic Fonts dan cari nama font ini di bilah pencarian.

+ + +
+ +

Grazie

+ +

Grazie per aver scaricato un font gratuito daTypodermic Fonts Inc.Questi font inclusi in questo ZIP includono un accordo di licenza desktop gratuito che ne consente l'uso commerciale. Leggere il contratto di licenza incluso per i dettagli.

+ + +

Installazione

+
  • Windows: estrai il carattere dallo ZIP. Fare clic con il tasto destro sul carattere e Installa
  • Mac OS X 10.3 o superiore: fare doppio clic sul file del font e Installa font
+ +

Permesso

+ +
    +
  • arte
  • +
  • cartello
  • +
  • manifesto
  • +
  • bandiera
  • +
  • prenotare
  • +
  • biglietto da visita
  • +
  • album
  • +
  • film
  • +
  • televisione
  • +
  • video/streaming/canali
  • +
  • logo
  • +
  • marchio registrato
  • +
  • capi di abbigliamento
  • +
  • etichetta
  • +
  • francobollo
  • +
  • etichetta del prodotto
  • +
  • pagina web (non incorporata)
  • +
  • app (non incorporata)
  • +
  • PDF
  • +
  • Copertina o immagini dell'eBook (non incorporate)
  • +
+ +

Non autorizzato

+ +
    +
  • app (incorporata)
  • +
  • pagina web (incorporata)
  • +
  • eBook (incorporato)
  • +
  • piattaforma di creazione del prodotto
  • +
  • francobolli alfabetici
  • +
  • server pubblicitario
  • +
  • modello web
  • +
  • OEM
  • +
  • incorporamento del dispositivo
  • +
+ +

È facile ottenere un contratto di licenza diverso. Leggi questa pagina per i dettagli.

+ +

Altri stili

+ +

Molti dei font gratuiti di Typodermic hanno altri stili disponibili. Si prega di visitare Typodermic Fonts e cercare il nome di questo font nella barra di ricerca.

+ + +
+ +

고맙습니다

+ +

에서 무료 글꼴을 다운로드해 주셔서 감사합니다 Typodermic Fonts Inc. 이 ZIP에 포함된 이러한 글꼴에는 상업적 사용을 허용하는 무료 데스크톱 라이선스 계약이 포함되어 있습니다. 자세한 내용은 포함된 라이센스 계약을 읽으십시오.

+ + +

설치

+
  • Windows: ZIP에서 글꼴을 가져옵니다. 글꼴을 마우스 오른쪽 버튼으로 클릭하고 설치
  • Mac OS X 10.3 이상: 글꼴 파일을 두 번 클릭하고 글꼴 설치
+ +

허용된

+ +
    +
  • 미술
  • +
  • 징후
  • +
  • 포스터
  • +
  • 배너
  • +
  • 도서
  • +
  • 명함
  • +
  • 앨범
  • +
  • 영화
  • +
  • 텔레비전
  • +
  • 비디오/스트리밍/채널
  • +
  • 심벌 마크
  • +
  • 상표 로고
  • +
  • 의류
  • +
  • 상표
  • +
  • 우표
  • +
  • 제품 라벨
  • +
  • 웹페이지(삽입되지 않음)
  • +
  • 앱(삽입되지 않음)
  • +
  • PDF
  • +
  • eBook 표지 또는 이미지(삽입되지 않음)
  • +
+ +

허용되지 않음

+ +
    +
  • 앱(임베디드)
  • +
  • 웹페이지(임베디드)
  • +
  • 전자책(임베디드)
  • +
  • 제품 제작 플랫폼
  • +
  • 알파벳 우표
  • +
  • 광고 서버
  • +
  • 웹 템플릿
  • +
  • OEM
  • +
  • 장치 임베딩
  • +
+ +

+다른 라이센스 계약을 얻는 것은 쉽습니다. 자세한 내용은 이 페이지 를 읽으십시오.

+ +

다른 스타일

+ +

많은 Typodermic의 무료 글꼴에는 다른 스타일을 사용할 수 있습니다. Typodermic Fonts 를 방문 하여 검색창에서 이 글꼴의 이름을 검색하십시오.

+ + +
+ +

ありがとうございます

+ +

から無料フォントをダウンロードしていただきありがとうございますTypodermic Fonts 株式会社。 この ZIP に含まれるこれらのフォントには、商用利用を許可する無料のデスクトップ ライセンス契約が含まれています。詳細については、同梱のライセンス契約をお読みください。

+ + +

インストール

+
  • Windows: ZIP からフォントを取得します。フォントを右クリックしてインストール
  • Mac OS X 10.3 以降: フォント ファイルをダブルクリックし、フォントをインストールします。
+ +

許可

+ +
    +
  • 美術
  • +
  • サイン
  • +
  • ポスター
  • +
  • バナー
  • +
  • +
  • 名刺
  • +
  • アルバム
  • +
  • 映画
  • +
  • テレビ
  • +
  • ビデオ/ストリーミング/チャンネル
  • +
  • ロゴ
  • +
  • 商標登録されたロゴ
  • +
  • 衣類
  • +
  • ステッカー
  • +
  • 切手
  • +
  • 製品ラベル
  • +
  • Web ページ (埋め込まれていません)
  • +
  • アプリ (埋め込まれていません)
  • +
  • PDF
  • +
  • eBook の表紙または画像 (埋め込まれていないもの)
  • +
+ +

禁止

+ +
    +
  • アプリ (組み込み)
  • +
  • Web ページ (埋め込み)
  • +
  • eBook (埋め込み)
  • +
  • プロダクトクリエーションプラットフォーム
  • +
  • アルファベットスタンプ
  • +
  • 広告サーバー
  • +
  • ウェブ テンプレート
  • +
  • OEM
  • +
  • デバイス埋め込み
  • +
+ +

別のライセンス契約を取得するのは簡単です。詳しくはこちらのページをお読みください。

+ +

その他のスタイル

+ +

Typodermic のフリー フォントの多くには、他のスタイルが用意されています。Typodermic Fontsにアクセスし、検索バーでこのフォントの名前を検索してください。 弊社は日本の会社ですので、お問い合わせフォームに日本語で入力してください。

+ + +
+ +

Takk skal du ha

+ +

Takk for at du lastet ned en gratis font fra Typodermic Fonts Inc. Disse skriftene som er inkludert i denne ZIP-filen inkluderer en gratis lisensavtale for skrivebord som tillater kommersiell bruk. Les den medfølgende lisensavtalen for detaljer.

+ + +

Installasjon

+
  • Windows: Få skriften ut av ZIP. Høyreklikk på skriften og installer
  • Mac OS X 10.3 eller nyere: Dobbeltklikk på skriftfilen og Installer skrift
+ +

Tillatt

+ +
    +
  • Kunst
  • +
  • skilt
  • +
  • plakat
  • +
  • banner
  • +
  • bok
  • +
  • visittkort
  • +
  • album
  • +
  • film
  • +
  • fjernsyn
  • +
  • video/streaming/kanaler
  • +
  • logo
  • +
  • varemerkebeskyttet logo
  • +
  • klær
  • +
  • klistremerke
  • +
  • stemple
  • +
  • produktetikett
  • +
  • nettside (ikke innebygd)
  • +
  • app (ikke innebygd)
  • +
  • PDF
  • +
  • e-bokomslag eller bilder (ikke innebygd)
  • +
+ +

Ikke tillatt

+ +
    +
  • app (innebygd)
  • +
  • nettside (innebygd)
  • +
  • e-bok (innebygd)
  • +
  • plattform for produktskaping
  • +
  • alfabetstempler
  • +
  • annonseserver
  • +
  • nettmal
  • +
  • OEM
  • +
  • innbygging av enheten
  • + +
+ +

Det er enkelt å få en annen lisensavtale. Les denne siden for detaljer.

+ +

Andre stiler

+ +

Mange av Typodermics gratis fonter har andre stiler tilgjengelig. Gå til Typodermic Fonts og søk etter navnet på denne fonten i søkefeltet.

+ + +
+ +

Dziękuję Ci

+ +

Dziękujemy za pobranie darmowej czcionki z Typodermic Fonts Inc. Czcionki zawarte w tym pliku ZIP zawierają umowę licencyjną dotyczącą bezpłatnego komputera stacjonarnego, która zezwala na wykorzystanie komercyjne. Przeczytaj dołączoną umowę licencyjną, aby poznać szczegóły.

+ + +

Dozwolony

+
  • Windows: Pobierz czcionkę z ZIP-a. Kliknij czcionkę prawym przyciskiem myszy i zainstaluj
  • Mac OS X 10.3 lub nowszy: Kliknij dwukrotnie plik czcionki i Zainstaluj czcionkę
+ +

Allowed

+ +
    +
  • sztuka
  • +
  • podpisać
  • +
  • plakat
  • +
  • transparent
  • +
  • książka
  • +
  • wizytówka
  • +
  • album
  • +
  • film
  • +
  • telewizja
  • +
  • wideo/transmisja strumieniowa/kanały
  • +
  • logo
  • +
  • znak firmowy
  • +
  • odzież
  • +
  • naklejka
  • +
  • znaczek
  • +
  • Etykieta produktu
  • +
  • strona internetowa (nie osadzona)
  • +
  • aplikacja (nie osadzona)
  • +
  • PDF
  • +
  • Okładka eBooka lub obrazy (nie osadzone)
  • +
+ +

Nie dozwolony

+ +
    +
  • aplikacja (wbudowana)
  • +
  • strona internetowa (wbudowana)
  • +
  • eBook (wbudowany)
  • +
  • platforma do tworzenia produktów
  • +
  • znaczki alfabetu
  • +
  • serwer reklam
  • +
  • szablon sieciowy
  • +
  • OEM
  • +
  • osadzanie urządzenia
  • +
+ +

Uzyskanie innej umowy licencyjnej jest łatwe. Przeczytaj tę stronę, aby uzyskać szczegółowe informacje.

+ +

Inne style

+ +

Wiele darmowych czcionek Typodermic ma dostępne inne style. Odwiedź stronę Typodermic Fonts i wyszukaj nazwę tej czcionki w pasku wyszukiwania.

+ + +
+ +

Obrigada

+ +

Obrigado por baixar uma fonte gratuita de Typodermic Fonts Inc. Essas fontes incluídas neste ZIP incluem um contrato de licença de desktop gratuito que permite o uso comercial. Leia o contrato de licença incluído para obter detalhes.

+ + +

Instalação

+
  • Windows: Obtenha a fonte do ZIP. Clique com o botão direito na fonte e instale
  • Mac OS X 10.3 ou superior: clique duas vezes no arquivo de fonte e instale a fonte
+ +

Permitido

+ +
    +
  • arte
  • +
  • o sinal
  • +
  • poster
  • +
  • bandeira
  • +
  • livro
  • +
  • cartão de visitas
  • +
  • álbum
  • +
  • filme
  • +
  • televisão
  • +
  • vídeo/streaming/canais
  • +
  • logotipo
  • +
  • logotipo de marca registrada
  • +
  • roupas
  • +
  • adesivo
  • +
  • carimbo
  • +
  • Rótulo do produto
  • +
  • página da web (não incorporada)
  • +
  • aplicativo (não incorporado)
  • +
  • PDF
  • +
  • Capa ou imagens do eBook (não incorporadas)
  • +
+ +

Não permitido

+ +
    +
  • aplicativo (incorporado)
  • +
  • página web (incorporada)
  • +
  • e-book (incorporado)
  • +
  • plataforma de criação de produtos
  • +
  • carimbos do alfabeto
  • +
  • servidor de anúncios
  • +
  • modelo da web
  • +
  • OEM
  • +
  • incorporação de dispositivo
  • +
+ +

É fácil obter um contrato de licença diferente. Leia esta página para obter detalhes.

+ +

Outros estilos

+ +

Muitas das fontes gratuitas do Typodermic têm outros estilos disponíveis. Por favor, visite Typodermic Fonts e procure o nome desta fonte na barra de pesquisa.

+ + +
+ +

ਤੁਹਾਡਾ ਧੰਨਵਾਦ

+ +

ਤੋਂ ਇੱਕ ਮੁਫਤ ਫੌਂਟ ਡਾਊਨਲੋਡ ਕਰਨ ਲਈ ਧੰਨਵਾਦ Typodermic Fonts Inc. ਇਸ ਜ਼ਿਪ ਵਿੱਚ ਸ਼ਾਮਲ ਇਹਨਾਂ ਫੌਂਟਾਂ ਵਿੱਚ ਇੱਕ ਮੁਫਤ ਡੈਸਕਟੌਪ ਲਾਇਸੈਂਸ ਸਮਝੌਤਾ ਸ਼ਾਮਲ ਹੈ ਜੋ ਵਪਾਰਕ ਵਰਤੋਂ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਸ਼ਾਮਲ ਲਾਇਸੰਸ ਸਮਝੌਤੇ ਨੂੰ ਪੜ੍ਹੋ।

+ + +

ਇੰਸਟਾਲੇਸ਼ਨ

+
  • Windows ਜ਼ਿਪ ਤੋਂ ਫੌਂਟ ਪ੍ਰਾਪਤ ਕਰੋ। ਫੌਂਟ 'ਤੇ ਸੱਜਾ-ਕਲਿਕ ਕਰੋ ਅਤੇ ਇੰਸਟਾਲ ਕਰੋ
  • Mac OS X 10.3 ਜਾਂ ਇਸ ਤੋਂ ਉੱਪਰ: ਫੌਂਟ ਫਾਈਲ 'ਤੇ ਡਬਲ-ਕਲਿਕ ਕਰੋ ਅਤੇ ਫੌਂਟ ਸਥਾਪਿਤ ਕਰੋ
+ +

ਦੀ ਇਜਾਜ਼ਤ ਹੈ

+ +
    +
  • ਕਲਾ
  • +
  • ਚਿੰਨ੍ਹ
  • +
  • ਪੋਸਟਰ
  • +
  • ਬੈਨਰ
  • +
  • ਕਿਤਾਬ
  • +
  • ਕਾਰੋਬਾਰੀ ਕਾਰਡ
  • +
  • ਐਲਬਮ
  • +
  • ਫਿਲਮ
  • +
  • ਟੈਲੀਵਿਜ਼ਨ
  • +
  • ਵੀਡੀਓ/ਸਟ੍ਰੀਮਿੰਗ/ਚੈਨਲ
  • +
  • ਲੋਗੋ
  • +
  • ਟ੍ਰੇਡਮਾਰਕ ਲੋਗੋ
  • +
  • ਕੱਪੜੇ
  • +
  • ਸਟਿੱਕਰ
  • +
  • ਮੋਹਰ
  • +
  • ਉਤਪਾਦ ਲੇਬਲ
  • +
  • ਵੈਬ ਪੇਜ (ਏਮਬੈਡਡ ਨਹੀਂ)
  • +
  • ਐਪ (ਏਮਬੈਡਡ ਨਹੀਂ)
  • +
  • PDF
  • +
  • ਈਬੁੱਕ ਕਵਰ ਜਾਂ ਚਿੱਤਰ (ਏਮਬੈਡਡ ਨਹੀਂ)
  • +
+ +

ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ

+ +
    +
  • ਐਪ (ਏਮਬੈਡਡ)
  • +
  • ਵੈੱਬ ਪੇਜ (ਏਮਬੈਡਡ)
  • +
  • ਈ-ਕਿਤਾਬ (ਏਮਬੈਡਡ)
  • +
  • ਉਤਪਾਦ ਬਣਾਉਣ ਪਲੇਟਫਾਰਮ
  • +
  • ਵਰਣਮਾਲਾ ਸਟਪਸ
  • +
  • ਵਿਗਿਆਪਨ ਸਰਵਰ
  • +
  • ਵੈੱਬ ਟੈਮਪਲੇਟ
  • +
  • OEM
  • +
  • ਡਿਵਾਈਸ ਏਮਬੈਡਿੰਗ
  • +
+ +

ਇੱਕ ਵੱਖਰਾ ਲਾਇਸੰਸ ਸਮਝੌਤਾ ਪ੍ਰਾਪਤ ਕਰਨਾ ਆਸਾਨ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਇਸ ਪੰਨੇ ਨੂੰ ਪੜ੍ਹੋ ।

+ +

ਹੋਰ ਸਟਾਈਲ

+ +

ਟਾਈਪੋਡਰਮਿਕ ਦੇ ਬਹੁਤ ਸਾਰੇ ਮੁਫਤ ਫੌਂਟਾਂ ਦੀਆਂ ਹੋਰ ਸ਼ੈਲੀਆਂ ਉਪਲਬਧ ਹਨ। ਕਿਰਪਾ ਕਰਕੇ Typodermic Fonts 'ਤੇ ਜਾਓ ਅਤੇ ਖੋਜ ਪੱਟੀ ਵਿੱਚ ਇਸ ਫੌਂਟ ਦੇ ਨਾਮ ਦੀ ਖੋਜ ਕਰੋ।

+ + +
+ +

Mulțumesc

+ +

Vă mulțumim pentru descărcarea unui font gratuit de la Typodermic Fonts Inc. Aceste fonturi incluse în acest ZIP includ un acord de licență gratuit pentru desktop, care permite utilizarea comercială. Citiți acordul de licență inclus pentru detalii.

+ + +

Instalare

+
  • Windows: scoateți fontul din ZIP. Faceți clic dreapta pe font și Instalați
  • Mac OS X 10.3 sau o versiune ulterioară: Faceți dublu clic pe fișierul fontului și Instalați fontul
+ +

Permis

+ +
    +
  • artă
  • +
  • semn
  • +
  • poster
  • +
  • banner
  • +
  • carte
  • +
  • carte de vizită
  • +
  • album
  • +
  • film
  • +
  • televiziune
  • +
  • video/streaming/canale
  • +
  • siglă
  • +
  • logo-ul mărcii comerciale
  • +
  • îmbrăcăminte
  • +
  • autocolant
  • +
  • timbru
  • +
  • eticheta produsului
  • +
  • pagină web (neîncorporată)
  • +
  • aplicație (nu încorporată)
  • +
  • PDF
  • +
  • Copertă sau imagini de cărți electronice (nu încorporate)
  • +
+ +

Nepermis

+ +
    +
  • aplicație (încorporată)
  • +
  • pagină web (încorporată)
  • +
  • carte electronică (încorporată)
  • +
  • platforma de creare a produselor
  • +
  • timbre cu alfabet
  • +
  • server de publicitate
  • +
  • șablon web
  • +
  • OEM
  • +
  • încorporarea dispozitivului
  • +
+ +

Este ușor să obțineți un alt acord de licență. Citiți această pagină pentru detalii.

+ +

Alte stiluri

+ +

Multe dintre fonturile gratuite ale Typodermic au alte stiluri disponibile. Vă rugăm să vizitați Typodermic Fonts și să căutați numele acestui font în bara de căutare.

+ + +
+ +

Спасибо

+ +

Спасибо за загрузку бесплатного шрифта с Typodermic Fonts Inc. Эти шрифты, включенные в этот ZIP-файл, включают бесплатное лицензионное соглашение для настольных компьютеров, которое разрешает коммерческое использование. Подробнее читайте в прилагаемом лицензионном соглашении.

+ + +

Установка

+
  • Windows: достаньте шрифт из ZIP. Щелкните правой кнопкой мыши шрифт и установите
  • Mac OS X 10.3 или более поздней версии: дважды щелкните файл шрифта и выберите « Установить шрифт» .
+ +

Допустимый

+ +
    +
  • Изобразительное искусство
  • +
  • подписать
  • +
  • плакат
  • +
  • баннер
  • +
  • книга
  • +
  • визитная карточка
  • +
  • альбом
  • +
  • кино
  • +
  • телевидение
  • +
  • видео/стриминг/каналы
  • +
  • логотип
  • +
  • логотип торговой марки
  • +
  • одежда
  • +
  • наклейка
  • +
  • печать
  • +
  • этикетка продукта
  • +
  • веб-страница (не встроенная)
  • +
  • приложение (не встроенное)
  • +
  • PDF
  • +
  • Обложка или изображения электронной книги (не встроенные)
  • +
+ +

Не положено

+ +
    +
  • приложение (встроенное)
  • +
  • веб-страница (встроенная)
  • +
  • электронная книга (встроенная)
  • +
  • платформа для создания продукта
  • +
  • алфавит марки
  • +
  • рекламный сервер
  • +
  • веб-шаблон
  • +
  • ОЕМ
  • +
  • встраивание устройства
  • +
+ +

Легко получить другое лицензионное соглашение. Подробности читайте на этой странице .

+ +

Другие стили

+ +

Для многих бесплатных шрифтов Typodermic доступны другие стили. Пожалуйста, посетите Typodermic Fonts и найдите название этого шрифта в строке поиска.

+ + +
+ +

Tack

+ +

Tack för att du laddar ner ett gratis typsnitt från Typodermic Fonts Inc. Dessa typsnitt som ingår i denna ZIP inkluderar ett gratis licensavtal för skrivbordet som tillåter kommersiell användning. Läs det medföljande licensavtalet för detaljer.

+ + +

Installation

+
  • Windows: Ta bort teckensnittet från ZIP. Högerklicka på typsnittet och installera
  • Mac OS X 10.3 eller senare: Dubbelklicka på teckensnittsfilen och Installera teckensnitt
+ +

Tillåten

+ +
    +
  • konst
  • +
  • skylt
  • +
  • affisch
  • +
  • baner
  • +
  • bok
  • +
  • visitkort
  • +
  • album
  • +
  • film
  • +
  • tv
  • +
  • video/streaming/kanaler
  • +
  • logotyp
  • +
  • varumärkesskyddad logotyp
  • +
  • Kläder
  • +
  • klistermärke
  • +
  • stämpel
  • +
  • produktetikett
  • +
  • webbsida (ej inbäddad)
  • +
  • app (ej inbäddad)
  • +
  • PDF
  • +
  • e-bokomslag eller bilder (ej inbäddade)
  • +
+ +

Inte tillåtet

+ +
    +
  • app (inbäddad)
  • +
  • webbsida (inbäddad)
  • +
  • e-bok (inbäddad)
  • +
  • plattform för att skapa produkter
  • +
  • alfabetet stämplar
  • +
  • annonsserver
  • +
  • webbmall
  • +
  • OEM
  • +
  • enhetsinbäddning
  • +
+ +

Det är lätt att få ett annat licensavtal. Läs den här sidan för detaljer.

+ +

Andra stilar

+ +

Många av Typodermics gratis typsnitt har andra stilar tillgängliga. Besök Typodermic Fonts och sök efter namnet på detta teckensnitt i sökfältet.

+ + +
+ +

நன்றி

+ +

இதிலிருந்து இலவச எழுத்துருவைப் பதிவிறக்கியதற்கு நன்றி Typodermic Fonts Inc. இந்த ஜிப்பில் சேர்க்கப்பட்டுள்ள இந்த எழுத்துருக்கள் வணிகரீதியான பயன்பாட்டை அனுமதிக்கும் இலவச டெஸ்க்டாப் உரிம ஒப்பந்தத்தை உள்ளடக்கியது. விவரங்களுக்கு சேர்க்கப்பட்ட உரிம ஒப்பந்தத்தைப் படிக்கவும்.

+ + +

நிறுவல்

+
  • Windows: ZIP இலிருந்து எழுத்துருவைப் பெறவும். எழுத்துரு மீது வலது கிளிக் செய்து நிறுவவும்
  • அல்லது அதற்கு மேல்: எழுத்துருக் கோப்பை இருமுறை கிளிக் செய்து, எழுத்துருவை நிறுவவும்
+ +

அனுமதிக்கப்பட்டது

+ +
    +
  • கலை
  • +
  • அடையாளம்
  • +
  • சுவரொட்டி
  • +
  • பதாகை
  • +
  • நூல்
  • +
  • வணிக அட்டை
  • +
  • ஆல்பம்
  • +
  • திரைப்படம்
  • +
  • தொலைக்காட்சி
  • +
  • வீடியோ/ஸ்ட்ரீமிங்/சேனல்கள்
  • +
  • சின்னம்
  • +
  • வர்த்தக முத்திரை லோகோ
  • +
  • ஆடை
  • +
  • ஓட்டி
  • +
  • முத்திரை
  • +
  • தயாரிப்பு லேபிள்
  • +
  • வலைப்பக்கம் (உட்பொதிக்கப்படவில்லை)
  • +
  • பயன்பாடு (உட்பொதிக்கப்படவில்லை)
  • +
  • PDF
  • +
  • மின்புத்தக அட்டை அல்லது படங்கள் (உட்பொதிக்கப்படவில்லை)
  • +
+ +

அனுமதி இல்லை

+ +
    +
  • பயன்பாடு (உட்பொதிக்கப்பட்டது)
  • +
  • வலைப்பக்கம் (உட்பொதிக்கப்பட்டது)
  • +
  • மின்புத்தகம் (உட்பொதிக்கப்பட்டது)
  • +
  • தயாரிப்பு உருவாக்கும் தளம்
  • +
  • எழுத்துக்கள் முத்திரைகள்
  • +
  • விளம்பர சர்வர்
  • +
  • வலை டெம்ப்ளேட்
  • +
  • OEM
  • +
  • சாதனம் உட்பொதித்தல்
  • +
+ +

வேறுபட்ட உரிம ஒப்பந்தத்தைப் பெறுவது எளிது. விவரங்களுக்கு இந்தப் பக்கத்தைப் படிக்கவும் .

+ +

பிற பாணிகள்

+ +

Typodermic இன் இலவச எழுத்துருக்கள் பல மற்ற பாணிகளைக் கொண்டுள்ளன. தயவு செய்து Typodermic எழுத்துருக்களைப் பார்வையிடவும் மற்றும் தேடல் பட்டியில் இந்த எழுத்துருவின் பெயரைத் தேடவும்.

+ + +
+ +

ขอขอบคุณ

+ +

Tขอขอบคุณที่ดาวน์โหลดฟอนต์ฟรีจากTypodermic Fonts Inc. แบบอักษรเหล่านี้ที่รวมอยู่ใน ZIP นี้รวมถึงข้อตกลงสิทธิ์การใช้งานเดสก์ท็อปฟรีซึ่งอนุญาตให้ใช้ในเชิงพาณิชย์ อ่านข้อตกลงใบอนุญาตรวมสำหรับรายละเอียด

+ + +

การติดตั้ง

+
  • Windows: รับแบบอักษรจาก ZIP คลิกขวาที่ฟอนต์และติดตั้ง
  • Mac OS X 10.3 ขึ้นไป: ดับเบิลคลิกไฟล์ฟอนต์และติดตั้งฟอนต์
+ +

อนุญาต

+ +
    +
  • ศิลปะ
  • +
  • เข้าสู่ระบบ
  • +
  • โปสเตอร์
  • +
  • แบนเนอร์
  • +
  • หนังสือ
  • +
  • นามบัตร
  • +
  • อัลบั้ม
  • +
  • ภาพยนตร์
  • +
  • โทรทัศน์
  • +
  • วิดีโอ/สตรีมมิ่ง/ช่อง
  • +
  • โลโก้
  • +
  • โลโก้เครื่องหมายการค้า
  • +
  • เสื้อผ้า
  • +
  • สติ๊กเกอร์
  • +
  • ประทับ
  • +
  • ฉลากสินค้า
  • +
  • หน้าเว็บ (ไม่ฝังตัว)
  • +
  • แอพ (ไม่ฝังตัว)
  • +
  • ไฟล์ PDF
  • +
  • หน้าปก eBook หรือรูปภาพ (ไม่ฝัง)
  • +
+ +

ไม่ได้รับอนุญาต

+ +
    +
  • แอพ (ฝังตัว)
  • +
  • หน้าเว็บ (แบบฝัง)
  • +
  • eBook (แบบฝัง)
  • +
  • แพลตฟอร์มการสร้างผลิตภัณฑ์
  • +
  • แสตมป์ตัวอักษร
  • +
  • เซิร์ฟเวอร์โฆษณา
  • +
  • แม่แบบเว็บ
  • +
  • OEM
  • +
  • การฝังอุปกรณ์
  • +
+ +

ง่ายที่จะได้รับข้อตกลงสิทธิ์การใช้งานอื่น อ่านหน้านี้เพื่อดูรายละเอียด

+ +

สไตล์อื่นๆ

+ +

ฟอนต์ฟรีมากมายของ Typodermic มีสไตล์อื่นๆ ให้เลือกใช้ โปรดไปที่ Typodermic Fontsและค้นหาชื่อของแบบอักษรนี้ในแถบค้นหา.

+ + +
+ +

Teşekkür ederim

+ +

Typodermic Fonts Inc.'den ücretsiz bir yazı tipi indirdiğiniz için teşekkür ederiz. Bu ZIP'te bulunan bu yazı tipleri, ticari kullanıma izin veren ücretsiz bir masaüstü lisans sözleşmesi içerir. Ayrıntılar için verilen lisans sözleşmesini okuyun.

+ + +

Kurulum

+
  • Windows: Yazı tipini ZIP dosyasından çıkarın. Yazı tipine sağ tıklayın ve Yükleyin
  • Mac OS X 10.3 veya üstü: Yazı tipi dosyasına çift tıklayın ve Yazı tipini yükle
+ +

İzin verilmiş

+ +
    +
  • sanat
  • +
  • imza
  • +
  • afiş
  • +
  • afiş
  • +
  • kitap
  • +
  • kartvizit
  • +
  • albüm
  • +
  • film
  • +
  • televizyon
  • +
  • video/akış/kanallar
  • +
  • logo
  • +
  • ticari marka logosu
  • +
  • Giyim
  • +
  • etiket
  • +
  • pul
  • +
  • ürün etiketi
  • +
  • web sayfası (gömülü değil)
  • +
  • uygulama (gömülü değil)
  • +
  • PDF
  • +
  • eKitap kapağı veya resimleri (gömülü değil)
  • +
+ +

İzin verilmedi

+ +
    +
  • uygulama (gömülü)
  • +
  • web sayfası (gömülü)
  • +
  • eKitap (gömülü)
  • +
  • ürün oluşturma platformu
  • +
  • alfabe pulları
  • +
  • reklam sunucusu
  • +
  • web şablonu
  • +
  • OEM
  • +
  • cihaz gömme
  • +
+ +

Farklı bir lisans sözleşmesi almak kolaydır. Ayrıntılar için bu sayfayı okuyun .

+ +

Diğer stiller

+ +

Typodermic'in ücretsiz yazı tiplerinin birçoğunda başka stiller mevcuttur. Lütfen Typodermic Fonts'u ziyaret edin ve arama çubuğunda bu fontun adını arayın.

+ +
+ +

Дуже дякую

+ +

Дякуємо за завантаження безкоштовного шрифту з Typodermic Fonts Inc. Ці шрифти, включені в цей ZIP, включають безкоштовну ліцензійну угоду для комп’ютера, яка дозволяє комерційне використання. Прочитайте включену ліцензійну угоду, щоб дізнатися більше.

+ + +

монтаж

+
  • Windows: дістаньте шрифт із ZIP. Клацніть правою кнопкою миші на шрифті та встановіть
  • Mac OS X 10.3 або вище: двічі клацніть файл шрифту та виберіть Установити шрифт
+ +

Дозволено

+ +
    +
  • ст
  • +
  • знак
  • +
  • плакат
  • +
  • банер
  • +
  • книга
  • +
  • бізнес картка
  • +
  • альбом
  • +
  • фільм
  • +
  • телебачення
  • +
  • відео/потокове передавання/канали
  • +
  • логотип
  • +
  • логотип торгової марки
  • +
  • одяг
  • +
  • наклейка
  • +
  • штамп
  • +
  • етикетка продукту
  • +
  • веб-сторінка (не вбудована)
  • +
  • додаток (не вбудований)
  • +
  • PDF
  • +
  • Обкладинка електронної книги або зображення (не вбудовані)
  • +
+ +

Не дозволено

+ +
    +
  • додаток (вбудований)
  • +
  • веб-сторінка (вбудована)
  • +
  • електронна книга (вбудована)
  • +
  • платформа створення продукту
  • +
  • алфавітні марки
  • +
  • сервер реклами
  • +
  • веб-шаблон
  • +
  • OEM
  • +
  • вбудовування пристрою
  • +
+ +

Отримати іншу ліцензійну угоду легко. Прочитайте цю сторінку для отримання деталей.

+ +

Інші стилі

+ +

Багато безкоштовних шрифтів Typodermic мають інші доступні стилі. Відвідайте Typodermic Fonts і знайдіть назву цього шрифту в рядку пошуку.

+ + +
+ + +

Cảm ơn bạn

+ +

Cảm ơn bạn đã tải xuống một phông chữ miễn phí từ Typodermic Fonts Inc. Những phông chữ có trong ZIP này bao gồm thỏa thuận cấp phép máy tính để bàn miễn phí cho phép sử dụng thương mại. Đọc thỏa thuận cấp phép đi kèm để biết chi tiết.

+ + +

Cài đặt

+
  • Windows: Lấy phông chữ ra khỏi ZIP. Nhấp chuột phải vào phông chữ và Cài đặt
  • Mac OS X 10.3 trở lên: Nhấp đúp vào tệp phông chữ và Cài đặt phông chữ
+ + + +
    +
  • Mỹ thuật
  • +
  • bảng hiệu
  • +
  • poster
  • +
  • Ảnh bìa
  • +
  • sách
  • +
  • danh thiếp
  • +
  • album
  • +
  • bộ phim
  • +
  • Tivi
  • +
  • video/phát trực tuyến/kênh
  • +
  • Logo
  • +
  • logo đã đăng ký nhãn hiệu
  • +
  • quần áo
  • +
  • nhãn dán
  • +
  • con tem
  • +
  • nhãn sản phẩm
  • +
  • trang web (không được nhúng)
  • +
  • ứng dụng (không được nhúng)
  • +
  • PDF
  • +
  • Bìa sách điện tử hoặc hình ảnh (không được nhúng)
  • +
+ +

Không cho phép

+ +
    +
  • ứng dụng (nhúng)
  • +
  • trang web (được nhúng)
  • +
  • Sách điện tử (nhúng)
  • +
  • nền tảng tạo sản phẩm
  • +
  • tem bảng chữ cái
  • +
  • máy chủ quảng cáo
  • +
  • mẫu web
  • +
  • OEM
  • +
  • nhúng thiết bị
  • +
+ +

Thật dễ dàng để có được một thỏa thuận cấp phép khác. Đọc trang này để biết chi tiết.

+ +

phong cách khác

+ +

Nhiều phông chữ miễn phí của Typodermic có sẵn các kiểu khác. Vui lòng truy cập Typodermic Fonts và tìm kiếm tên của phông chữ này trong thanh tìm kiếm.

+ +
+ + \ No newline at end of file diff --git a/External Assets/Fonts/oxanium/FONTLOG.txt b/External Assets/Fonts/oxanium/FONTLOG.txt new file mode 100644 index 00000000..61767d65 --- /dev/null +++ b/External Assets/Fonts/oxanium/FONTLOG.txt @@ -0,0 +1,53 @@ +Oxanium font family +https://sev.dev/fonts/oxanium + + +Weights +------- + +200 ExtraLight +300 Light +400 Regular +500 Medium +600 SemiBold +700 Bold +800 ExtraBold + + +OpenType features +----------------- + +kern Provides kerning. +mark Positions combining diacritics relative to base characters. +pnum Replaces monospaced digits with proportional versions. +zero Replaces digit zero with a dotted version. + + +Characters +---------- + +Adobe Latin 3 + +U+0300 Combining grave +U+0301 Combining acute +U+0302 Combining circumflex +U+0303 Combining tilde +U+0304 Combining macron +U+0306 Combining breve +U+0307 Combining dot above +U+0308 Combining diaeresis +U+030A Combining ring above +U+030B Combining double acute +U+030C Combining caron +U+0326 Combining comma below +U+0327 Combining cedilla +U+0328 Combining ogonek +U+1E9E Capital Eszett +U+F000 TrueType hinting marker (up=on, down=off) + + +Changelog +--------- + +Oxanium 1.000 2019-03-20 Severin Meyer hello@sev.dev + Initial release diff --git a/External Assets/Fonts/oxanium/LICENSE.txt b/External Assets/Fonts/oxanium/LICENSE.txt new file mode 100644 index 00000000..1bca71a3 --- /dev/null +++ b/External Assets/Fonts/oxanium/LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2019 Severin Meyer, with Reserved Font Name Oxanium + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/External Assets/Fonts/oxanium/Oxanium-Bold.ttf b/External Assets/Fonts/oxanium/Oxanium-Bold.ttf new file mode 100644 index 00000000..65fc5e5a --- /dev/null +++ b/External Assets/Fonts/oxanium/Oxanium-Bold.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6690376ac20ddf9ca4e2f01f0769c1ee2b275c05512c69a5de6f92b95d7be679 +size 55512 diff --git a/External Assets/Fonts/oxanium/Oxanium-ExtraBold.ttf b/External Assets/Fonts/oxanium/Oxanium-ExtraBold.ttf new file mode 100644 index 00000000..42ab9c88 --- /dev/null +++ b/External Assets/Fonts/oxanium/Oxanium-ExtraBold.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41b86751635d6a969641b69e3de3f9a520a4a780d50b787d524ca71da1f46f34 +size 55604 diff --git a/External Assets/Fonts/oxanium/Oxanium-ExtraLight.ttf b/External Assets/Fonts/oxanium/Oxanium-ExtraLight.ttf new file mode 100644 index 00000000..74adbc3c --- /dev/null +++ b/External Assets/Fonts/oxanium/Oxanium-ExtraLight.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43fd82eaaa4b99e4c58683b20e768f3f7ed9c033be8dc3e45af6f5fc77a3ad3e +size 55728 diff --git a/External Assets/Fonts/oxanium/Oxanium-Light.ttf b/External Assets/Fonts/oxanium/Oxanium-Light.ttf new file mode 100644 index 00000000..0d61c9a0 --- /dev/null +++ b/External Assets/Fonts/oxanium/Oxanium-Light.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:435564a4556f789348b4cdcef25ff3c61c59dc1efa300823c3fd3eac6d3808ad +size 55644 diff --git a/External Assets/Fonts/oxanium/Oxanium-Medium.ttf b/External Assets/Fonts/oxanium/Oxanium-Medium.ttf new file mode 100644 index 00000000..9ddaf5bb --- /dev/null +++ b/External Assets/Fonts/oxanium/Oxanium-Medium.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4099edb1e05797c995fff37e0770e23f74c4f8f88b3294842784efcc7bbaac9 +size 55620 diff --git a/External Assets/Fonts/oxanium/Oxanium-Regular.ttf b/External Assets/Fonts/oxanium/Oxanium-Regular.ttf new file mode 100644 index 00000000..5f09dfa4 --- /dev/null +++ b/External Assets/Fonts/oxanium/Oxanium-Regular.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66a9688339f6d3fcde312660fa193659e6ed13a39aa929308dd17c550352e71d +size 55552 diff --git a/External Assets/Fonts/oxanium/Oxanium-SemiBold.ttf b/External Assets/Fonts/oxanium/Oxanium-SemiBold.ttf new file mode 100644 index 00000000..e64d0349 --- /dev/null +++ b/External Assets/Fonts/oxanium/Oxanium-SemiBold.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b11e06346cdba8718fd20ea31f780612c11c2a1a5f31d35713367bd5ff6b2974 +size 55624 diff --git a/External Assets/Fonts/oxanium/Oxanium.png b/External Assets/Fonts/oxanium/Oxanium.png new file mode 100644 index 00000000..2df0ff01 --- /dev/null +++ b/External Assets/Fonts/oxanium/Oxanium.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4426bdcc85524087105e70456de3fc6c2ce5378c5dce92e68d3c3cd0674a5a1f +size 16928 From ef1b12ecede00c524519e325d4e17c56796b5957 Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Thu, 30 Nov 2023 11:10:43 +0000 Subject: [PATCH 05/99] Add Dialogue UI for Dialgoue Enterpretation --- EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset diff --git a/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset b/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset new file mode 100644 index 00000000..e89ee981 --- /dev/null +++ b/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:398c0cb689086999133a4c6df05209145d3b95f37cc1be5a2774f22ac14a7f8f +size 64236 From 7791bce833d50dbad86acf2e0bde9939c6d8b55b Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Thu, 30 Nov 2023 11:17:24 +0000 Subject: [PATCH 06/99] Update Dialogue UI for Name Text to Conthrax Font --- EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset b/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset index e89ee981..7e974392 100644 --- a/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset +++ b/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:398c0cb689086999133a4c6df05209145d3b95f37cc1be5a2774f22ac14a7f8f -size 64236 +oid sha256:29c613509e937218a2a534f000e4cc677b1e4b9600ad42426076af0891913a4f +size 62070 From b53a2af8cea80c95fc66ca273fae84c3b438155c Mon Sep 17 00:00:00 2001 From: MH261677 Date: Tue, 12 Dec 2023 11:39:25 +0000 Subject: [PATCH 07/99] Added Idle, Sprint, Walk, OutOfStam Camera Anims --- .../FirstPerson/Blueprints/BaseWeapons/BP_BaseWeapon.uasset | 4 ++-- .../Blueprints/BaseWeapons/BP_GunCameraShake.uasset | 4 ++-- .../Blueprints/HeadBobbingEffect/CameraShake_Idle.uasset | 3 +++ .../Blueprints/HeadBobbingEffect/CameraShake_OutOfStam.uasset | 3 +++ .../Blueprints/HeadBobbingEffect/CameraShake_Sprint.uasset | 3 +++ .../Blueprints/HeadBobbingEffect/CameraShake_Walk.uasset | 3 +++ 6 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Idle.uasset create mode 100644 EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_OutOfStam.uasset create mode 100644 EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Sprint.uasset create mode 100644 EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Walk.uasset diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_BaseWeapon.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_BaseWeapon.uasset index af5ea1b4..327dae54 100644 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_BaseWeapon.uasset +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_BaseWeapon.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e1e829f4770985384af4baf7f94ed5089f11e12ec69b2ec09fb5f193a1ab960 -size 124465 +oid sha256:1e9217667c6560bc2ec620effa164ebf76834a0551a1036ca9e30305a5bca1f5 +size 124543 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_GunCameraShake.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_GunCameraShake.uasset index cc04228d..f570bf8e 100644 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_GunCameraShake.uasset +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_GunCameraShake.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4358c8520e164b973fae2ae1a18307f0eb691ecfd94b433cbda1052b8b2751fa -size 7209 +oid sha256:c17011787947edd0492999385adc17e76b12aa4fe03ef946ae96b2ad435f4eda +size 9114 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Idle.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Idle.uasset new file mode 100644 index 00000000..451728d5 --- /dev/null +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Idle.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4edc2f6d9b0bde40c02ba5fec57f3f08573add14e1d62bbed4e4cb33a74f73a +size 7217 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_OutOfStam.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_OutOfStam.uasset new file mode 100644 index 00000000..c8468545 --- /dev/null +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_OutOfStam.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e7640dc1229f02365ed721ad413a620bf85e1a1280a08cec8b56e499f7820af +size 6830 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Sprint.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Sprint.uasset new file mode 100644 index 00000000..929d8476 --- /dev/null +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Sprint.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a9231f702f7fffdfe9f4bd9024bcb549a148dd6d9a4410f55475f6445d0a432 +size 6791 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Walk.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Walk.uasset new file mode 100644 index 00000000..7b388294 --- /dev/null +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/HeadBobbingEffect/CameraShake_Walk.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0465ca03bf373461df13d58cf2ad596af380542610db4f3a151a91128482be61 +size 6765 From 3395c2083aca2c3694c6b6c35bd3fd875faeb643 Mon Sep 17 00:00:00 2001 From: MH261677 Date: Tue, 12 Dec 2023 11:39:37 +0000 Subject: [PATCH 08/99] Setup Functionality for use of new Animations --- .../FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset index ea9b685a..da2ebfc0 100644 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58139ccad1a63dd9fa03404f0fb0b7af3f742d844b0ed7da0e081b96319600b9 -size 54773 +oid sha256:ad0ae20e5303a3fe8c408d0c82d6c1c660c27a857c3f466918550a803b21cd6c +size 113048 From cdac36f359f43d81ed017a295bedc963807a55fb Mon Sep 17 00:00:00 2001 From: MH261677 Date: Tue, 12 Dec 2023 11:39:52 +0000 Subject: [PATCH 09/99] Fixed More FOV issues and removed FOV when Sprinting --- EndlessVendetta/Content/Levels/TrainingFacility.umap | 2 +- .../Source/EndlessVendetta/EndlessVendettaCharacter.cpp | 5 ----- .../Source/EndlessVendetta/EndlessVendettaCharacter.h | 3 ++- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/EndlessVendetta/Content/Levels/TrainingFacility.umap b/EndlessVendetta/Content/Levels/TrainingFacility.umap index 174ac378..bc768da8 100644 --- a/EndlessVendetta/Content/Levels/TrainingFacility.umap +++ b/EndlessVendetta/Content/Levels/TrainingFacility.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7711a7f6afcfd75419a73d627b6359ec3fb76c48d9dbb34e50b2a2318ee05b7d +oid sha256:bb646d54518a71e888f0accb0e1de76627bc4352cc2c1b65312eec17fbd42c6f size 679380 diff --git a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp index 438d89e8..66984a2a 100644 --- a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp @@ -86,7 +86,6 @@ void AEndlessVendettaCharacter::Tick(float DeltaTime) } else if (MoveGroundSpeed <= 0) { - this->GetFirstPersonCameraComponent()->SetFieldOfView(90); bIsPlayerMoving = false; } if (bPressedJump) @@ -105,7 +104,6 @@ void AEndlessVendettaCharacter::Tick(float DeltaTime) if (CurrentStamina <= 0.0f) { bIsPlayerSprinting = false; - this->GetFirstPersonCameraComponent()->SetFieldOfView(90); CurrentStamina = 0.0f; CharacterMovement->MaxWalkSpeed = OriginalWalkSpeed; } @@ -554,7 +552,6 @@ void AEndlessVendettaCharacter::Sprint() if (MoveGroundSpeed > 0) { CharacterMovement->MaxWalkSpeed = SprintSpeed; - this->GetFirstPersonCameraComponent()->SetFieldOfView(100); } } } @@ -566,7 +563,6 @@ void AEndlessVendettaCharacter::StopSprint() { UE_LOG(LogTemp, Display, TEXT("Player stopped sprinting")); CharacterMovement->MaxWalkSpeed = OriginalWalkSpeed; - this->GetFirstPersonCameraComponent()->SetFieldOfView(90); } } @@ -590,7 +586,6 @@ void AEndlessVendettaCharacter::Jumping() void AEndlessVendettaCharacter::StopJump() { Super::StopJumping(); - UE_LOG(LogTemp, Display, TEXT("Player has stopped jumping")); bHasPlayerJumped = false; } diff --git a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h index 8bfa7c05..2fa0e06f 100644 --- a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h +++ b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h @@ -127,7 +127,7 @@ public: bool bIsPlayerMoving = false; - UPROPERTY(VisibleAnywhere) + UPROPERTY(VisibleAnywhere, BlueprintReadWrite) bool bIsPlayerSprinting = false; double MoveGroundSpeed; @@ -177,6 +177,7 @@ public: void Jumping(); void StopJump(); + UPROPERTY(BlueprintReadWrite) bool bHasPlayerJumped = false; UArrowComponent* ScopedLocationArrow; From bce12478340736780fb49c27999115d0f8eabe9e Mon Sep 17 00:00:00 2001 From: MH261677 Date: Thu, 14 Dec 2023 10:17:53 +0000 Subject: [PATCH 10/99] Renamed DoorPrompt folder to DoorBP --- .../Content/FirstPerson/Blueprints/DoorBP/BP_Door.uasset | 3 +++ .../FirstPerson/Blueprints/DoorBP/WBP_DoorPrompt.uasset | 3 +++ .../Content/FirstPerson/Blueprints/DoorPrompt/BP_Door.uasset | 3 --- .../FirstPerson/Blueprints/DoorPrompt/WBP_DoorPrompt.uasset | 3 --- .../Levels/DoorTestLevel/D/HT/HCK94DMZ442FV8M21GRO0Q.uasset | 3 +++ 5 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 EndlessVendetta/Content/FirstPerson/Blueprints/DoorBP/BP_Door.uasset create mode 100644 EndlessVendetta/Content/FirstPerson/Blueprints/DoorBP/WBP_DoorPrompt.uasset delete mode 100644 EndlessVendetta/Content/FirstPerson/Blueprints/DoorPrompt/BP_Door.uasset delete mode 100644 EndlessVendetta/Content/FirstPerson/Blueprints/DoorPrompt/WBP_DoorPrompt.uasset create mode 100644 EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/D/HT/HCK94DMZ442FV8M21GRO0Q.uasset diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/DoorBP/BP_Door.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/DoorBP/BP_Door.uasset new file mode 100644 index 00000000..6c55793e --- /dev/null +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/DoorBP/BP_Door.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d577d68165ea935df55d93682617ee4cde6015fd49125424514f6d7f4724246a +size 69897 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/DoorBP/WBP_DoorPrompt.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/DoorBP/WBP_DoorPrompt.uasset new file mode 100644 index 00000000..b55b152d --- /dev/null +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/DoorBP/WBP_DoorPrompt.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7cff7bcd8f753a0c636853df512555687c1450a25dd908391b55b7589c220ec +size 79813 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/DoorPrompt/BP_Door.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/DoorPrompt/BP_Door.uasset deleted file mode 100644 index 2e39669d..00000000 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/DoorPrompt/BP_Door.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:03cc628cc4a9ab85f3fb7754903bb0b4f5cbf3db50b0cb2044f6812aec991c82 -size 71627 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/DoorPrompt/WBP_DoorPrompt.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/DoorPrompt/WBP_DoorPrompt.uasset deleted file mode 100644 index 5608096e..00000000 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/DoorPrompt/WBP_DoorPrompt.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dd2cc6201da826cdd7357a5f683f0c9d0638cd2c44ebaab60b6585f1c2659159 -size 81251 diff --git a/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/D/HT/HCK94DMZ442FV8M21GRO0Q.uasset b/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/D/HT/HCK94DMZ442FV8M21GRO0Q.uasset new file mode 100644 index 00000000..8a863e39 --- /dev/null +++ b/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/D/HT/HCK94DMZ442FV8M21GRO0Q.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5031de0341c64f2e3c51a272d4a848d1b16bcb7605f1b5f41e668e263bf9309c +size 5152 From 9e01262b2b16cb7b6c07586fd1c39b2a6844dc1b Mon Sep 17 00:00:00 2001 From: MH261677 Date: Thu, 14 Dec 2023 10:18:06 +0000 Subject: [PATCH 11/99] Created basic weapon workbench functionality --- .../BP_WeaponWorkbench.uasset | 3 ++ .../WeaponWorkbenchClass.cpp | 36 +++++++++++++++++++ .../WeaponWorkbenchClass.h | 29 +++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset create mode 100644 EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.cpp create mode 100644 EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.h diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset new file mode 100644 index 00000000..adf7c5a3 --- /dev/null +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04cfc7fe61d70436448fef9aab937104318ff0f55b78ff073901898ebba5427b +size 30633 diff --git a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.cpp b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.cpp new file mode 100644 index 00000000..7dda702e --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.cpp @@ -0,0 +1,36 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "WeaponWorkbenchClass.h" + + +// Sets default values +AWeaponWorkbenchClass::AWeaponWorkbenchClass() +{ + // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. + PrimaryActorTick.bCanEverTick = true; +} + +// Called when the game starts or when spawned +void AWeaponWorkbenchClass::BeginPlay() +{ + Super::BeginPlay(); + +} + +// Called every frame +void AWeaponWorkbenchClass::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); +} + +void AWeaponWorkbenchClass::Interact() +{ + UE_LOG(LogTemp, Display, TEXT("Interacted with weapon workbench")); +} + +void AWeaponWorkbenchClass::InteractPrompt() +{ + +} + diff --git a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.h b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.h new file mode 100644 index 00000000..6cf64981 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.h @@ -0,0 +1,29 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "EndlessVendetta/InteractionInterface.h" +#include "GameFramework/Actor.h" +#include "WeaponWorkbenchClass.generated.h" + +UCLASS() +class ENDLESSVENDETTA_API AWeaponWorkbenchClass : public AActor, public IInteractionInterface +{ + GENERATED_BODY() + +public: + // Sets default values for this actor's properties + AWeaponWorkbenchClass(); + +protected: + // Called when the game starts or when spawned + virtual void BeginPlay() override; + +public: + // Called every frame + virtual void Tick(float DeltaTime) override; + + void Interact() override; + void InteractPrompt() override; +}; From 1a2a56229998034247b567fc6f81230b10388978 Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Thu, 11 Jan 2024 21:46:48 +0000 Subject: [PATCH 12/99] Add Dialogue Tree Interpreter Basic for Dialogue --- EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset b/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset index 7e974392..057d634b 100644 --- a/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset +++ b/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29c613509e937218a2a534f000e4cc677b1e4b9600ad42426076af0891913a4f -size 62070 +oid sha256:c9fd68dea1601223395d64bc68c54d2c6881cb90841e1c841f68155573462ae8 +size 143837 From 94d096dc91595174a030ca5ebd792858d145d32b Mon Sep 17 00:00:00 2001 From: KACPER SZELEST Date: Fri, 12 Jan 2024 13:53:40 +0000 Subject: [PATCH 13/99] Added mayor dialogue tree Added a dialogue tree to the mayor that the player can interact with during the tutorial --- .../Content/Dialogue/Mayor_tutorial_dialogue_tree.uasset | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 EndlessVendetta/Content/Dialogue/Mayor_tutorial_dialogue_tree.uasset diff --git a/EndlessVendetta/Content/Dialogue/Mayor_tutorial_dialogue_tree.uasset b/EndlessVendetta/Content/Dialogue/Mayor_tutorial_dialogue_tree.uasset new file mode 100644 index 00000000..94d07770 --- /dev/null +++ b/EndlessVendetta/Content/Dialogue/Mayor_tutorial_dialogue_tree.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ff24a84d1c042c20b8f3ec95ad35354f71120cae523ef67a0e54a129fb4c738 +size 106796 From f0692b04f05c54414eb3bcf94b65950c9a2c26c0 Mon Sep 17 00:00:00 2001 From: MH261677 Date: Fri, 12 Jan 2024 15:37:57 +0000 Subject: [PATCH 14/99] Added Silencer Class for Attachment --- .../9/PG/AISD2CY0WTWKV1BJDYTYJ3.uasset | 3 ++ .../SilencerAttachmentClass.cpp | 35 +++++++++++++++++++ .../SilencerAttachmentClass.h | 26 ++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/9/PG/AISD2CY0WTWKV1BJDYTYJ3.uasset create mode 100644 EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.cpp create mode 100644 EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.h diff --git a/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/9/PG/AISD2CY0WTWKV1BJDYTYJ3.uasset b/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/9/PG/AISD2CY0WTWKV1BJDYTYJ3.uasset new file mode 100644 index 00000000..e1458c06 --- /dev/null +++ b/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/9/PG/AISD2CY0WTWKV1BJDYTYJ3.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77637c287f5c68e2af19622ea2ba3b0d853503b6d73eb3cb143a82c9c10851dc +size 6362 diff --git a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.cpp b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.cpp new file mode 100644 index 00000000..e40f0844 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.cpp @@ -0,0 +1,35 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "SilencerAttachmentClass.h" + + +// Sets default values for this component's properties +USilencerAttachmentClass::USilencerAttachmentClass() +{ + // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features + // off to improve performance if you don't need them. + PrimaryComponentTick.bCanEverTick = true; + + // ... +} + + +// Called when the game starts +void USilencerAttachmentClass::BeginPlay() +{ + Super::BeginPlay(); + + // ... + +} + + +// Called every frame +void USilencerAttachmentClass::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + // ... +} + diff --git a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.h b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.h new file mode 100644 index 00000000..a5053c3c --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.h @@ -0,0 +1,26 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Components/SceneComponent.h" +#include "SilencerAttachmentClass.generated.h" + + +UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) +class ENDLESSVENDETTA_API USilencerAttachmentClass : public USceneComponent +{ + GENERATED_BODY() + +public: + // Sets default values for this component's properties + USilencerAttachmentClass(); + +protected: + // Called when the game starts + virtual void BeginPlay() override; + +public: + // Called every frame + virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; +}; From 247ab29a6101bd2428a1b883adb973c71312a85f Mon Sep 17 00:00:00 2001 From: MH261677 Date: Fri, 12 Jan 2024 15:38:09 +0000 Subject: [PATCH 15/99] Fixed player crashing if no starter weapons --- .../Source/EndlessVendetta/EndlessVendettaCharacter.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp index 438d89e8..1393ee9b 100644 --- a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp @@ -313,6 +313,7 @@ void AEndlessVendettaCharacter::ToggleCombat() //When 1 is pressed it calls EquipPrimary void AEndlessVendettaCharacter::EquipPrimary() { + if (!IsValid(PrimaryWeaponClass)) return; FActorSpawnParameters spawnParams; spawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; FAttachmentTransformRules AttachmentRules(EAttachmentRule::SnapToTarget, true); @@ -364,6 +365,7 @@ void AEndlessVendettaCharacter::EquipPrimary() void AEndlessVendettaCharacter::EquipSecondary() { + if (!IsValid(SecondaryWeaponClass)) return; FActorSpawnParameters spawnParams; spawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; FAttachmentTransformRules AttachmentRules(EAttachmentRule::SnapToTarget, true); From 4743e4e792a91eab856b69eb156334a0e58c944d Mon Sep 17 00:00:00 2001 From: MH261677 Date: Fri, 12 Jan 2024 15:38:25 +0000 Subject: [PATCH 16/99] Added Basic WeaponWorkbench Code --- .../FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset | 4 ++-- .../Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset | 4 ++-- .../Workbench&Attachments/WeaponWorkbenchClass.cpp | 8 +++++--- .../Workbench&Attachments/WeaponWorkbenchClass.h | 6 ++++++ 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset index ea9b685a..39194017 100644 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58139ccad1a63dd9fa03404f0fb0b7af3f742d844b0ed7da0e081b96319600b9 -size 54773 +oid sha256:5eaca2e57e26f94e805c2ac2c43e5f48686cb60e923d4676b8a229ab1206d46f +size 54396 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset index adf7c5a3..b396c563 100644 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:04cfc7fe61d70436448fef9aab937104318ff0f55b78ff073901898ebba5427b -size 30633 +oid sha256:8d5cfa689a3e0540b6d9d02b7c7f52a810fc65740e4831b3fc1e97070cae84ff +size 40168 diff --git a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.cpp b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.cpp index 7dda702e..5fbb7457 100644 --- a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.cpp @@ -15,7 +15,7 @@ AWeaponWorkbenchClass::AWeaponWorkbenchClass() void AWeaponWorkbenchClass::BeginPlay() { Super::BeginPlay(); - + PlayerCharacterRef = Cast(GetWorld()->GetFirstPlayerController()->GetCharacter()); } // Called every frame @@ -26,11 +26,13 @@ void AWeaponWorkbenchClass::Tick(float DeltaTime) void AWeaponWorkbenchClass::Interact() { - UE_LOG(LogTemp, Display, TEXT("Interacted with weapon workbench")); + if (!PlayerCharacterRef->bHasRifle) return; + UE_LOG(LogTemp, Display, TEXT("Opening Workbench")); + WorkbenchUI(); } void AWeaponWorkbenchClass::InteractPrompt() { - + //THIS IS PROMPT WHERE WILL BE PRESS F TO INTERACT OR WHATEVER } diff --git a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.h b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.h index 6cf64981..c1e54793 100644 --- a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.h +++ b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/WeaponWorkbenchClass.h @@ -3,6 +3,7 @@ #pragma once #include "CoreMinimal.h" +#include "EndlessVendetta/EndlessVendettaCharacter.h" #include "EndlessVendetta/InteractionInterface.h" #include "GameFramework/Actor.h" #include "WeaponWorkbenchClass.generated.h" @@ -26,4 +27,9 @@ public: void Interact() override; void InteractPrompt() override; + + UFUNCTION(BlueprintImplementableEvent) + void WorkbenchUI(); + + AEndlessVendettaCharacter* PlayerCharacterRef; }; From 6d7c4d236b1cbc0094ae1a3233a4d3e06d7c8c71 Mon Sep 17 00:00:00 2001 From: MH261677 Date: Fri, 12 Jan 2024 18:50:10 +0000 Subject: [PATCH 17/99] Gave all weapons suppressor slots --- .../FirstPerson/Blueprints/BaseWeapons/BP_BaseWeapon.uasset | 4 ++-- .../Blueprints/BaseWeapons/Pistols/BP_BasePistolWeapon.uasset | 4 ++-- .../Blueprints/BaseWeapons/Shotguns/BP_BaseShotgun.uasset | 4 ++-- .../Blueprints/BaseWeapons/Snipers/BaseSniper.uasset | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_BaseWeapon.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_BaseWeapon.uasset index af5ea1b4..d5d8a380 100644 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_BaseWeapon.uasset +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/BP_BaseWeapon.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e1e829f4770985384af4baf7f94ed5089f11e12ec69b2ec09fb5f193a1ab960 -size 124465 +oid sha256:0e23dc0f3a3090c3b7bcca01e9123e96b564867646215f48b4871eeb8fc157b5 +size 127141 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Pistols/BP_BasePistolWeapon.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Pistols/BP_BasePistolWeapon.uasset index 4b1c45a0..f516b5b6 100644 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Pistols/BP_BasePistolWeapon.uasset +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Pistols/BP_BasePistolWeapon.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6f31b971cc0237138a2bd8e0aa68d0ac68cac907b0a05aa9617c69883a711cd5 -size 125774 +oid sha256:f9b033aff080a0e32f37aed5b6a02c7e31aa216dc029b70518a5754cd12feb70 +size 127890 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Shotguns/BP_BaseShotgun.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Shotguns/BP_BaseShotgun.uasset index 8e445757..bcb197a6 100644 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Shotguns/BP_BaseShotgun.uasset +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Shotguns/BP_BaseShotgun.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d4bcd23aa245c0819235be1d2d992930fed4440aabdafba514d6a1f99a418fcb -size 124531 +oid sha256:678f82f6a80f2cf13d5d74b24d768045b58bb9b030f70510a095a90f40fb0d29 +size 126463 diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Snipers/BaseSniper.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Snipers/BaseSniper.uasset index 881c555d..deebf3b8 100644 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Snipers/BaseSniper.uasset +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/BaseWeapons/Snipers/BaseSniper.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d3335a1091802c5f484bcc99a573e0cbd388e3cbb586147614ede78c274a14fc -size 124510 +oid sha256:02029898c211501ff276d6996d6fddb8fdbb470aebc1f7f4bb26bfcfbd1928a0 +size 126654 From d66bc0330a933bf589d35db0f008bd44c2492706 Mon Sep 17 00:00:00 2001 From: MH261677 Date: Fri, 12 Jan 2024 18:50:26 +0000 Subject: [PATCH 18/99] Added basic silencer code --- .../Workbench&Attachments/SilencerAttachmentClass.cpp | 2 +- .../Workbench&Attachments/SilencerAttachmentClass.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.cpp b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.cpp index e40f0844..7f31f73b 100644 --- a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.cpp @@ -20,7 +20,7 @@ void USilencerAttachmentClass::BeginPlay() { Super::BeginPlay(); - // ... + // ADD THE LOGIC HERE LATER AFTER DEMO TO ACTUALLY MAKE THE GUN "SILENT" EVEN THO WE HAVE NO AUDIO IN THE GAME. } diff --git a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.h b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.h index a5053c3c..c84b624f 100644 --- a/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.h +++ b/EndlessVendetta/Source/EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.h @@ -23,4 +23,7 @@ protected: public: // Called every frame virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + + UPROPERTY(EditAnywhere) + UStaticMeshComponent* SilencerMesh; }; From 1939f521f8503af0c89128c717cd730b2c2e1c12 Mon Sep 17 00:00:00 2001 From: MH261677 Date: Fri, 12 Jan 2024 18:50:37 +0000 Subject: [PATCH 19/99] Fixed workbench not detecting secondary weapon --- .../Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset index b396c563..84b26b2c 100644 --- a/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/BP_WeaponWorkbench.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d5cfa689a3e0540b6d9d02b7c7f52a810fc65740e4831b3fc1e97070cae84ff -size 40168 +oid sha256:3dbeac730ab96ed8a3fdb5ed3842fe792784887ee6c342020f708872851b788e +size 49997 From 21cfa4f2c910f957ca5cf3a836030bfafe10b609 Mon Sep 17 00:00:00 2001 From: MH261677 Date: Fri, 12 Jan 2024 18:50:53 +0000 Subject: [PATCH 20/99] Added Silencer attachment code to all weapons --- .../WeaponSystem/BaseWeaponClass.cpp | 23 ++++++++----------- .../WeaponSystem/BaseWeaponClass.h | 3 +++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/EndlessVendetta/Source/EndlessVendetta/WeaponSystem/BaseWeaponClass.cpp b/EndlessVendetta/Source/EndlessVendetta/WeaponSystem/BaseWeaponClass.cpp index 6ebc5b94..b154ddd5 100644 --- a/EndlessVendetta/Source/EndlessVendetta/WeaponSystem/BaseWeaponClass.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/WeaponSystem/BaseWeaponClass.cpp @@ -12,6 +12,8 @@ #include "EndlessVendetta/AI/EnemyCharacter.h" #include +#include "EndlessVendetta/Workbench&Attachments/SilencerAttachmentClass.h" + // Sets default values ABaseWeaponClass::ABaseWeaponClass() @@ -251,19 +253,14 @@ void ABaseWeaponClass::InteractPrompt() WeaponStatsPopUp(); } -// void ABaseWeaponClass::GetOutHit(FHitResult OutHit) -// { -// if(IsValid(this)) -// { -// endlessVendettaChar->PrimaryWeapon->Destroy(); -// } -// if (OutHit.GetActor()->ActorHasTag(FName("AssaultRifle"))) -// { -// endlessVendettaChar->EquipPrimary(); -// } -// AActor* HitActor = Cast(endlessVendettaChar->PrimaryWeaponClass); -// endlessVendettaChar->PrimaryWeapon = Cast(HitActor); -// } +void ABaseWeaponClass::SetupSilencerAttachment(UStaticMesh* SilencerMesh) +{ + FTransform emptytransform; + UActorComponent* SilencerComponent = AddComponentByClass(USilencerAttachmentClass::StaticClass(), true, emptytransform, false); + Cast(SilencerComponent)->AttachToComponent(RootComponent, FAttachmentTransformRules::SnapToTargetIncludingScale); + TArray SilencerMeshSocketArray (GetComponentsByTag(UStaticMeshComponent::StaticClass(), FName("SilencerMeshSocket"))); + Cast(SilencerMeshSocketArray[0])->SetStaticMesh(SilencerMesh); +} diff --git a/EndlessVendetta/Source/EndlessVendetta/WeaponSystem/BaseWeaponClass.h b/EndlessVendetta/Source/EndlessVendetta/WeaponSystem/BaseWeaponClass.h index 2637e31f..455752b0 100644 --- a/EndlessVendetta/Source/EndlessVendetta/WeaponSystem/BaseWeaponClass.h +++ b/EndlessVendetta/Source/EndlessVendetta/WeaponSystem/BaseWeaponClass.h @@ -176,6 +176,9 @@ public: //void GetOutHit(FHitResult OutHit); + UFUNCTION(BlueprintCallable) + void SetupSilencerAttachment(UStaticMesh* SilencerMesh); + protected: UArrowComponent* GunStartArrow; bool bStopShooting = false; From ab948c5d2f78a745ba7a60e86fab559e09da3254 Mon Sep 17 00:00:00 2001 From: MH261677 Date: Fri, 12 Jan 2024 18:51:05 +0000 Subject: [PATCH 21/99] Made BlueprintReadWrite for weapon actors --- .../Source/EndlessVendetta/EndlessVendettaCharacter.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h index 8bfa7c05..cb06f775 100644 --- a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h +++ b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h @@ -103,7 +103,9 @@ public: float WalkSpeed; float OriginalWalkSpeed; + UPROPERTY(BlueprintReadWrite) AActor* PrimaryWeaponActor; + UPROPERTY(BlueprintReadWrite) AActor* SecondaryWeaponActor; bool bIsPrimaryWeaponCreated = false; bool bIsSecondaryWeaponCreated = false; @@ -148,13 +150,15 @@ public: UFUNCTION(BlueprintCallable, Category = Weapon) bool GetHasRifle(); - UPROPERTY(EditAnywhere, Category = "Weapons") + UPROPERTY(EditAnywhere, Category = "Weapons", BlueprintReadWrite) TSubclassOf PrimaryWeaponClass; - UPROPERTY(EditAnywhere, Category = "Weapons") + UPROPERTY(EditAnywhere, Category = "Weapons", BlueprintReadWrite) TSubclassOf SecondaryWeaponClass; + UPROPERTY(BlueprintReadWrite) ABaseWeaponClass* PrimaryWeapon; + UPROPERTY(BlueprintReadWrite) ABaseWeaponClass* SecondaryWeapon; UFUNCTION(BlueprintCallable, Category = "Weapons") From e0786f911982523f0be78cdfdbf1a11792ae2175 Mon Sep 17 00:00:00 2001 From: MH261677 Date: Fri, 12 Jan 2024 18:51:21 +0000 Subject: [PATCH 22/99] Created UI for workbench and handling weapon checks --- .../Workbench_UI/WBP_Workbench.uasset | 3 +++ .../Levels/DoorTestLevel/0/24/JBARER4CBJ0QZT5CZY8ID6.uasset | 3 +++ .../Levels/DoorTestLevel/9/PG/AISD2CY0WTWKV1BJDYTYJ3.uasset | 4 ++-- .../Levels/DoorTestLevel/D/HT/HCK94DMZ442FV8M21GRO0Q.uasset | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/Workbench_UI/WBP_Workbench.uasset create mode 100644 EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/0/24/JBARER4CBJ0QZT5CZY8ID6.uasset diff --git a/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/Workbench_UI/WBP_Workbench.uasset b/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/Workbench_UI/WBP_Workbench.uasset new file mode 100644 index 00000000..26b8081a --- /dev/null +++ b/EndlessVendetta/Content/FirstPerson/Blueprints/Workbench_WeaponAttachments/Workbench_UI/WBP_Workbench.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b0b18849fe2fb41c53b6835e8c1d882a5ed56dfa96a403797277280ffd3067b +size 136669 diff --git a/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/0/24/JBARER4CBJ0QZT5CZY8ID6.uasset b/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/0/24/JBARER4CBJ0QZT5CZY8ID6.uasset new file mode 100644 index 00000000..60e887d3 --- /dev/null +++ b/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/0/24/JBARER4CBJ0QZT5CZY8ID6.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:461d223dbbabb2824e1ad8bac0d5732bb55d731e0b74285715f207e458b609f4 +size 6878 diff --git a/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/9/PG/AISD2CY0WTWKV1BJDYTYJ3.uasset b/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/9/PG/AISD2CY0WTWKV1BJDYTYJ3.uasset index e1458c06..b2990eba 100644 --- a/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/9/PG/AISD2CY0WTWKV1BJDYTYJ3.uasset +++ b/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/9/PG/AISD2CY0WTWKV1BJDYTYJ3.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77637c287f5c68e2af19622ea2ba3b0d853503b6d73eb3cb143a82c9c10851dc -size 6362 +oid sha256:bb7fd3b17bbcc170b84fda39c7712b526f201a4a45ea48d1ac36415e0ca366ee +size 7007 diff --git a/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/D/HT/HCK94DMZ442FV8M21GRO0Q.uasset b/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/D/HT/HCK94DMZ442FV8M21GRO0Q.uasset index 8a863e39..b8758f85 100644 --- a/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/D/HT/HCK94DMZ442FV8M21GRO0Q.uasset +++ b/EndlessVendetta/Content/__ExternalActors__/Levels/DoorTestLevel/D/HT/HCK94DMZ442FV8M21GRO0Q.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5031de0341c64f2e3c51a272d4a848d1b16bcb7605f1b5f41e668e263bf9309c +oid sha256:4eba44b03ff058bd86a49a05814cbb134bd5c24beb99148a7b8e7c2c7e71eb21 size 5152 From eb8f90016f942c20fa24ffb945b51db14bd3ff73 Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Fri, 12 Jan 2024 21:23:44 +0000 Subject: [PATCH 23/99] Update Dialogue Tree to be Able to have Cyclical Graphs --- .../Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp index 903afba3..92569451 100644 --- a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp @@ -11,6 +11,7 @@ UDialogueTree::UDialogueTree() LeftDialogueBgColor = FLinearColor::Black; RightDialogueBgColor = FLinearColor(0.93f, 0.93f, 0.93f, 1.f); + bCanBeCyclical = true; Name = "Dialogue Tree"; } From adc5787b430ad3898b4b9a329e16e9e545a8fbda Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Fri, 12 Jan 2024 21:31:14 +0000 Subject: [PATCH 24/99] Update Dialogue Tree for Text Wrapping & Multiple Speakers --- .../DialogueSystem/DialogueTextNode.cpp | 40 +++++++++++++++---- .../DialogueSystem/DialogueTextNode.h | 16 +++++--- .../DialogueSystem/DialogueTree.cpp | 14 +++++-- .../DialogueSystem/DialogueTree.h | 26 +++++++++--- 4 files changed, 75 insertions(+), 21 deletions(-) diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp index 8b61bba0..6d3e3c88 100644 --- a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.cpp @@ -16,7 +16,29 @@ UDialogueTextNode::UDialogueTextNode() FText UDialogueTextNode::GetNodeTitle() const { - return Text.IsEmpty() ? LOCTEXT("EmptyParagraph", "(Empty paragraph)") : Text; + if (Text.IsEmpty()) return LOCTEXT("EmptyParagraph", "(Empty paragraph)"); + FString WrappedText = Text.ToString(); + WrappedText = WrappedText.TrimStartAndEnd(); + if (Text.ToString().Len() > 20) + { + WrappedText = ""; + int CharCount = 0; + for (int i = 0; i < Text.ToString().Len(); i++) + { + if (CharCount > 20 && Text.ToString()[i] == ' ') + { + WrappedText += "\n"; + CharCount = 0; + } + else + { + WrappedText += Text.ToString()[i]; + CharCount++; + } + } + } + UE_LOG(LogTemp, Warning, TEXT("Wrapped Text: %s"), *WrappedText); + return FText::FromString(WrappedText); } void UDialogueTextNode::SetNodeTitle(const FText& NewTitle) @@ -31,12 +53,16 @@ FLinearColor UDialogueTextNode::GetBackgroundColor() const if (DialogueTree == nullptr) return Super::GetBackgroundColor(); - switch (DialoguePosition) + switch (DialogueCharacterSpeaking) { - case EDialoguePosition::Left: - return DialogueTree->LeftDialogueBgColor; - case EDialoguePosition::Right: - return DialogueTree->RightDialogueBgColor; + case ECharacterSpeaking::Character1: + return DialogueTree->Character1.DialogueNodeBgColor; + case ECharacterSpeaking::Character2: + return DialogueTree->Character2.DialogueNodeBgColor; + case ECharacterSpeaking::Character3: + return DialogueTree->Character3.DialogueNodeBgColor; + case ECharacterSpeaking::Character4: + return DialogueTree->Character4.DialogueNodeBgColor; default: return FLinearColor::Black; } @@ -44,4 +70,4 @@ FLinearColor UDialogueTextNode::GetBackgroundColor() const #endif -#undef LOCTEXT_NAMESPACE \ No newline at end of file +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.h index 6ff78b28..af556e4b 100644 --- a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.h +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTextNode.h @@ -2,27 +2,31 @@ #include "CoreMinimal.h" #include "GenericGraphNode.h" +#include "DialogueTree.h" #include "DialogueTextNode.generated.h" UENUM(BlueprintType) -enum class EDialoguePosition : uint8 +enum class ECharacterSpeaking : uint8 { - Left, - Right + Character1, + Character2, + Character3, + Character4 }; UCLASS(Blueprintable) class UDialogueTextNode : public UGenericGraphNode { GENERATED_BODY() + public: UDialogueTextNode(); - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue") + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue", meta = (MultiLine = true)) FText Text; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue") - EDialoguePosition DialoguePosition; + ECharacterSpeaking DialogueCharacterSpeaking = ECharacterSpeaking::Character1; #if WITH_EDITOR virtual FText GetNodeTitle() const override; @@ -31,4 +35,4 @@ public: virtual FLinearColor GetBackgroundColor() const override; #endif -}; \ No newline at end of file +}; diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp index 92569451..fc669ebf 100644 --- a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.cpp @@ -9,11 +9,19 @@ UDialogueTree::UDialogueTree() NodeType = UGenericGraphNode::StaticClass(); EdgeType = UDialogueEdge::StaticClass(); - LeftDialogueBgColor = FLinearColor::Black; - RightDialogueBgColor = FLinearColor(0.93f, 0.93f, 0.93f, 1.f); bCanBeCyclical = true; + Character1.CharacterName = "Character 1"; + Character2.CharacterName = "Character 2"; + Character3.CharacterName = "None"; + Character4.CharacterName = "None"; + + Character1.DialogueNodeBgColor = FLinearColor::Black; + Character2.DialogueNodeBgColor = FLinearColor(0.93f, 0.93f, 0.93f, 1.f); + Character3.DialogueNodeBgColor = FLinearColor::Yellow; + Character4.DialogueNodeBgColor = FLinearColor::Blue; + Name = "Dialogue Tree"; } -#undef LOCTEXT_NAMESPACE \ No newline at end of file +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.h index 8150ba61..ed992455 100644 --- a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.h +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueTree.h @@ -4,8 +4,21 @@ #include "GenericGraph.h" #include "DialogueTree.generated.h" +USTRUCT(BlueprintType) +struct FDialogueCharacter +{ + GENERATED_BODY() + + UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = "Dialogue") + FName CharacterName; + UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = "Dialogue") + FLinearColor DialogueNodeBgColor; + UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = "Dialogue") + UTexture2D* DialogueCharacterPortrait; +}; + UCLASS(Blueprintable) -class ENDLESSVENDETTA_API UDialogueTree: public UGenericGraph +class ENDLESSVENDETTA_API UDialogueTree : public UGenericGraph { GENERATED_BODY() @@ -13,8 +26,11 @@ public: UDialogueTree(); UPROPERTY(EditDefaultsOnly, Category = "Dialogue") - FLinearColor LeftDialogueBgColor; - + FDialogueCharacter Character1; UPROPERTY(EditDefaultsOnly, Category = "Dialogue") - FLinearColor RightDialogueBgColor; -}; \ No newline at end of file + FDialogueCharacter Character2; + UPROPERTY(EditDefaultsOnly, Category = "Dialogue") + FDialogueCharacter Character3; + UPROPERTY(EditDefaultsOnly, Category = "Dialogue") + FDialogueCharacter Character4; +}; From 5145b6900903a67766e20e0008f404ba723388aa Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Mon, 15 Jan 2024 03:44:09 +0000 Subject: [PATCH 25/99] Update Dialogue Tree for Proper Choice Interpretation --- .../DialogueSystem/AC_Dialogue.h | 19 +++++ .../AC_PlayerDialogueInterpreter.cpp | 75 +++++++++++++++++++ .../AC_PlayerDialogueInterpreter.h | 57 ++++++++++++++ .../DialogueSystem/DialogueChoiceNode.cpp | 29 +++++++ .../DialogueSystem/DialogueChoiceNode.h | 25 +++++++ .../DialogueSystem/DialogueEdge.h | 6 +- 6 files changed, 208 insertions(+), 3 deletions(-) create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_Dialogue.h create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.cpp create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.h create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueChoiceNode.cpp create mode 100644 EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueChoiceNode.h diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_Dialogue.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_Dialogue.h new file mode 100644 index 00000000..5d8635c0 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_Dialogue.h @@ -0,0 +1,19 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "DialogueTree.h" +#include "Components/ActorComponent.h" +#include "AC_Dialogue.generated.h" + + +UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) +class ENDLESSVENDETTA_API UAC_Dialogue : public UActorComponent +{ + GENERATED_BODY() + +public: + UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = "Dialogue") + UDialogueTree* DialogueTree; +}; diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.cpp b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.cpp new file mode 100644 index 00000000..72be7b3a --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.cpp @@ -0,0 +1,75 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "AC_PlayerDialogueInterpreter.h" + + +// Sets default values for this component's properties +UAC_PlayerDialogueInterpreter::UAC_PlayerDialogueInterpreter() +{ + // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features + // off to improve performance if you don't need them. + PrimaryComponentTick.bCanEverTick = false; + + // ... +} + + +// Called when the game starts +void UAC_PlayerDialogueInterpreter::BeginPlay() +{ + Super::BeginPlay(); + + // ... +} + + +// Called every frame +void UAC_PlayerDialogueInterpreter::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + // ... +} + +void UAC_PlayerDialogueInterpreter::StartDialogue(UDialogueTree* DialogueTree) +{ + CurrentDialogueTree = DialogueTree; + CurrentTextNode = Cast(DialogueTree->RootNodes[0]->ChildrenNodes[0]); + OnStartDialogue.Broadcast(CurrentTextNode); +} + +void UAC_PlayerDialogueInterpreter::NextDialogue() +{ + if (IsValid(CurrentTextNode)) + { + if (Cast(CurrentTextNode->ChildrenNodes[0])) + { + CurrentTextNode = nullptr; + CurrentChoiceNode = Cast(CurrentTextNode->ChildrenNodes[0]); + OnChoiceDialogue.Broadcast(CurrentChoiceNode); + } + else + { + CurrentChoiceNode = nullptr; + CurrentTextNode = Cast(CurrentTextNode->ChildrenNodes[0]); + OnNextDialogue.Broadcast(CurrentTextNode); + } + } +} + +void UAC_PlayerDialogueInterpreter::MakeChoiceDialogue(const int Choice) +{ + if (Cast(CurrentTextNode->ChildrenNodes[Choice])) + { + CurrentTextNode = nullptr; + CurrentChoiceNode = Cast(CurrentTextNode->ChildrenNodes[Choice]); + OnChoiceDialogue.Broadcast(CurrentChoiceNode); + } + else + { + CurrentChoiceNode = nullptr; + CurrentTextNode = Cast(CurrentTextNode->ChildrenNodes[Choice]); + OnNextDialogue.Broadcast(CurrentTextNode); + } +} diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.h new file mode 100644 index 00000000..3f449ced --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/AC_PlayerDialogueInterpreter.h @@ -0,0 +1,57 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "DialogueChoiceNode.h" +#include "DialogueTextNode.h" +#include "Components/ActorComponent.h" +#include "AC_PlayerDialogueInterpreter.generated.h" + + +UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) +class ENDLESSVENDETTA_API UAC_PlayerDialogueInterpreter : public UActorComponent +{ + GENERATED_BODY() + +public: + // Sets default values for this component's properties + UAC_PlayerDialogueInterpreter(); + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnStartDialogue, UDialogueTextNode*, StartingNode); + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnNextDialogue, UDialogueTextNode*, NextNode); + + DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnChoiceDialogue, UDialogueChoiceNode*, ChoiceNode); + + UPROPERTY(BlueprintAssignable, Category = "Dialogue") + FOnStartDialogue OnStartDialogue; + UPROPERTY(BlueprintAssignable, Category = "Dialogue") + FOnNextDialogue OnNextDialogue; + UPROPERTY(BlueprintAssignable, Category = "Dialogue") + FOnChoiceDialogue OnChoiceDialogue; + + UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = "Dialogue") + UDialogueTree* CurrentDialogueTree; + +protected: + // Called when the game starts + virtual void BeginPlay() override; + +private: + UPROPERTY() + UDialogueTextNode* CurrentTextNode; + UPROPERTY() + UDialogueChoiceNode* CurrentChoiceNode; + +public: + // Called every frame + virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + + UFUNCTION(BlueprintCallable, Category = "Dialogue") + void StartDialogue(UDialogueTree* DialogueTree); + UFUNCTION(BlueprintCallable, Category = "Dialogue") + void NextDialogue(); + UFUNCTION(BlueprintCallable, Category = "Dialogue") + void MakeChoiceDialogue(int Choice); +}; diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueChoiceNode.cpp b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueChoiceNode.cpp new file mode 100644 index 00000000..2758d6af --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueChoiceNode.cpp @@ -0,0 +1,29 @@ +#include "DialogueChoiceNode.h" +#include "DialogueTree.h" + +#define LOCTEXT_NAMESPACE "UDialogueChoiceNode" + +UDialogueChoiceNode::UDialogueChoiceNode() +{ +#if WITH_EDITORONLY_DATA + CompatibleGraphType = UDialogueTree::StaticClass(); + + ContextMenuName = LOCTEXT("ConextMenuName", "Choice Node"); +#endif +} + +#if WITH_EDITOR + +FLinearColor UDialogueChoiceNode::GetBackgroundColor() const +{ + const UDialogueTree* DialogueTree = Cast(GetGraph()); + + if (DialogueTree == nullptr) + return Super::GetBackgroundColor(); + + return FLinearColor(1.f, 0.5f, 0.f, 1.f); +} + +#endif + +#undef LOCTEXT_NAMESPACE diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueChoiceNode.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueChoiceNode.h new file mode 100644 index 00000000..0b0550b2 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueChoiceNode.h @@ -0,0 +1,25 @@ +#pragma once + +#include "CoreMinimal.h" +#include "GenericGraphNode.h" +#include "DialogueChoiceNode.generated.h" + +UCLASS(Blueprintable) +class UDialogueChoiceNode : public UGenericGraphNode +{ + GENERATED_BODY() + +public: + UDialogueChoiceNode(); + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue") + FString Choice1Text = "None"; + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue") + FString Choice2Text = "None"; + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue") + FString Choice3Text = "None"; + +#if WITH_EDITOR + virtual FLinearColor GetBackgroundColor() const override; +#endif +}; diff --git a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueEdge.h b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueEdge.h index 72d6491b..ef92beff 100644 --- a/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueEdge.h +++ b/EndlessVendetta/Source/EndlessVendetta/DialogueSystem/DialogueEdge.h @@ -10,7 +10,7 @@ class UDialogueEdge: public UGenericGraphEdge { GENERATED_BODY() -public: - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue") - FText Selection; + // public: + // UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Dialogue") + // FText Selection; }; \ No newline at end of file From 9458d574e3d3d6ef5101343a088af166642ba06f Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Mon, 15 Jan 2024 03:44:31 +0000 Subject: [PATCH 26/99] Update Dialogue for Choices UI & Events --- EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset b/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset index 057d634b..eadef84b 100644 --- a/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset +++ b/EndlessVendetta/Content/Dialogue/BP_DialogueUI.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c9fd68dea1601223395d64bc68c54d2c6881cb90841e1c841f68155573462ae8 -size 143837 +oid sha256:4030e57c1b966dfdb126958edaf4372bb098c41c034292d54fab657ec6c914b0 +size 223792 From 10fc559eb9e1f6e87f35f3c2e01027c364a4da71 Mon Sep 17 00:00:00 2001 From: Rafal Swierczek Date: Fri, 19 Jan 2024 15:05:05 +0000 Subject: [PATCH 27/99] Deleted Corrupted Arrow Icon --- .../.idea.EndlessVendetta/.idea/workspace.xml | 73 +++++++++++++++++++ .../Waypoint/WaypointArrow.uasset | 3 - .../HDRI/HDRI_Epic_Courtyard_Daylight.uasset | 4 +- .../Particles/P_Ambient_Dust.uasset | 4 +- 4 files changed, 77 insertions(+), 7 deletions(-) delete mode 100644 EndlessVendetta/Content/BountySystem/Waypoint/WaypointArrow.uasset diff --git a/EndlessVendetta/.idea/.idea.EndlessVendetta/.idea/workspace.xml b/EndlessVendetta/.idea/.idea.EndlessVendetta/.idea/workspace.xml index 18b2937a..92e001be 100644 --- a/EndlessVendetta/.idea/.idea.EndlessVendetta/.idea/workspace.xml +++ b/EndlessVendetta/.idea/.idea.EndlessVendetta/.idea/workspace.xml @@ -1,5 +1,60 @@ + + Intermediate/ProjectFiles/EndlessVendetta.vcxproj + + + + + + + + + + + + + + + + + + + + @@ -63,4 +118,22 @@ + + + + + 1705270207676 + + + + + + + \ No newline at end of file diff --git a/EndlessVendetta/Content/BountySystem/Waypoint/WaypointArrow.uasset b/EndlessVendetta/Content/BountySystem/Waypoint/WaypointArrow.uasset deleted file mode 100644 index 77db169b..00000000 --- a/EndlessVendetta/Content/BountySystem/Waypoint/WaypointArrow.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:581ee1ef957a3b4e90433ecabc49b6afd731418013eb96e516f54876097f0ca4 -size 255 diff --git a/EndlessVendetta/Content/StarterContent/HDRI/HDRI_Epic_Courtyard_Daylight.uasset b/EndlessVendetta/Content/StarterContent/HDRI/HDRI_Epic_Courtyard_Daylight.uasset index 1c0675e1..0f990580 100644 --- a/EndlessVendetta/Content/StarterContent/HDRI/HDRI_Epic_Courtyard_Daylight.uasset +++ b/EndlessVendetta/Content/StarterContent/HDRI/HDRI_Epic_Courtyard_Daylight.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b1214c2656169689002a1b8976a3ae6c3287520fae9ca08f71889c57690c775 -size 66790690 +oid sha256:bc35eb2d43a47427d30aba0196f9eac90d089dd3abca319528c5d25c83510d0d +size 72364642 diff --git a/EndlessVendetta/Content/StarterContent/Particles/P_Ambient_Dust.uasset b/EndlessVendetta/Content/StarterContent/Particles/P_Ambient_Dust.uasset index bf2e4391..6bf92200 100644 --- a/EndlessVendetta/Content/StarterContent/Particles/P_Ambient_Dust.uasset +++ b/EndlessVendetta/Content/StarterContent/Particles/P_Ambient_Dust.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:01ef616c7a8bd90cd1b7a13efb18a56f33346efbae51efa31f09804478b7621d -size 43456 +oid sha256:50573b1db83529bf6fe3f718bf4fe1e8008ad675a7865d2507d362fc399595f2 +size 53268 From d203b8932007c7523db165b4d84b8608a8ba5885 Mon Sep 17 00:00:00 2001 From: Rafal Swierczek Date: Fri, 19 Jan 2024 18:01:13 +0000 Subject: [PATCH 28/99] Bugfix Head Bobbing Merge Conflicts --- .../.idea.EndlessVendetta/.idea/workspace.xml | 16 +++++++++------- .../Blueprints/BP_FirstPersonCharacter.uasset | 4 ++-- .../Content/Levels/ControlTutorialLevel.umap | 4 ++-- .../HDRI/HDRI_Epic_Courtyard_Daylight.uasset | 4 ++-- .../Particles/P_Ambient_Dust.uasset | 4 ++-- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/EndlessVendetta/.idea/.idea.EndlessVendetta/.idea/workspace.xml b/EndlessVendetta/.idea/.idea.EndlessVendetta/.idea/workspace.xml index 92e001be..85b48aee 100644 --- a/EndlessVendetta/.idea/.idea.EndlessVendetta/.idea/workspace.xml +++ b/EndlessVendetta/.idea/.idea.EndlessVendetta/.idea/workspace.xml @@ -7,9 +7,11 @@