Add new plugins, refactor exp, introduce stat forge to replace GAS
This commit is contained in:
520
Plugins/SUDS/Source/SUDSEditor/Public/SUDSScriptImporter.h
Normal file
520
Plugins/SUDS/Source/SUDSEditor/Public/SUDSScriptImporter.h
Normal file
@@ -0,0 +1,520 @@
|
||||
// Copyright Steve Streeting 2022
|
||||
// Released under the MIT license https://opensource.org/license/MIT/
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "SUDSExpression.h"
|
||||
|
||||
struct FSUDSMessageLogger;
|
||||
class USUDSScript;
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogSUDSImporter, Verbose, All);
|
||||
|
||||
struct SUDSEDITOR_API FSUDSParsedEdge
|
||||
{
|
||||
public:
|
||||
/// Text associated with this edge (if a player choice option)
|
||||
FString Text;
|
||||
/// Identifier of the text, for the string table
|
||||
FString TextID;
|
||||
/// Metadata associated with text, for translator comments
|
||||
TMap<FName, FString> TextMetadata;
|
||||
/// The line this edge was created on
|
||||
int SourceLineNo;
|
||||
/// Condition expression that applies to this edge (for select nodes)
|
||||
FSUDSExpression ConditionExpression;
|
||||
/// Custom metadata for a node which the user can set. Can be used to annotate choice lines
|
||||
/// Could be used to disable a choice if you don't have the stats to take it, or anything else
|
||||
/// where you need a bit of extra information about a line that doesn't suit setting a dialogue variable for.
|
||||
TMap<FName, FSUDSExpression> UserMetadata;
|
||||
|
||||
int SourceNodeIdx = -1;
|
||||
int TargetNodeIdx = -1;
|
||||
|
||||
FSUDSParsedEdge(int LineNo) : SourceLineNo(LineNo){}
|
||||
|
||||
FSUDSParsedEdge(int FromNodeIdx, int ToNodeIdx, int LineNo, const FString& InText, const FString& InTextID, const TMap<FName, FString>& Metadata, const TMap<FName, FSUDSExpression>& UserMeta)
|
||||
: Text(InText),
|
||||
TextID(InTextID),
|
||||
TextMetadata(Metadata),
|
||||
SourceLineNo(LineNo),
|
||||
UserMetadata(UserMeta),
|
||||
SourceNodeIdx(FromNodeIdx),
|
||||
TargetNodeIdx(ToNodeIdx)
|
||||
{
|
||||
}
|
||||
|
||||
FSUDSParsedEdge(int FromNodeIdx, int ToNodeIdx, int LineNo)
|
||||
: SourceLineNo(LineNo),
|
||||
SourceNodeIdx(FromNodeIdx),
|
||||
TargetNodeIdx(ToNodeIdx)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
*this = FSUDSParsedEdge(-1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
enum class ESUDSParsedNodeType : uint8
|
||||
{
|
||||
/// Text node, displaying a line of dialogue
|
||||
Text,
|
||||
/// Choice node, displaying a series of user choices which navigate to other nodes
|
||||
Choice,
|
||||
/// Select node, automatically selecting one which navigates to another node based on state (also Random)
|
||||
Select,
|
||||
/// Goto node, redirects execution somewhere else
|
||||
/// Gotos are only nodes in the parsing structure, because they need to be discoverable as a fallthrough destination
|
||||
/// When converting to runtime use they just become edges
|
||||
Goto,
|
||||
/// Gosub node, acts like goto except stores return location
|
||||
Gosub,
|
||||
/// Return node, returns from a gosub
|
||||
Return,
|
||||
/// Set variable node
|
||||
SetVariable,
|
||||
/// Event node
|
||||
Event
|
||||
};
|
||||
|
||||
/// Intermediate parsed node from script text
|
||||
/// This will be converted into a final asset later
|
||||
struct SUDSEDITOR_API FSUDSParsedNode
|
||||
{
|
||||
public:
|
||||
ESUDSParsedNodeType NodeType;
|
||||
int OriginalIndent;
|
||||
/// Identifier is speaker ID, goto label, variable name etc
|
||||
FString Identifier;
|
||||
/// Text in native language
|
||||
FString Text;
|
||||
/// Identifier of the text, for the string table
|
||||
FString TextID;
|
||||
/// Metadata associated with text, for translator comments
|
||||
TMap<FName, FString> TextMetadata;
|
||||
/// Expression, for nodes that use it (e.g. set)
|
||||
FSUDSExpression Expression;
|
||||
/// Event arguments, for event nodes
|
||||
TArray<FSUDSExpression> EventArgs;
|
||||
/// Labels which lead to this node
|
||||
TArray<FString> Labels;
|
||||
/// Edges leading to other nodes
|
||||
TArray<FSUDSParsedEdge> Edges;
|
||||
/// The line this node was created on
|
||||
int SourceLineNo;
|
||||
/// Whether this is a valid fall-through target
|
||||
bool AllowFallthrough = true;
|
||||
|
||||
/// Custom metadata for a node which the user can set. Can be used to annotate speaker lines
|
||||
TMap<FName, FSUDSExpression> UserMetadata;
|
||||
|
||||
// Path hierarchy of choice nodes leading to this node, of the form "/C002/C006" etc, not including this node index
|
||||
// This helps us identify valid fallthroughs
|
||||
FString ChoicePath;
|
||||
// Path hierarchy of select nodes leading to this node, of the form "/S002/S006" etc, not including this node index
|
||||
// This helps us identify valid fallthroughs
|
||||
FString ConditionalPath;
|
||||
|
||||
/// Although multiple edges can lead here, this index is for the auto-connected parent (may be nothing)
|
||||
int ParentNodeIdx = -1;
|
||||
|
||||
FSUDSParsedNode(ESUDSParsedNodeType InNodeType, int Indent, int LineNo) : NodeType(InNodeType),
|
||||
OriginalIndent(Indent),
|
||||
SourceLineNo(LineNo)
|
||||
{
|
||||
}
|
||||
|
||||
FSUDSParsedNode(const FString& Label,
|
||||
const FString& GosubID,
|
||||
int Indent,
|
||||
int LineNo) : NodeType(ESUDSParsedNodeType::Gosub),
|
||||
OriginalIndent(Indent),
|
||||
Identifier(Label),
|
||||
TextID(GosubID),
|
||||
SourceLineNo(LineNo)
|
||||
{
|
||||
}
|
||||
|
||||
FSUDSParsedNode(const FString& InSpeaker, const FString& InText, const FString& InTextID, const TMap<FName, FString>& Metadata, const TMap<FName, FSUDSExpression>& UserMeta, int Indent, int LineNo)
|
||||
: NodeType(ESUDSParsedNodeType::Text),
|
||||
OriginalIndent(Indent),
|
||||
Identifier(InSpeaker),
|
||||
Text(InText),
|
||||
TextID(InTextID),
|
||||
TextMetadata(Metadata),
|
||||
SourceLineNo(LineNo),
|
||||
UserMetadata(UserMeta)
|
||||
{
|
||||
}
|
||||
|
||||
FSUDSParsedNode(const FString& GotoLabel, int Indent, int LineNo)
|
||||
: NodeType(ESUDSParsedNodeType::Goto), OriginalIndent(Indent), Identifier(GotoLabel), SourceLineNo(LineNo)
|
||||
{
|
||||
}
|
||||
|
||||
FSUDSParsedNode(const FString& VariableName, const FSUDSExpression& InExpr, int Indent, int LineNo)
|
||||
: NodeType(ESUDSParsedNodeType::SetVariable),
|
||||
OriginalIndent(Indent),
|
||||
Identifier(VariableName),
|
||||
Expression(InExpr),
|
||||
SourceLineNo(LineNo)
|
||||
{
|
||||
}
|
||||
|
||||
FSUDSParsedNode(const FString& VariableName,
|
||||
const FSUDSExpression& InExpr,
|
||||
const FString& InTextID,
|
||||
int Indent,
|
||||
int LineNo)
|
||||
: NodeType(ESUDSParsedNodeType::SetVariable),
|
||||
OriginalIndent(Indent),
|
||||
Identifier(VariableName),
|
||||
TextID(InTextID),
|
||||
Expression(InExpr),
|
||||
SourceLineNo(LineNo)
|
||||
{
|
||||
}
|
||||
};
|
||||
class SUDSEDITOR_API FSUDSScriptImporter
|
||||
{
|
||||
public:
|
||||
bool ImportFromBuffer(const TCHAR* Buffer, int32 Len, const FString& NameForErrors, FSUDSMessageLogger* Logger, bool bSilent);
|
||||
void PopulateAsset(USUDSScript* Asset, UStringTable* StringTable);
|
||||
static FMD5Hash CalculateHash(const TCHAR* Buffer, int32 Len);
|
||||
static const FString EndGotoLabel;
|
||||
protected:
|
||||
static const FString TreePathSeparator;
|
||||
|
||||
enum class EConditionalStage : uint8
|
||||
{
|
||||
IfStage,
|
||||
ElseIfStage,
|
||||
ElseStage,
|
||||
RandomStage,
|
||||
RandomOptionStage
|
||||
};
|
||||
enum class EConditionalParent : uint8
|
||||
{
|
||||
Select,
|
||||
ElseIfStage,
|
||||
ElseStage
|
||||
};
|
||||
|
||||
// Struct for tracking if/elseif blocks
|
||||
struct ConditionalContext
|
||||
{
|
||||
/// Index of parent select node where else will be added
|
||||
int SelectNodeIdx = -1;
|
||||
/// Previous block index (parent for nesting)
|
||||
int PreviousBlockIdx = -1;
|
||||
/// Track whether we're in if/elseif/else
|
||||
EConditionalStage Stage;
|
||||
/// String identifying the current condition; for elseif or else contains original "if" context
|
||||
FString ConditionPathElement;
|
||||
|
||||
ConditionalContext(int InSelectNodeIdx, int InPrevBlockIdx, EConditionalStage InStage, const FString& InCondStr) :
|
||||
SelectNodeIdx(InSelectNodeIdx),
|
||||
PreviousBlockIdx(InPrevBlockIdx),
|
||||
Stage(InStage),
|
||||
ConditionPathElement(InCondStr)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// Struct for tracking indents
|
||||
struct IndentContext
|
||||
{
|
||||
public:
|
||||
// The index of the Node which is the parent of this context
|
||||
// This potentially changes every time a sequential text node is encountered in the same context, so it's
|
||||
// always pointing to the last node encountered at this level, for connection
|
||||
int LastNodeIdx = -1;
|
||||
|
||||
/// The outermost indent level where this context lives
|
||||
/// You can indent things that don't create a new context, e.g.
|
||||
/// 1. Indent a text line under another text line: this is the same as no indent, just a continuation
|
||||
/// 2. Indent choices or conditions under a text line
|
||||
/// This is just good for readability, but does not create a new context, it's just a linear sequence
|
||||
/// Therefore the ThresholdIndent tracks the outermost indent relating to the current linear sequence, to know
|
||||
/// when you do in fact need to pop the current context off the stack.
|
||||
int ThresholdIndent = 0;
|
||||
|
||||
int LastTextNodeIdx = -1;
|
||||
|
||||
/// The path entry for this indent, to be combined with all previous levels to provide full path context
|
||||
FString PathEntry;
|
||||
|
||||
IndentContext(int NodeIdx, int Indent, const FString& Path) : LastNodeIdx(NodeIdx), ThresholdIndent(Indent), LastTextNodeIdx(-1), PathEntry(Path) {}
|
||||
|
||||
};
|
||||
|
||||
/// A tree of nodes. Contained to separate header nodes from body nodes
|
||||
struct ParsedTree
|
||||
{
|
||||
public:
|
||||
/// The indent context stack representing where we are in the indentation tree while parsing
|
||||
/// There must always be 1 level (root)
|
||||
TArray<IndentContext> IndentLevelStack;
|
||||
/// When encountering conditions and choice lines, we are building up details for an edge to another node, but
|
||||
/// we currently don't know the target node. We keep these pending details here
|
||||
int EdgeInProgressNodeIdx = -1;
|
||||
int EdgeInProgressEdgeIdx = -1;
|
||||
/// List of all nodes, appended to as parsing progresses
|
||||
/// Ordering is important, these nodes must be in the order encountered in the file
|
||||
TArray<FSUDSParsedNode> Nodes;
|
||||
/// Record of goto labels to node index, built up during parsing (forward refs are OK so not complete until end of parsing)
|
||||
TMap<FString, int> GotoLabelList;
|
||||
/// Goto labels which have been encountered but we haven't found a destination yet
|
||||
TArray<FString> PendingGotoLabels;
|
||||
/// Goto labels that lead directly to another goto and thus are just aliases
|
||||
TMap<FString, FString> AliasedGotoLabels;
|
||||
|
||||
/// Conditional blocks
|
||||
/// "if" creates a new context, uses current as parent
|
||||
/// "elseif" and "else" also create new contexts, but copies parent from current (sibling)
|
||||
/// "endif" ends the context
|
||||
/// You cannot have conditionals that were started in an indent context ending outside it
|
||||
TArray<ConditionalContext> ConditionalBlocks;
|
||||
/// Index of the current conditional block, if any
|
||||
int CurrentConditionalBlockIdx = -1;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
IndentLevelStack.Reset();
|
||||
EdgeInProgressNodeIdx = EdgeInProgressEdgeIdx -1;
|
||||
Nodes.Reset();
|
||||
GotoLabelList.Reset();
|
||||
PendingGotoLabels.Reset();
|
||||
AliasedGotoLabels.Reset();
|
||||
ConditionalBlocks.Reset();
|
||||
CurrentConditionalBlockIdx = -1;
|
||||
}
|
||||
};
|
||||
|
||||
ParsedTree HeaderTree;
|
||||
ParsedTree BodyTree;
|
||||
|
||||
struct ParsedMetadata
|
||||
{
|
||||
public:
|
||||
FName Key;
|
||||
FString Value;
|
||||
int IndentLevel;
|
||||
|
||||
ParsedMetadata(const FName& InKey, const FString& InValue, int InIndentLevel)
|
||||
: Key(InKey),
|
||||
Value(InValue),
|
||||
IndentLevel(InIndentLevel)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/// Text Metadata applied to speaker lines / choices until reset
|
||||
/// For each key there's a stack of metadata, with most indented at the top
|
||||
TMap<FName, TArray<ParsedMetadata>> PersistentMetadata;
|
||||
/// Text Metadata applied just to the next speaker line or choice
|
||||
TMap<FName, ParsedMetadata> TransientMetadata;
|
||||
/// User metadata for the next speaker line or choice
|
||||
TMap<FName, FSUDSExpression> UserMetadata;
|
||||
|
||||
/// List of speakers, detected during parsing of lines of text
|
||||
TArray<FString> ReferencedSpeakers;
|
||||
|
||||
const int TabIndentValue = 4;
|
||||
bool bHeaderDone = false;
|
||||
bool bTooLateForHeader = false;
|
||||
bool bHeaderInProgress = false;
|
||||
TOptional<bool> bOverrideGenerateSpeakerLineForChoice;
|
||||
TOptional<FString> OverrideChoiceSpeakerID;
|
||||
bool bTextInProgress = false;
|
||||
int ChoiceUniqueId = 0;
|
||||
/// For generating text IDs
|
||||
int TextIDHighestNumber = 0;
|
||||
/// For generating gosub IDs
|
||||
int GosubIDHighestNumber = 0;
|
||||
/// Parse a single line
|
||||
bool ParseLine(const FStringView& Line, int LineNo, const FString& NameForErrors, FSUDSMessageLogger* Logger, bool bSilent);
|
||||
bool ParseHeaderLine(const FStringView& Line, int IndentLevel, int LineNo, const FString& NameForErrors, FSUDSMessageLogger* Logger, bool bSilent);
|
||||
bool ParseBodyLine(const FStringView& Line, int IndentLevel, int LineNo, const FString& NameForErrors, FSUDSMessageLogger* Logger, bool bSilent);
|
||||
bool ParseCommentMetadataLine(const FStringView& Line, int IndentLevel, int LineNo, const FString& NameForErrors, FSUDSMessageLogger* Logger, bool bSilent);
|
||||
bool IsLastNodeOfType(const ParsedTree& Tree, ESUDSParsedNodeType Type);
|
||||
bool ParseChoiceLine(const FStringView& Line, ParsedTree& Tree, int IndentLevel, int LineNo, const FString& NameForErrors, FSUDSMessageLogger*
|
||||
Logger,
|
||||
bool bSilent);
|
||||
FSUDSParsedEdge* GetEdgeInProgress(ParsedTree& Tree);
|
||||
void EnsureChoiceNodeExistsAboveSelect(ParsedTree& Tree, int IndentLevel, int LineNo);
|
||||
static bool IsConditionalLine(const FStringView& Line);
|
||||
bool ParseConditionalLine(const FStringView& Line, ParsedTree& Tree, int IndentLevel, int LineNo, const FString& NameForErrors, FSUDSMessageLogger* Logger, bool bSilent);
|
||||
bool ParseIfLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
const FString& ConditionStr,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseElseIfLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
const FString& ConditionStr,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
|
||||
bool ParseElseLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseEndIfLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger*
|
||||
Logger,
|
||||
bool bSilent);
|
||||
static bool IsRandomLine(const FStringView& Line);
|
||||
bool ParseRandomLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseBeginRandomLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseRandomOptionLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseEndRandomLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseGotoLabelLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseGotoLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseGosubLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseReturnLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseSetLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseEventLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseTextLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool ParseImportSettingLine(const FStringView& Line,
|
||||
ParsedTree& Tree,
|
||||
int IndentLevel,
|
||||
int LineNo,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
TMap<FName, FString> GetTextMetadataForNextEntry(int CurrentLineIndent);
|
||||
TMap<FName, FSUDSExpression> ConsumeUserMetadata();
|
||||
bool IsCommentLine(const FStringView& TrimmedLine);
|
||||
FStringView TrimLine(const FStringView& Line, int& OutIndentLevel) const;
|
||||
int FindChoiceAfterTextNode(const FSUDSScriptImporter::ParsedTree& Tree, int TextNodeIdx, const FString& ConditionalPath);
|
||||
int RecurseChoiceNodeFindDeepest(const ParsedTree& Tree, int FromChoiceIdx, const FString& ConditionalPath);
|
||||
int RecurseSelectNodeFindDeepestChoice(const ParsedTree& Tree, int FromSelectNode, const FString& ConditionalPath);
|
||||
int FindEdge(const FSUDSScriptImporter::ParsedTree& Tree, int ParentNodeIdx, int TargetNodeIndex);
|
||||
FString MakeIfConditionPathElement(int SelectNodeIdx, const FString& ConditionStr);
|
||||
FString MakeElseIfConditionPathElement(int SelectNodeIdx, const FString& ConditionStr);
|
||||
FString MakeElseConditionPathElement(int SelectNodeIdx);
|
||||
int FindLastChoiceNode(const ParsedTree& Tree, int IndentLevel);
|
||||
int FindLastChoiceNode(const ParsedTree& Tree, int IndentLevel, int FromIndex, const FString& ConditionPath);
|
||||
void PopIndent(ParsedTree& Tree);
|
||||
void PushIndent(ParsedTree& Tree, int NodeIdx, int Indent, const FString& Path);
|
||||
FString GetCurrentTreePath(const FSUDSScriptImporter::ParsedTree& Tree);
|
||||
FString GetCurrentTreeConditionalPath(const FSUDSScriptImporter::ParsedTree& Tree);
|
||||
FString GetTreeConditionalPath(const ParsedTree& Tree, int NodeIndex);
|
||||
void SetFallthroughForNewNode(FSUDSScriptImporter::ParsedTree& Tree, FSUDSParsedNode& NewNode);
|
||||
int AppendNode(ParsedTree& Tree, const FSUDSParsedNode& InNode);
|
||||
bool SelectNodeIsMissingElsePath(const FSUDSScriptImporter::ParsedTree& Tree, const FSUDSParsedNode& Node);
|
||||
bool PostImportSanityCheck(const FString& NameForErrors, FSUDSMessageLogger* Logger, bool bSilent);
|
||||
bool ChoiceNodeCheckPaths(const FSUDSParsedNode& ChoiceNode,
|
||||
const FString& NameForErrors,
|
||||
FSUDSMessageLogger* Logger,
|
||||
bool bSilent);
|
||||
bool RecurseChoiceNodeCheckPaths(const FSUDSParsedNode& OrigChoiceNode, const FSUDSParsedNode& CurrChoiceNode, const FString& NameForErrors, FSUDSMessageLogger* Logger, bool bSilent);
|
||||
bool RecurseChoiceNodeCheckPaths(const FSUDSParsedNode& ChoiceNode, const FSUDSParsedEdge& Edge, const FString& NameForErrors, FSUDSMessageLogger*
|
||||
Logger,
|
||||
bool bSilent);
|
||||
void ConnectRemainingNodes(ParsedTree& Tree, const FString& NameForErrors, FSUDSMessageLogger* Logger, bool bSilent);
|
||||
void GenerateTextIDs(ParsedTree& BodyTree);
|
||||
int FindFallthroughNodeIndex(ParsedTree& Tree, int StartNodeIndex, const FString& FromChoicePath, const FString& FromConditionalPath);
|
||||
bool RetrieveAndRemoveTextID(FStringView& InOutLine, FString& OutTextID);
|
||||
bool RetrieveAndRemoveGosubID(FStringView& InOutLine, FString& OutTextID);
|
||||
FString GenerateTextID();
|
||||
const FSUDSParsedNode* GetNode(const ParsedTree& Tree, int Index = 0);
|
||||
int GetGotoTargetNodeIndex(const ParsedTree& Tree, const FString& InLabel);
|
||||
void PopulateAssetFromTree(USUDSScript* Asset,
|
||||
const ParsedTree& Tree,
|
||||
TArray<TObjectPtr<class USUDSScriptNode>>* pOutNodes,
|
||||
TMap<FName, int>* pOutLabels,
|
||||
UStringTable* StringTable);
|
||||
|
||||
public:
|
||||
const FSUDSParsedNode* GetNode(int Index = 0);
|
||||
const FSUDSParsedNode* GetHeaderNode(int Index = 0);
|
||||
/// Resolve a goto label to a target index (after import), or -1 if not resolvable
|
||||
int GetGotoTargetNodeIndex(const FString& Label);
|
||||
static bool RetrieveTextIDFromLine(FStringView& InOutLine, FString& OutTextID, int& OutNumber);
|
||||
static bool RetrieveGosubIDFromLine(FStringView& InOutLine, FString& OutID, int& OutNumber);
|
||||
};
|
||||
Reference in New Issue
Block a user