/// <summary> /// This method creates a script that calls ExecuteScript() to invoke /// multiple scripts. It is designed to allow multiple scripts to wire up /// to an event handler. The script is created and compiled and both /// the NSS and NCS files are added to the module. /// </summary> /// <param name="module">The module to modify</param> /// <param name="property">The property to which the scripts are being attached</param> /// <param name="originalScript">The original script on the property, or /// string.Empty if none</param> /// <param name="otherScripts">A list of other scripts to execute</param> /// <returns>The ResRef of the newly created script</returns> private string CreateExecuteScript(Erf module, string property, string originalScript, StringCollection otherScripts) { // If the original script and the otherScripts are the same then // there is nothing to do, just return originalScript as the RefRef if (1 == otherScripts.Count && 0 == string.Compare(otherScripts[0], originalScript, true, CultureInfo.InvariantCulture)) return originalScript.ToLower(); // Build the file name and full name of the script file. string substring = property.Length > 12 ? property.Substring(0, 12) : property; string sourceName = "hif_" + substring + ".nss"; string fullSourceName = Path.Combine(currentTempDir, sourceName); System.Text.StringBuilder b = new System.Text.StringBuilder(); // Check to see if the original script is one of our generated scripts // (the name will start with "hif_" if it is). If so then we need to // open the file and read the list of scripts currently being called // and add them to the list of scripts to call. StringCollection scriptsToExecute = new StringCollection(); bool createScript = 0 != string.Compare(originalScript, Path.GetFileNameWithoutExtension(sourceName), true, CultureInfo.InvariantCulture); if (!createScript) { // Read the list of scripts currently being executed from the hif_ // script file. string[] scripts = null; using (StreamReader reader = new StreamReader(fullSourceName)) { // Read the first line, strip the comment prefix off, and // split the line into all of the scripts that the script // executes. string line = reader.ReadLine(); line = line.Trim(); line = line.Substring(3, line.Length - 3); scripts = line.Split(','); } // Add all of the scripts currently in the file, and then add // all of the scripts in the otherScripts collection if they aren't // already there. scriptsToExecute.AddRange(scripts); foreach (string script in otherScripts) if (!scriptsToExecute.Contains(script)) scriptsToExecute.Add(script); } else { // Add the original script if there was on, then add all of the // other scripts to our execute list. if (string.Empty != originalScript) scriptsToExecute.Add(originalScript); foreach (string script in otherScripts) scriptsToExecute.Add(script); } // Create the script file. using (StreamWriter writer = new StreamWriter(fullSourceName, false, System.Text.Encoding.ASCII)) { // Make the first line be a list of the scripts being executed // so we can do updates to the file later. b.Length = 0; foreach (string script in scriptsToExecute) { if (b.Length > 0) b.Append(","); b.Append(script); } writer.WriteLine("// {0}", b.ToString()); // Write out a comment header. writer.WriteLine("/////////////////////////////////////////////////////////////////////"); writer.WriteLine("//"); writer.WriteLine("// This script has been auto-generated by HakInstaller to call"); writer.WriteLine("// multiple handlers for the {0} event.", property); writer.WriteLine("//"); writer.WriteLine("/////////////////////////////////////////////////////////////////////"); writer.WriteLine(""); writer.WriteLine("void main()"); writer.WriteLine("{"); // Add an execute line for each script in the collection. foreach (string script in scriptsToExecute) writer.WriteLine(" ExecuteScript(\"{0}\", OBJECT_SELF);", script); writer.WriteLine("}"); writer.Flush(); writer.Close(); } // Build the name of the obj file. string objName = Path.GetFileNameWithoutExtension(sourceName) + ".ncs"; string fullObjName = Path.Combine(currentTempDir, objName); // Generate the compiler command line. //string compiler = Path.Combine(NWNInfo.ToolsPath, "clcompile.exe"); // SBH for NWN2 // Use the PRC's compiler... its much better and can handle NWN2 string compiler = Path.Combine(NWNInfo.ToolsPath, "nwnnsscomp.exe"); b.Length = 0; // -c for compile, -I is the path to NWNSCRIPT.NSS 1 is the script to compile and 2 is the output directory for the ncs b.AppendFormat("-c -I \"{0}\" \"{1}\" \"{2}\"",NWNInfo.ToolsPath, fullSourceName, fullObjName); // Start the compiler process and wait for it. ProcessStartInfo info = new ProcessStartInfo(); info.FileName = compiler; info.Arguments = b.ToString(); info.CreateNoWindow = true; info.WindowStyle = ProcessWindowStyle.Hidden; Process process = Process.Start(info); process.WaitForExit(); // If the compiler didn't work then we have a problem. if (0 != process.ExitCode) throw new NWNException("Could not run the NWN script compiler"); // Add the source and object files to the module, if we have created new // files. If the original script was a hif_ script that we just changed // then the file is already part of the module, no need to add it. if (createScript) { module.AddFile(fullSourceName, true); module.AddFile(fullObjName, true); } // Return the ResRef for the new script file. return Path.GetFileNameWithoutExtension(sourceName).ToLower(); }