// handle null nodes private static NodeBase DecompileNode(CompiledScriptNode node) { switch (node.NodeType) { case CompiledNodeType.FunctionCall: { List <NodeBase> parameters = new List <NodeBase>(); CompiledScriptNode firstChild = new CompiledScriptNode(BitConverter.ToInt16(node.ValueData, 0), s_nodeDataReader); short childIndex = firstChild.NextSiblingIndex; while (childIndex != -1) { CompiledScriptNode child = new CompiledScriptNode(childIndex, s_nodeDataReader); parameters.Add(DecompileNode(child)); childIndex = child.NextSiblingIndex; } /*if (node.OpCode == 0) // Begin * return new GroupingNode(parameters);*/ return(new BslFunctionCallNode(node.OpCode, parameters)); } case CompiledNodeType.ScriptCall: { List <NodeBase> parameters = new List <NodeBase>(); CompiledScriptNode firstChild = new CompiledScriptNode(BitConverter.ToInt16(node.ValueData, 0), s_nodeDataReader); short childIndex = firstChild.NextSiblingIndex; while (childIndex != -1) { CompiledScriptNode child = new CompiledScriptNode(childIndex, s_nodeDataReader); parameters.Add(DecompileNode(child)); childIndex = child.NextSiblingIndex; } return(new ScriptCallNode(s_scripts[node.OpCode] as ScriptNode, parameters)); } case CompiledNodeType.GlobalReference: { uint index = BitConverter.ToUInt32(node.ValueData, 0); if (index >= 0xFFFF8000) { return(new BslGameGlobalReferenceNode((short)(index - 0xFFFF8000), node.ValueType)); } else { return(new VariableReferenceValueNode(s_globals[(short)index] as VariableNode, node.ValueType)); } } case CompiledNodeType.Value: { switch ((IntegralValueType)node.ValueType) { case IntegralValueType.Bool: return(new BoolValueNode(BitConverter.ToBoolean(node.ValueData, 0))); case IntegralValueType.Real: return(new RealValueNode(BitConverter.ToSingle(node.ValueData, 0))); case IntegralValueType.Short: return(new ShortValueNode(BitConverter.ToInt16(node.ValueData, 0))); case IntegralValueType.Long: return(new LongValueNode(BitConverter.ToInt32(node.ValueData, 0))); case IntegralValueType.String: return(new StringValueNode(s_scnr.GetScriptString(node.StringTableOffset))); case IntegralValueType.Script: return(new ScriptReferenceValueNode(s_scripts[BitConverter.ToInt16(node.ValueData, 0)] as ScriptNode)); } ExtendedTypeBase type = s_engineDefinition.ExtendedTypes[node.ValueType - ExtendedTypeBase.FirstTypeIndex]; if (type is EnumerationType) { return(new EnumerationValueNode(type as EnumerationType, BitConverter.ToInt16(node.ValueData, 0))); } if (type is BlockReferenceType) { return (new BlockReferenceValueNode(type as BlockReferenceType, s_scnr.GetBlockStringForScriptingReferenceType( BitConverter.ToInt16(node.ValueData, 0), type.TypeIndex))); } if (type is TagReferenceType) { return(new TagReferenceValueNode(type as TagReferenceType, s_tagList[BitConverter.ToInt16(node.ValueData, 0)])); } throw new OnlyForDebuggingException("N.B. :("); } } throw new OnlyForDebuggingException("N.B. :X"); }