示例#1
0
 public Node(int index, int indent, ScriptNode scriptNode, TranslatedScript ts)
 {
     this.index      = index;
     this.indent     = indent;
     this.scriptNode = scriptNode;
     this.children   = new List <Node>();
     this.ts         = ts;
 }
示例#2
0
            public string ToString(Perso perso)
            {
                if (scriptNode != null)
                {
                    string firstChildNode  = (this.children.Count > 0 && this.children[0] != null) ? this.children[0].ToString() : "null";
                    string secondChildNode = (this.children.Count > 1 && this.children[1] != null) ? this.children[1].ToString() : "null";
                    string prefix          = (ts.printAddresses ? "{" + scriptNode.offset.ToString() + "}" : "");

                    AITypes aiTypes = Settings.s.aiTypes;
                    uint    param   = scriptNode.param;

                    switch (scriptNode.nodeType)
                    {
                    case ScriptNode.NodeType.KeyWord:
                        string keyword = param < aiTypes.keywordTable.Length ? aiTypes.keywordTable[param] : "";
                        switch (keyword)
                        {
                        // If keywords
                        case "If": return(prefix + "if ({condition})".Replace("{condition}", firstChildNode));

                        case "IfNot": return(prefix + "if (!({condition}))".Replace("{condition}", firstChildNode));

                        case "If2": return(prefix + "if (globalRandomizer % 2 == 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "If4": return(prefix + "if (globalRandomizer % 4 == 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "If8": return(prefix + "if (globalRandomizer % 8 == 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "If16": return(prefix + "if (globalRandomizer % 16 == 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "If32": return(prefix + "if (globalRandomizer % 32 == 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "If64": return(prefix + "if (globalRandomizer % 64 == 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "IfNot2": return(prefix + "if (globalRandomizer % 2 != 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "IfNot4": return(prefix + "if (globalRandomizer % 4 != 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "IfNot8": return(prefix + "if (globalRandomizer % 8 != 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "IfNot16": return(prefix + "if (globalRandomizer % 16 != 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "IfNot32": return(prefix + "if (globalRandomizer % 32 != 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "IfNot64": return(prefix + "if (globalRandomizer % 64 != 0 && ({condition}))".Replace("{condition}", firstChildNode));

                        case "IfDebug": return(prefix + "if (debug && {condition})".Replace("{condition}", firstChildNode));

                        case "IfNotU64": return(prefix + "if (!u64)\n{\n{childNodes}\n}\n".Replace("{childNodes}", string.Join("\n", Array.ConvertAll <Node, String>(this.children.ToArray(), x => x.ToString()))));

                        // Then
                        case "Then": return(prefix + "{\n{childNodes}\n}\n".Replace("{childNodes}", string.Join("\n", Array.ConvertAll <Node, String>(this.children.ToArray(), x => x.ToString()))));

                        // Else
                        case "Else": return(prefix + "else\n{\n{childNodes}\n}\n".Replace("{childNodes}", string.Join("\n", Array.ConvertAll <Node, String>(this.children.ToArray(), x => x.ToString()))));

                        default: return(prefix + scriptNode.ToString(perso, ts.settings));
                        }

                    case ScriptNode.NodeType.Condition:
                        string cond = param < aiTypes.conditionTable.Length ? aiTypes.conditionTable[param] : "";
                        switch (cond)
                        {
                        // Boolean conditions:
                        case "Cond_And": return(prefix + firstChildNode + " && " + secondChildNode);

                        case "Cond_Or": return(prefix + firstChildNode + " || " + secondChildNode);

                        case "Cond_Not": return(prefix + "!" + "(" + firstChildNode + ")");

                        case "Cond_XOR": return(prefix + firstChildNode + " != " + secondChildNode);        // XOR

                        // Real (float) comparisons:
                        case "Cond_Equal": return(prefix + firstChildNode + " == " + secondChildNode);

                        case "Cond_Different": return(prefix + firstChildNode + " != " + secondChildNode);

                        case "Cond_Lesser": return(prefix + firstChildNode + " < " + secondChildNode);

                        case "Cond_Greater": return(prefix + firstChildNode + " > " + secondChildNode);

                        case "Cond_LesserOrEqual": return(prefix + firstChildNode + " <= " + secondChildNode);

                        case "Cond_GreaterOrEqual": return(prefix + firstChildNode + " >= " + secondChildNode);

                        // Button condition:

                        /*case 44:
                         * case 45:
                         * case 46:
                         * case 47:
                         *  return prefix + firstChildNode;*/

                        default:
                            if (firstChildNode != null)
                            {
                                return(prefix + scriptNode.ToString(perso, ts.settings) + "(" + string.Join(", ", Array.ConvertAll <Node, String>(this.children.ToArray(), x => x.ToString())) + ")");
                            }
                            else
                            {
                                return(prefix + scriptNode.ToString(perso, ts.settings) + "()");
                            }
                        }

                    case ScriptNode.NodeType.Function:
                        string function     = param < aiTypes.functionTable.Length ? aiTypes.functionTable[param] : "";
                        string ternaryCheck = "";

                        switch (function)
                        {
                        // Ternary real operators (e.g. x > y ? true : false)
                        case "Func_TernInf":
                        case "Func_TernSup":
                        case "Func_TernEq":
                        case "Func_TernInfEq":
                        case "Func_TernSupEq":
                            switch (function)
                            {
                            case "Func_TernInf": ternaryCheck = " < "; break;

                            case "Func_TernSup": ternaryCheck = " > "; break;

                            case "Func_TernEq": ternaryCheck = " == "; break;

                            case "Func_TernInfEq": ternaryCheck = " <= "; break;

                            case "Func_TernSupEq": ternaryCheck = " >= "; break;
                            }
                            if (this.children.Count >= 4)
                            {
                                return(prefix + "((" + this.children[0] + ternaryCheck + this.children[1] + ") ? " + this.children[2] + " : " + this.children[3] + ")");
                            }
                            else
                            {
                                return("ERROR");
                            }

                        case "Func_TernOp":         // conditional ternary operator (cond ? true : false)

                            string childCast1 = "";
                            string childCast2 = "";

                            if (this.children[1].scriptNode.nodeType == ScriptNode.NodeType.DsgVarRef && this.children[2].scriptNode.nodeType == ScriptNode.NodeType.Real)
                            {
                                childCast1 = "(float)";
                            }
                            if (this.children[2].scriptNode.nodeType == ScriptNode.NodeType.DsgVarRef && this.children[1].scriptNode.nodeType == ScriptNode.NodeType.Real)
                            {
                                childCast2 = "(float)";
                            }

                            return(prefix + "((" + this.children[0] + ") ? " + childCast1 + this.children[1] + " : " + childCast2 + this.children[2] + ")");

                        default:
                            string func = scriptNode.ToString(perso, ts.settings);
                            return(prefix + func + "(" + string.Join(", ", Array.ConvertAll <Node, String>(this.children.ToArray(), x => x.ToString())) + ")");
                        }



                    case ScriptNode.NodeType.Procedure:
                        string procedure = param < aiTypes.procedureTable.Length ? aiTypes.procedureTable[param] : "";
                        switch (procedure)
                        {
                        case "Proc_Loop": return(prefix + "for(int i = 0; i < " + firstChildNode + "; i++)\n{");

                        case "Proc_EndLoop": return(prefix + "}\n");

                        case "Proc_Break": return(prefix + "break;\n");

                        default:
                            string proc = scriptNode.ToString(perso, ts.settings);
                            return(prefix + proc + "(" + string.Join(", ", Array.ConvertAll <Node, String>(this.children.ToArray(), x => x.ToString())) + ");");
                        }

                    case ScriptNode.NodeType.Operator:
                        string  op       = param < aiTypes.operatorTable.Length ? aiTypes.operatorTable[param] : "";
                        Pointer persoPtr = null;

                        switch (op)
                        {
                        // scalar:
                        case "Operator_Plus": return("(" + firstChildNode + (children[1].scriptNode.param >= 0 ? " + " : "") + secondChildNode + ")");

                        case "Operator_Minus":
                        case "Operator_UnaryMinus":
                            if (children.Count > 1)
                            {
                                return("(" + firstChildNode + " - " + secondChildNode + ")");
                            }
                            else
                            {
                                return("-" + firstChildNode);
                            }

                        case "Operator_Mul": return("(" + firstChildNode + " * " + secondChildNode + ")");

                        case "Operator_Div": return("(" + firstChildNode + " / " + secondChildNode + ")");

                        case "Operator_Mod": return("(" + firstChildNode + " % " + secondChildNode + ")");

                        // affect:
                        case "Operator_PlusAffect":
                        case "Operator_PlusPlusAffect":
                            return(children.Count > 1 ? (firstChildNode + " += " + secondChildNode + ";") : firstChildNode + "++" + ";");

                        case "Operator_MinusAffect":
                        case "Operator_MinusMinusAffect":
                            return(children.Count > 1 ? (firstChildNode + " -= " + secondChildNode + ";") : firstChildNode + "--" + ";");

                        case "Operator_MulAffect": return(firstChildNode + " *= " + secondChildNode + ";");

                        case "Operator_DivAffect": return(firstChildNode + " /= " + secondChildNode + ";");

                        case "Operator_Affect": return(firstChildNode + " = " + secondChildNode + ";");

                        case "Operator_Dot":         // dot operator
                            persoPtr = this.children[0].scriptNode.param_ptr;
                            if (persoPtr != null)
                            {
                                Perso firstNodePerso = Perso.FromOffset(persoPtr);

                                /*if (firstNodePerso != null) {
                                 *  string secondChildNodeWithDifferentContext = (this.children.Count > 1 && this.children[1] != null) ? this.children[1].ToString(firstNodePerso) : "null";
                                 *  return firstChildNode + "." + secondChildNodeWithDifferentContext;
                                 * } else {*/
                                return(firstChildNode + "." + this.children[1].ToString(null));
                                //}
                            }

                            return(firstChildNode + "." + secondChildNode);

                        case ".X": return(firstChildNode + ".x");        // vector

                        case ".Y": return(firstChildNode + ".y");        // vector

                        case ".Z": return(firstChildNode + ".z");        // vector

                        case "Operator_VectorPlusVector": return(firstChildNode + " + " + secondChildNode);

                        case "Operator_VectorMinusVector": return(firstChildNode + " - " + secondChildNode);

                        case "Operator_VectorMulScalar": return(firstChildNode + " * " + secondChildNode);

                        case "Operator_VectorDivScalar": return(firstChildNode + " / " + secondChildNode);

                        case "Operator_VectorUnaryMinus": return("-" + firstChildNode);

                        case ".X:=": return(firstChildNode + ".x = " + secondChildNode + ";"); // vector

                        case ".Y:=": return(firstChildNode + ".y = " + secondChildNode + ";"); // vector

                        case ".Z:=": return(firstChildNode + ".z = " + secondChildNode + ";"); // vector

                        case "Operator_Ultra":                                                 // Ultra operator (execute code for different object)
                            return(firstChildNode + ".{code}".Replace("{code}", secondChildNode));

                        case "Operator_ModelCast": return("((" + firstChildNode + ")(" + secondChildNode + "))");

                        case "Operator_Array": return(firstChildNode + "[" + secondChildNode + "]");

                        default:
                            string proc = "(" + scriptNode.param + ")" + scriptNode.ToString(perso, ts.settings);
                            return(prefix + proc + "(" + string.Join(", ", Array.ConvertAll <Node, String>(this.children.ToArray(), x => x.ToString())) + ");");
                        }

                    case ScriptNode.NodeType.Field:
                        if (firstChildNode != null)
                        {
                            return(prefix + scriptNode.ToString(perso, ts.settings) + "(" + string.Join(", ", Array.ConvertAll <Node, String>(this.children.ToArray(), x => x.ToString())) + ")");
                        }
                        else
                        {
                            return(prefix + scriptNode.ToString(perso, ts.settings));
                        }

                    case ScriptNode.NodeType.Vector:
                    case ScriptNode.NodeType.ConstantVector:

                        return(prefix + scriptNode.ToString(perso, ts.settings) + "(" + string.Join(", ", Array.ConvertAll <Node, String>(this.children.ToArray(), x => x.ToString())) + ")");

                    case ScriptNode.NodeType.MetaAction:

                        return(prefix + scriptNode.ToString(perso, ts.settings) + "(" + string.Join(", ", Array.ConvertAll <Node, String>(this.children.ToArray(), x => x.ToString())) + ");");

                    case ScriptNode.NodeType.SubRoutine:

                        if (ts.expandMacros)
                        {
                            Macro macro = MapLoader.Loader.FromOffset <Macro>(scriptNode.param_ptr);

                            if (macro != null)
                            {
                                string macroString = "// evalMacro(" + macro.ShortName + ");";
                                macroString += Environment.NewLine;
                                TranslatedScript macroScript = new TranslatedScript(macro.script, perso);
                                macroScript.expandMacros = true;
                                macroString += macroScript.ToString();
                                macroString += Environment.NewLine + "// end macro";
                                return(macroString);
                            }
                        }

                        return(prefix + scriptNode.ToString(perso, ts.settings));

                    default:
                        return(prefix + scriptNode.ToString(perso, ts.settings));
                    }
                }
                else   // Root node returns all children concatenated
                {
                    string result = "";
                    foreach (Node child in this.children)
                    {
                        result += child.ToString() + '\n';
                    }
                    return(result);
                }
            }