DialogueComponent doodles

This commit is contained in:
2025-09-26 15:47:26 +02:00
committed by Michal Pikulski
parent c8cbc45f04
commit b07eea6aae
35 changed files with 1025 additions and 373 deletions

View File

@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Dialogue;
using PuzzleS;
namespace Editor.Dialogue
{
@@ -17,12 +18,13 @@ namespace Editor.Dialogue
RuntimeDialogueGraph runtimeGraph = ScriptableObject.CreateInstance<RuntimeDialogueGraph>();
var nodeIDMap = new Dictionary<INode, string>();
// Generate stable GUIDs for each node
foreach (var node in editorGraph.GetNodes())
{
nodeIDMap[node] = Guid.NewGuid().ToString();
}
// TODO: This could be done in the above loop, but for clarity, I'm keeping it separate for now.
// Process start node to get entry point and speaker name
var startNode = editorGraph.GetNodes().OfType<StartNode>().FirstOrDefault();
if (startNode != null)
{
@@ -35,33 +37,193 @@ namespace Editor.Dialogue
runtimeGraph.speakerName = GetPortValue<string>(startNode.GetInputPortByName("SpeakerName"));
}
// Process each node in the graph
foreach (var iNode in editorGraph.GetNodes())
{
if (iNode is StartNode || iNode is EndNode)
if (iNode is StartNode || iNode is IVariableNode)
continue;
var runtimeNode = new RuntimeDialogueNode{ nodeID = nodeIDMap[iNode]};
var runtimeNode = new RuntimeDialogueNode{ nodeID = nodeIDMap[iNode] };
// Process node based on its type
if (iNode is DialogueNode dialogueNode)
{
ProcessDialogueNode(dialogueNode, runtimeNode, nodeIDMap);
if (iNode is WaitOnPuzzleStep puzzleNode)
{
ProcessPuzzleNode(puzzleNode, runtimeNode);
}
else if (iNode is WaitOnPickup pickupNode)
{
ProcessPickupNode(pickupNode, runtimeNode);
}
else if (iNode is WaitOnSlot slotNode)
{
ProcessSlotNode(slotNode, runtimeNode);
}
// Process base dialogue node properties (for all node types)
ProcessDialogueNodeBase(dialogueNode, runtimeNode);
}
else if (iNode is EndNode)
{
runtimeNode.nodeType = RuntimeDialogueNodeType.End;
// End nodes don't have next nodes, so we don't need to look for "out" ports
}
// Get next node connection (skip for EndNodes as they don't have out ports)
if (!(iNode is EndNode))
{
// Check if the node has output ports before trying to get one by name
var outputPorts = iNode.GetOutputPorts();
if (outputPorts != null && outputPorts.Any())
{
var outPort = outputPorts.FirstOrDefault(p => p.name == "out");
if (outPort != null && outPort.firstConnectedPort != null)
{
runtimeNode.nextNodeID = nodeIDMap[outPort.firstConnectedPort.GetNode()];
}
}
}
// Add node to runtime graph
runtimeGraph.allNodes.Add(runtimeNode);
}
ctx.AddObjectToAsset("RuntimeData", runtimeGraph);
ctx.SetMainObject(runtimeGraph);
Debug.Log($"Imported DialogueGraph with {runtimeGraph.allNodes.Count} nodes.");
}
private void ProcessDialogueNode(DialogueNode node, RuntimeDialogueNode runtimeNode, Dictionary<INode, string> nodeIDMap)
private void ProcessDialogueNodeBase(DialogueNode node, RuntimeDialogueNode runtimeNode)
{
runtimeNode.dialogueLine = GetPortValue<string>(node.GetInputPortByName("DialogueLine"));
// Set default node type
runtimeNode.nodeType = RuntimeDialogueNodeType.Dialogue;
var nextNodePort = node.GetOutputPortByName("out")?.firstConnectedPort;
if (nextNodePort != null)
// Get line type and count options
var lineTypeOption = node.GetNodeOptionByName("DialogueLineType");
lineTypeOption.TryGetValue<DialogueType>(out var lineType);
var lineCountOption = node.GetNodeOptionByName("NoLines");
lineCountOption.TryGetValue<int>(out var lineCount);
// Process dialogue lines based on line type
if (lineType == DialogueType.SayMultipleLines)
{
runtimeNode.nextNodeID = nodeIDMap[nextNodePort.GetNode()];
for (var i = 0; i < lineCount; i++)
{
var lineValue = GetPortValue<string>(node.GetInputPortByName($"DefaultDialogueLine{i + 1}"));
if (!string.IsNullOrEmpty(lineValue))
{
runtimeNode.dialogueLines.Add(lineValue);
}
}
}
else
{
var lineValue = GetPortValue<string>(node.GetInputPortByName("DefaultDialogueLine"));
if (!string.IsNullOrEmpty(lineValue))
{
runtimeNode.dialogueLines.Add(lineValue);
}
}
// Get loop through lines option
var loopThroughLines = GetPortValue<bool>(node.GetInputPortByName("LoopThroughDefaultLines"));
runtimeNode.loopThroughLines = loopThroughLines;
}
private void ProcessPuzzleNode(WaitOnPuzzleStep node, RuntimeDialogueNode runtimeNode)
{
runtimeNode.nodeType = RuntimeDialogueNodeType.WaitOnPuzzleStep;
var puzzleStep = GetPortValue<PuzzleStepSO>(node.GetInputPortByName("RequiredPuzzleStep"));
if (puzzleStep != null)
{
runtimeNode.puzzleStepID = puzzleStep.stepId;
}
}
private void ProcessPickupNode(WaitOnPickup node, RuntimeDialogueNode runtimeNode)
{
runtimeNode.nodeType = RuntimeDialogueNodeType.WaitOnPickup;
var pickup = GetPortValue<PickupItemData>(node.GetInputPortByName("RequiredPickup"));
if (pickup != null)
{
runtimeNode.pickupItemID = pickup.itemId;
}
}
private void ProcessSlotNode(WaitOnSlot node, RuntimeDialogueNode runtimeNode)
{
runtimeNode.nodeType = RuntimeDialogueNodeType.WaitOnSlot;
var slot = GetPortValue<PickupItemData>(node.GetInputPortByName("RequiredSlot"));
if (slot != null)
{
runtimeNode.slotItemID = slot.itemId;
}
// Process incorrect item lines
var incorrectItemLineTypeOption = node.GetNodeOptionByName("IncorrectItemDialogueLineType");
incorrectItemLineTypeOption.TryGetValue<DialogueType>(out var incorrectItemLineType);
var incorrectItemLineCountOption = node.GetNodeOptionByName("IncorrectItemNoLines");
incorrectItemLineCountOption.TryGetValue<int>(out var incorrectItemLineCount);
if (incorrectItemLineType == DialogueType.SayMultipleLines)
{
for (var i = 0; i < incorrectItemLineCount; i++)
{
var lineValue = GetPortValue<string>(node.GetInputPortByName($"IncorrectItemDialogueLine{i + 1}"));
if (!string.IsNullOrEmpty(lineValue))
{
runtimeNode.incorrectItemLines.Add(lineValue);
}
}
}
else
{
var lineValue = GetPortValue<string>(node.GetInputPortByName("IncorrectItemDialogueLine"));
if (!string.IsNullOrEmpty(lineValue))
{
runtimeNode.incorrectItemLines.Add(lineValue);
}
}
runtimeNode.loopThroughIncorrectLines =
GetPortValue<bool>(node.GetInputPortByName("LoopThroughIncorrectItemLines"));
// Process forbidden item lines
var forbiddenItemLineTypeOption = node.GetNodeOptionByName("ForbiddenItemDialogueLineType");
forbiddenItemLineTypeOption.TryGetValue<DialogueType>(out var forbiddenItemLineType);
var forbiddenItemLineCountOption = node.GetNodeOptionByName("ForbiddenItemNoLines");
forbiddenItemLineCountOption.TryGetValue<int>(out var forbiddenItemLineCount);
if (forbiddenItemLineType == DialogueType.SayMultipleLines)
{
for (var i = 0; i < forbiddenItemLineCount; i++)
{
var lineValue = GetPortValue<string>(node.GetInputPortByName($"ForbiddenItemDialogueLine{i + 1}"));
if (!string.IsNullOrEmpty(lineValue))
{
runtimeNode.forbiddenItemLines.Add(lineValue);
}
}
}
else
{
var lineValue = GetPortValue<string>(node.GetInputPortByName("ForbiddenItemDialogueLine"));
if (!string.IsNullOrEmpty(lineValue))
{
runtimeNode.forbiddenItemLines.Add(lineValue);
}
}
runtimeNode.loopThroughForbiddenLines =
GetPortValue<bool>(node.GetInputPortByName("LoopThroughForbiddenItemLines"));
}
private T GetPortValue<T>(IPort port)