/// <summary> /// Attaches an object to the specified node. /// </summary> /// <param name="nodeName">Name of the node to attach to.</param> /// <param name="prefab">Prefab for the object to be attached.</param> /// <returns>Whether or not the attachment was a success - failure indicates that the node does not exist.</returns> public bool AttachToNode(string nodeName, GameObject prefab) { // Verify that the prefab is set. if (prefab == null) { Debug.LogWarning("Warning: Attempted to attach a null prefab to a NodeSkeletonBehavior."); return(false); } // Verify that the skeleton structure is set. if (SkeletonStructure == null) { Debug.LogWarning("Warning: Attempted to attach a node to a NodeSkeletonBehavior with no skeleton structure defined!"); return(false); } // Check for the node name. if (!SkeletonStructure.ContainsNode(nodeName)) { Debug.LogWarning("Warning: Attempted to retrieve a node (" + nodeName + ") that does not exist!"); return(false); } // Retrieve the node, then get its location. NSSNode node = SkeletonStructure.GetNode(nodeName); // Instantiate the object, then set its local position, scale and rotation. GameObject subObject = (GameObject)Instantiate(prefab, Vector3.zero, Quaternion.identity); subObject.transform.parent = transform; subObject.transform.localPosition = node.Offset; subObject.transform.localRotation = Quaternion.identity; return(true); }
public int GetFromCU(CompilationUnit cu, string className, out string data) { stringBuilder.Clear(); internalCallId = 0; stringBuilder.AppendLine("namespace NWN.Core"); stringBuilder.AppendLine("{"); stringBuilder.AppendLine($"{Output_CSharp.GetIndent(1)}public static partial class NWScript"); stringBuilder.AppendLine($"{Output_CSharp.GetIndent(1)}{{"); ProcessCustomConstants(); for (int index = 0; index < cu.m_Nodes.Count; index++) { NSSNode node = cu.m_Nodes[index]; NSSNode nextNode = index < cu.m_Nodes.Count - 1 ? cu.m_Nodes[index + 1] : null; if (node is LineComment lineComment) { string xmlEscapedComment = lineComment.Comment .Replace("\"", """) .Replace("'", "'") .Replace("<", "<") .Replace(">", ">") .Replace("&", "&"); stringBuilder.Append($"{Output_CSharp.GetIndent(2)}/// " + xmlEscapedComment); if (nextNode is Comment) { stringBuilder.Append("<br/>"); } stringBuilder.AppendLine(); } if (node is BlockComment blockComment) { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(2)}/*"); foreach (string line in blockComment.CommentLines) { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(2)}" + line); } stringBuilder.AppendLine($"{Output_CSharp.GetIndent(2)}*/"); } if (node is LvalueDeclSingleWithAssignment lvalueDecl) { BuildConstant(lvalueDecl); if (cu.m_Nodes.Count > index + 2 && !(cu.m_Nodes[index + 1] is LvalueDeclSingleWithAssignment)) { stringBuilder.AppendLine(); } } if (node is UnknownPreprocessor unknPreprocessor) { BuildDefine(unknPreprocessor); } if (node is FunctionDeclaration funcDecl) { BuildMethod(funcDecl); } } stringBuilder.AppendLine($"{Output_CSharp.GetIndent(1)}}}"); stringBuilder.AppendLine("}"); data = stringBuilder.ToString(); return(0); }
private void ProcessImplementationNode(FunctionImplementation implementation, List <string> vectorDecls, NSSNode node, int depth) { string expression; switch (node) { case LvalueDeclSingleWithAssignment declAssignment: expression = VMTranslations.TryTranslate(pluginNameVar, declAssignment.m_Expression.m_Expression); if (declAssignment.m_Lvalue.Identifier == "sFunc") { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}const {declAssignment.m_Type.Declaration} {declAssignment.m_Lvalue.Identifier} = {expression};"); stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}VM.NWNX.SetFunction({pluginNameVar}, sFunc);"); break; } stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}{declAssignment.m_Type.Declaration} {declAssignment.m_Lvalue.Identifier} = {expression};"); break; case LvalueAssignment assignment: string[] identifier = assignment.m_Lvalue.Identifier.Split('.', 2); if (identifier.Length > 1 && vectorDecls.Contains(identifier[0])) { identifier[1] = identifier[1].ToUpper(); } expression = VMTranslations.TryTranslate(pluginNameVar, assignment.m_Expression.m_Expression); stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}{string.Join('.', identifier)} = {expression};"); break; case LvalueDeclSingle declaration: if (declaration.m_Type.GetType() == typeof(StringType)) { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}{VMTranslations.RemovePrefixes(pluginNameVar, declaration.m_Type.Declaration)} {declaration.m_Lvalue.Identifier} = \"\";"); } else if (declaration.m_Type is StructType) { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}{VMTranslations.RemovePrefixes(pluginNameVar, declaration.m_Type.Declaration)} {declaration.m_Lvalue.Identifier} = default;"); } else if (declaration.m_Type is VectorType) { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}{VMTranslations.RemovePrefixes(pluginNameVar, declaration.m_Type.Declaration)} {declaration.m_Lvalue.Identifier} = default;"); vectorDecls.Add(declaration.m_Lvalue.Identifier); } else { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}{VMTranslations.RemovePrefixes(pluginNameVar, declaration.m_Type.Declaration)} {declaration.m_Lvalue.Identifier};"); } break; case FunctionCall functionCall: expression = VMTranslations.TranslateCall(pluginNameVar, functionCall.m_Name.Identifier, functionCall.m_Arguments); stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}{expression};"); break; case ReturnStatement returnStatement: if (implementation.ReturnType is StructType || implementation.ReturnType is VectorType) { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}return {returnStatement.m_Expression.m_Expression};"); break; } stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}return {implementation.ReturnType.NWNXPopFormat};"); break; case IfStatement ifStatement: expression = VMTranslations.TryTranslate(pluginNameVar, ifStatement.m_Expression.m_Expression); if (!expression.Contains("==") && !expression.Contains("!=") && !expression.Contains("<") && !expression.Contains(">")) { if (expression.StartsWith("!")) { expression = $"{expression.Substring(1)} == FALSE"; } else { expression = $"{expression} == TRUE"; } } stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}if ({expression})"); ProcessImplementationNode(implementation, vectorDecls, ifStatement.m_Action, depth); break; case ElseStatement elseStatement: stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}else"); ProcessImplementationNode(implementation, vectorDecls, elseStatement.m_Action, depth); break; case ForLoop forLoop: stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}for ({forLoop.m_Pre.m_Expression}; {forLoop.m_Condition.m_Expression}; {forLoop.m_Post.m_Expression})"); ProcessImplementationNode(implementation, vectorDecls, forLoop.m_Action, depth); break; case Block block: stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}{{"); foreach (NSSNode childNode in block.m_Nodes) { ProcessImplementationNode(implementation, vectorDecls, childNode, depth + 1); } stringBuilder.AppendLine($"{Output_CSharp.GetIndent(depth)}}}"); break; } }
public int GetFromCU(CompilationUnit cu, string className, out string data) { stringBuilder.Clear(); pluginNameVar = null; stringBuilder.AppendLine("using static NWN.Core.NWScript;"); stringBuilder.AppendLine(); stringBuilder.AppendLine("namespace NWN.Core.NWNX"); stringBuilder.AppendLine("{"); int attributePos = stringBuilder.Length; stringBuilder.AppendLine(); stringBuilder.AppendLine($"{Output_CSharp.GetIndent(1)}public class {className}"); stringBuilder.AppendLine($"{Output_CSharp.GetIndent(1)}{{"); HashSet <FunctionImplementation> implementedMethods = new HashSet <FunctionImplementation>(); for (int index = 0; index < cu.m_Nodes.Count; index++) { NSSNode node = cu.m_Nodes[index]; if (node is LineComment lineComment) { string xmlEscapedComment = lineComment.Comment .Replace("&", "&") .Replace("\"", """) .Replace("'", "'") .Replace("<", "<") .Replace(">", ">") .Replace("/ @}", " @}"); if (xmlEscapedComment.Contains("@param")) { string paramName = xmlEscapedComment.Split(' ')[2]; stringBuilder.AppendLine($"{Output_CSharp.GetIndent(2)}//{xmlEscapedComment.Replace($"@param {paramName} ", $"<param name=\"{paramName}\">").Replace($"@param {paramName}", $"<param name=\"{paramName}\">")}</param>"); } else if (xmlEscapedComment.Contains("@return")) { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(2)}//{xmlEscapedComment.Replace("@return ", $"<returns>").Replace("@return", $"<returns>")}</returns>"); } else { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(2)}//" + xmlEscapedComment.Replace("@brief ", "")); } } if (node is BlockComment blockComment) { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(2)}/*"); foreach (string line in blockComment.CommentLines) { stringBuilder.AppendLine($"{Output_CSharp.GetIndent(2)}" + line); } stringBuilder.AppendLine($"{Output_CSharp.GetIndent(2)}*/"); } if (node is LvalueDeclSingleWithAssignment lvalueDecl) { // First entry is always the plugin name. if (pluginNameVar == null) { if (lvalueDecl.m_Type.GetType() != typeof(StringType)) { data = null; return(-1); } pluginNameVar = lvalueDecl.m_Lvalue.Identifier; } string type = lvalueDecl.m_Type.Declaration; string name = lvalueDecl.m_Lvalue.Identifier; string value = lvalueDecl.m_Expression.m_Expression; stringBuilder.AppendLine($"{Output_CSharp.GetIndent(2)}public const {type} {name} = {value}{(lvalueDecl.m_Type.GetType() == typeof(FloatType) && !value.EndsWith("f") ? "f" : "")};"); if (cu.m_Nodes.Count > index + 2 && !(cu.m_Nodes[index + 1] is LvalueDeclSingleWithAssignment)) { stringBuilder.AppendLine(); } } if (pluginNameVar == null) { continue; } if (node is FunctionDeclaration funcDecl) { FunctionImplementation funcImpl = GetFunction(cu, funcDecl); if (implementedMethods.Contains(funcImpl)) { continue; } BuildMethod(funcImpl); implementedMethods.Add(funcImpl); } if (node is FunctionImplementation func) { if (implementedMethods.Contains(func)) { continue; } BuildMethod(func); implementedMethods.Add(func); } } stringBuilder.AppendLine($"{Output_CSharp.GetIndent(1)}}}"); // Structures foreach (StructDeclaration structDeclaration in cu.m_Nodes.OfType <StructDeclaration>()) { stringBuilder.AppendLine(); stringBuilder.AppendLine($"{Output_CSharp.GetIndent(1)}public struct {VMTranslations.RemovePrefixes(pluginNameVar, structDeclaration.m_Name.Identifier)}"); stringBuilder.AppendLine($"{Output_CSharp.GetIndent(1)}{{"); foreach (LvalueDeclSingle dec in structDeclaration.m_Members.OfType <LvalueDeclSingle>()) { string type = dec.m_Type.Declaration; string name = dec.m_Lvalue.Identifier; stringBuilder.AppendLine($"{Output_CSharp.GetIndent(2)}public {type} {name};"); } stringBuilder.AppendLine($"{Output_CSharp.GetIndent(1)}}}"); } stringBuilder.Append("}"); stringBuilder.AppendLine(); if (pluginNameVar == null) { data = null; return(-1); } stringBuilder.Insert(attributePos, $"{Output_CSharp.GetIndent(1)}[NWNXPlugin({pluginNameVar})]"); data = stringBuilder.ToString(); return(0); }