Ejemplo n.º 1
0
 private void ParseFileForStatics(BinaryReader br, Dictionary<string, staticOverride> OverrideList, bool activators, bool includemisc, Dictionary<string, bool> IgnoreList) {
     int DEBUG_statics = 0;
     int DEBUG_ignored = 0;
     //Look for any scripts that might be disabling activators
     if (activators) {
         ParseFileForDisableScripts(br, OverrideList);
         //Rest file position
         br.BaseStream.Position = 0;
     }
     string s = "";
     while (br.BaseStream.Position < br.BaseStream.Length) {
         s = ReadString(br);
         int size = br.ReadInt32();
         br.BaseStream.Position += 8;
         if (s == "STAT" || s == "ACTI" || s == "DOOR" || s == "CONT" || s == "LIGH") {
             int read = 0;
             bool activator = s == "ACTI";
             bool misc = s == "DOOR" || s == "CONT" || s == "LIGH";
             string name = null;
             string model = null;
             string script = null;
             while (read < size) {
                 s = ReadString(br);
                 int size2 = br.ReadInt32();
                 read += size2 + 8;
                 switch (s) {
                     case "NAME":
                         name = ReadCString(br).ToLower(Statics.Culture);
                         break;
                     case "MODL":
                         model = ReadCString(br).ToLower(Statics.Culture);
                         break;
                     case "SCRI":
                         script = ReadCString(br).ToLower(Statics.Culture);
                         break;
                     default:
                         br.BaseStream.Position += size2;
                         break;
                 }
             }
             if (name != null && model != null && model.Trim () != null) {
                 //Named exceptions
                 if (IgnoreList != null && IgnoreList.ContainsKey(name)) {
                     if (!IgnoreList[name]) {
                         StaticsList[name] = new Static(name, model);
                         if (OverrideList != null && OverrideList.ContainsKey(model) && OverrideList[model].Ignore) {
                             OverrideList[model] = new staticOverride(OverrideList[model], true);
                             if (DEBUG) { DEBUG_statics++; continue; }
                         }
                     }
                     if (DEBUG) DEBUG_ignored++;
                     continue;
                 }
                 //NoScript override
                 if (script != null && OverrideList != null && OverrideList.ContainsKey(model) && OverrideList[model].NoScript) {
                     script = null;
                 }
                 //Special exceptions
                 if (name == "chargen boat" || name == "chargen_plank") {
                     if (DEBUG) DEBUG_ignored++;
                     continue;
                 }
                 //Special model exceptions
                 if (model == "f\\active_blight_large.nif") {
                     if (OverrideList != null && !OverrideList.ContainsKey(model)) {
                         if (DEBUG) DEBUG_ignored++;
                         continue;
                     }
                 }
                 if ((misc && !includemisc) || activator && !activators) {
                     if (OverrideList != null && OverrideList.ContainsKey(model) && !OverrideList[model].Ignore) {
                         if (script != null && DisableScripts != null && DisableScripts.ContainsKey(script) && DisableScripts[script] == true) {
                             if (DEBUG) DEBUG_ignored++;
                             continue;
                         }
                         StaticsList[name] = new Static(name, model);
                         if (DEBUG) DEBUG_statics++;
                     }
                 } else {
                     if (OverrideList == null || !OverrideList.ContainsKey(model) || !OverrideList[model].Ignore) {
                         if (script != null && DisableScripts != null && DisableScripts.ContainsKey(script) && DisableScripts[script] == true) {
                             if (DEBUG) DEBUG_ignored++;
                             continue;
                         }
                         StaticsList[name] = new Static(name, model);
                         if (DEBUG) DEBUG_statics++;
                     }
                 }
             }
         } else br.BaseStream.Position += size;
     }
     if (DEBUG) allWarnings.Add("Static definitions: " + DEBUG_statics + "; Ignored definitions: " + DEBUG_ignored);
 }
Ejemplo n.º 2
0
        void workerCreateStatics(object sender, System.ComponentModel.DoWorkEventArgs e) {
            CreateStaticsArgs args = (CreateStaticsArgs)e.Argument;
            List<string> warnings = new List<string>();
            Dictionary<string, staticOverride> OverrideList = new Dictionary<string, staticOverride>();
            Dictionary<string, bool> IgnoreList = new Dictionary<string, bool>();
            Dictionary<string, bool> CellList = new Dictionary<string, bool>();
            StaticsList.Clear();
            UsedStaticsList.Clear();
            StaticMap.Clear();
            if (args.useOverrideList && args.OverrideList.Count > 0) foreach (string overrideList in args.OverrideList) {
                if (DEBUG) allWarnings.Add("Loading override: " + overrideList);
                StreamReader sr = null;
                try { sr = new StreamReader(File.OpenRead(overrideList)); }
                catch { warnings.Add("Error: Could not import statics list '" + overrideList + "'"); }
                if (sr != null) {
                    int index; string section = ""; string line; string escape;
                    while (!sr.EndOfStream) switch (section) {
                        case "":
                            line = sr.ReadLine().ToLower(Statics.Culture);
                            index = line.IndexOf(':');
                            if (index != -1) line = line.Substring(0, index);
                            line = line.Trim();
                            if (line.Length > 0 && line[0] != '#') {
                                if (line.StartsWith("[") && line.EndsWith("]")) {
                                    section = line.Substring(1, line.Length - 2);
                                    continue;
                                }
                                index = line.LastIndexOf('=');
                                if (index != -1) {
                                    string mesh = line.Substring(0, index);
                                    string value = line.Substring(index + 1);
                                    byte type;
                                    if (byte.TryParse(value, out type)) {
                                        if (type != 3 && type <= 6) OverrideList[line] = new staticOverride(type);
                                        else if (type > 6) warnings.Add("Warning: Invalid type specified in statics list '" + overrideList + "' line '" + line + "'");
                                    } else OverrideList[mesh] = new staticOverride(value);
                                } else {
                                	warnings.Add("Warning: Failed to parse line in statics list '" + overrideList + "': '" + line + "'");
                                }
                            }
                            break;
                        case "names":
                            line = sr.ReadLine().ToLower(Statics.Culture);
                            index = line.IndexOf(':');
                            escape = line;
                            if (index != -1) escape = escape.Substring(0, index);
                            escape = escape.Trim();
                            if (escape.Length > 0 && escape.StartsWith("[") && escape.EndsWith("]") && !escape.EndsWith("\\]")) {
                                section = escape.Substring(1, escape.Length - 2);
                                continue;
                            }
                            if (line.IndexOf('\u0001') != -1) continue;
                            escape = "";
                            while ((index = line.IndexOf('\\') + 1) != 0) {
                                if (index == line.Length) break;
                                escape += line[index];
                                line = line.Substring(0, index - 1) + "\u0001" + (line.Length >= index ? line.Substring(index + 1) : "");
                            }
                            index = line.IndexOf(':');
                            if (index != -1) line = line.Substring(0, index);
                            line = line.Trim();
                            int equals_index = line.LastIndexOf('=');
                            for (var i = 0; (index = line.IndexOf ('\u0001')) != -1; i++) {
                                line = line.Substring(0, index) + escape[i] + (line.Length >= index ? line.Substring(index + 1) : "");
                            }
                            if (line.Length > 0) {
                                if (equals_index == -1) IgnoreList[line] = true;
                                else {
                                    string value = line.Substring(equals_index + 1);
                                    line = line.Substring(0, equals_index);
                                    switch (value) {
                                        case "enable":
                                            IgnoreList[line] = false;
                                            break;
                                        case "disable":
                                            IgnoreList[line] = true;
                                            break;
                                        default:
                                            warnings.Add("Warning: Invalid keyword in statics list line '" + line + "'");
                                            break;
                                    }
                                }
                            }
                            break;
                        case "interiors":
                            line = sr.ReadLine().ToLower(Statics.Culture);
                            index = line.IndexOf (':');
                            escape = line;
                            if (index != -1) escape = escape.Substring (0, index);
                            escape = escape.Trim();
                            if (escape.Length > 0 && escape.StartsWith("[") && escape.EndsWith("]") && !escape.EndsWith("\\]")) {
                                section = escape.Substring(1, escape.Length - 2);
                                continue;
                            }
                            if (line.IndexOf ('\u0001') != -1) continue;
                            escape = "";
                            while ((index = line.IndexOf('\\') + 1) != 0) {
                                if (index == line.Length) break;
                                escape += line[index];
                                line = line.Substring(0, index - 1) + "\u0001" + (line.Length >= index ? line.Substring(index + 1) : "");
                            }
                            index = line.IndexOf(':');
                            if (index != -1) line = line.Substring(0, index);
                            line = line.Trim();
                            equals_index = line.LastIndexOf('=');
                            for (var i = 0; (index = line.IndexOf('\u0001')) != -1; i++) {
                                line = line.Substring(0, index) + escape[i] + (line.Length >= index ? line.Substring(index + 1) : "");
                            }
                            if (line.Length > 0) {
                                if (equals_index == -1) CellList[line] = true;
                                else {
                                    string value = line.Substring(equals_index + 1);
                                    line = line.Substring(0, equals_index);
                                    switch (value) {
                                        case "enable":
                                            CellList[line] = true;
                                            break;
                                        case "disable":
                                            CellList[line] = false;
                                            break;
                                        default:
                                            warnings.Add("Warning: Invalid keyword in statics cell list line '" + line + "'");
                                            break;
                                    }
                                }
                            }
                            break;
                    }
                    sr.Close();
                }
            }
            Directory.CreateDirectory(Statics.fn_statics);
            foreach (string file in files) {
                if (DEBUG) allWarnings.Add("Parsing for statics definitions: " + file);
                BinaryReader br = new BinaryReader(File.OpenRead(file), System.Text.Encoding.Default);
                ParseFileForStatics(br, OverrideList, args.activators, args.misc, IgnoreList);
                br.Close();
            }
            backgroundWorker.ReportProgress(1, strings["StaticsGenerate1"]);
            UsedStaticsList.Add("", new Dictionary<string, StaticReference>());
            foreach (string file in files) {
                if (DEBUG) allWarnings.Add("Parsing for used statics: " + file);
                BinaryReader br = new BinaryReader(File.OpenRead(file), System.Text.Encoding.Default);
                FileInfo fi = new FileInfo(file);
                try {
                    ParseFileForCells(br, fi.Name, IgnoreList, CellList);
                } catch (Exception ex) {
                    warnings.Add("Non-fatal error in ParseFileForCells(\"" + file + "\"): " + ex.Message);
                }
                br.Close();
            }
            //Generate a list of the NIF files we need to load
            backgroundWorker.ReportProgress(2, strings["StaticsGenerate2"]);
            List<string> UsedNifList = new List<string>();
            foreach (KeyValuePair<string, Dictionary<string, StaticReference>> cellStatics in UsedStaticsList) {
                foreach (KeyValuePair<string, StaticReference> pair in cellStatics.Value) {
                    string nif_name = StaticsList[pair.Value.name].mesh;
                    if (!UsedNifList.Contains(nif_name)) UsedNifList.Add(nif_name);
                }
            }
            backgroundWorker.ReportProgress(3, strings["StaticsGenerate3"]);
            unsafe {
                NativeMethods.BeginStaticCreation((IntPtr)DXMain.device.ComPointer, Statics.fn_statmesh);
            }
            Random rnd = new Random();
            try {
                //Try to load the NIFs and remove any from the list that fail or are too small
                for (int i = 0; i < UsedNifList.Count; i++) {
                    string name = UsedNifList[i];
                    byte[] data;

                    //Try to load a version of the file that ends with '_dist' first.
                    // This allows people to supply a different version of the NIF to be
                    // rendered by distant land.  For example, a low poly nif.
                    string file_name = name;
                    string extention = "";
                    int dot_pos = file_name.LastIndexOf ('.');
                    if (dot_pos != -1) {
                        extention = file_name.Substring (dot_pos, file_name.Length - dot_pos);
                        file_name = file_name.Substring (0, dot_pos);
                    }
                    string dist_name = file_name + "_dist" + extention;
                    try {
                        data = BSA.GetNif (dist_name);
                    } catch {
                        // We didn't find a NIF file with '_dist' in its name,
                        // so search for the normal NIF file now.
                        try {
                            data = BSA.GetNif (name);
                        } catch {
                            data = null;
                        }
                    }
                    if (data == null) {
                        UsedNifList.RemoveAt (i--);
                    } else {
                        try {
                            if (DEBUG) {
                                statusText.Text = strings["StaticsGenerate3Nif"] + name;
                                allWarnings.Add ("Processing NIF: " + name);
                            }
                            float size = -1;
                            if (OverrideList.ContainsKey (name)) {
                                staticOverride so = OverrideList[name];
                                if (!so.Ignore || so.NamesNoIgnore) size = NativeMethods.ProcessNif (data, data.Length, so.overrideSimplify ? so.Simplify : args.simplify, args.MinSize, (byte)so.Type, (so.OldSimplify ? (byte)1 : (byte)0));
                            } else {
                                // Set static classification based on the file path
                                if (name.StartsWith ("grass\\")) size = NativeMethods.ProcessNif (data, data.Length, args.simplify, args.MinSize, (byte)StaticType.Grass, 0);
                                else if (name.StartsWith ("trees\\")) size = NativeMethods.ProcessNif (data, data.Length, args.simplify, args.MinSize, (byte)StaticType.Tree, 0);
                                else if (name.StartsWith ("x\\")) size = NativeMethods.ProcessNif (data, data.Length, args.simplify, args.MinSize, (byte)StaticType.Building, 0);
                                else size = NativeMethods.ProcessNif (data, data.Length, args.simplify, args.MinSize, (byte)StaticType.Auto, 0);
                            }
                            if (size < 0) UsedNifList.RemoveAt (i--);
                        } catch (Exception) {
                            warnings.Add ("Failed to process " + name);
                            UsedNifList.RemoveAt (i--);
                        }
                    }
                }
            } finally {
                NativeMethods.EndStaticCreation();
            }
            //Reset used distant static ID numbers to match NIF list order
            Dictionary<string, uint> NifMap = new Dictionary<string, uint>();
            uint count = 0;
            foreach (string name in UsedNifList) NifMap[name] = count++;
            List<StaticToRemove> UsedStaticsToRemove = new List<StaticToRemove>();
            //Determine floating point grass density
            float GrassDensity = (float)udStatGrassDensity.Value / 100.0f;
            foreach (KeyValuePair<string, Dictionary<string, StaticReference>> cellStatics in UsedStaticsList) {
                foreach (KeyValuePair<string, StaticReference> pair in cellStatics.Value) {
                    string nif_name = StaticsList[pair.Value.name].mesh;
                    if (NifMap.ContainsKey(nif_name)) pair.Value.staticID = NifMap[nif_name];
                    else UsedStaticsToRemove.Add(new StaticToRemove(cellStatics.Key, pair.Key));
                    if (nif_name.StartsWith("grass\\") || (OverrideList.ContainsKey (nif_name) && OverrideList[nif_name].Type == StaticType.Grass)) {
                        if (OverrideList.ContainsKey (nif_name)) {
                            if (OverrideList[nif_name].Density >= 0) GrassDensityThreshold (OverrideList[nif_name].Density, cellStatics, pair, rnd, UsedStaticsToRemove);
                            else GrassDensityThreshold (GrassDensity, cellStatics, pair, rnd, UsedStaticsToRemove);
                        } else GrassDensityThreshold (GrassDensity, cellStatics, pair, rnd, UsedStaticsToRemove);
                    }
                }
            }
            foreach (StaticToRemove key in UsedStaticsToRemove) UsedStaticsList[key.worldspace].Remove(key.reference);
            backgroundWorker.ReportProgress(4, strings["StaticsGenerate4"]);
            BinaryWriter bw = new BinaryWriter(File.Create(Statics.fn_usagedata), System.Text.Encoding.Default);
            bw.Write(UsedNifList.Count);
            bw.Write(UsedStaticsList[""].Count);
            //uint UseRef = 0;
            foreach (KeyValuePair<string, StaticReference> pair in UsedStaticsList[""]) pair.Value.Write(bw/*, UseRef++*/);
            UsedStaticsList[""].Clear();
            UsedStaticsList.Remove("");
            char[] cellName = new char[64];
            foreach (KeyValuePair<string, Dictionary<string, StaticReference>> cellStatics in UsedStaticsList) {
                bw.Write((int)(cellStatics.Value as Dictionary<string, StaticReference>).Count);
                int i; for (i = 0; i < 64; ++i) cellName[i] = '\0'; i = 0;
                foreach (char c in cellStatics.Key) cellName[i++] = c;
                bw.Write(cellName, 0, 64);
                foreach (KeyValuePair<string, StaticReference> pair in cellStatics.Value) pair.Value.Write(bw/*, UseRef++*/);
            }
            bw.Write((int)0);
            bw.Write((float)Convert.ToSingle(udStatMinSize.Value));
            bw.Close();
            
            if (!File.Exists(Statics.fn_statmesh)) return;
            setFinishDesc(4);
            backgroundWorker.ReportProgress(5, strings["StaticsGenerate5"]);
            {
                StaticTexCreator stc = new StaticTexCreator(args.MipSkip);
                BinaryReader br = new BinaryReader(File.OpenRead(Statics.fn_statmesh), System.Text.Encoding.Default);
                foreach (string name in UsedNifList) {
                    int nodes = br.ReadInt32();
                    br.BaseStream.Position += 16; //4 - radius, 12 - center
                    int type = br.BaseStream.ReadByte();
                    for (int j = 0; j < nodes; j++) {
                        br.BaseStream.Position += 40; //4 - radius, 12 - center, 12 - min, 12 - center
                        int verts = br.ReadInt32();
                        int faces = br.ReadInt32();
                        int vert_size = NativeMethods.GetCompressedVertSize();
                        br.BaseStream.Position += verts * vert_size + faces * 6;
                        short chars = br.ReadInt16();
                        string path = new string(br.ReadChars(chars - 1));
                        br.BaseStream.Position += 1;
                        try {
                            if (type != (int)StaticType.Grass && type != (int)StaticType.Tree)
                            {
                                bool ok = stc.LoadTexture(path);
                                if(!ok) warnings.Add("Warning: Texture '"+path+"' could not be converted to a distant texture, original texture will be used");
                            }
                        } catch (ArgumentException) {
                            //warnings.Add("Warning: Texture '"+path+"' on subset "+j+" of mesh '"+pair.Key+"' could not be found");
                        }
                    }
                }
                br.Close();
                stc.Dispose();
            }
            if (warnings.Count > 0) e.Result = warnings;
        }
Ejemplo n.º 3
0
 public staticOverride(staticOverride value, bool enabledInNames) {
     OldSimplify = value.OldSimplify;
     Simplify = value.Simplify;
     Density = value.Density;
     overrideSimplify = value.overrideSimplify;
     Ignore = value.Ignore;
     StaticsOnly = value.StaticsOnly;
     Type = value.Type;
     NoScript = value.NoScript;
     NamesNoIgnore = enabledInNames;
 }