public static void ExtractSet(WMODoodadData doodadData, MODF wmo, bool isGlobalWmo, uint mapID, uint originalMapId, BinaryWriter writer, List <ADTOutputCache> dirfileCache) { if (wmo.DoodadSet >= doodadData.Sets.Count) { return; } Vector3 wmoPosition = new Vector3(wmo.Position.Z, wmo.Position.X, wmo.Position.Y); Matrix3 wmoRotation = Matrix3.fromEulerAnglesZYX(MathFunctions.toRadians(wmo.Rotation.Y), MathFunctions.toRadians(wmo.Rotation.X), MathFunctions.toRadians(wmo.Rotation.Z)); if (isGlobalWmo) { wmoPosition += new Vector3(533.33333f * 32, 533.33333f * 32, 0.0f); } ushort doodadId = 0; MODS doodadSetData = doodadData.Sets[wmo.DoodadSet]; using (BinaryReader reader = new BinaryReader(new MemoryStream(doodadData.Paths))) { foreach (ushort doodadIndex in doodadData.References) { if (doodadIndex < doodadSetData.StartIndex || doodadIndex >= doodadSetData.StartIndex + doodadSetData.Count) { continue; } MODD doodad = doodadData.Spawns[doodadIndex]; reader.BaseStream.Position = doodad.NameIndex; string ModelInstName = reader.ReadCString().GetPlainName(); if (ModelInstName.Length > 3) { string extension = ModelInstName.Substring(ModelInstName.Length - 4); if (extension == ".mdx" || extension == ".mdl") { ModelInstName = ModelInstName.Remove(ModelInstName.Length - 2, 2); ModelInstName += "2"; } } if (!File.Exists(Program.WmoDirectory + ModelInstName)) { continue; } using (BinaryReader binaryReader = new BinaryReader(File.Open(Program.WmoDirectory + ModelInstName, FileMode.Open, FileAccess.Read, FileShare.Read))) { binaryReader.BaseStream.Seek(8, SeekOrigin.Begin); // get the correct no of vertices int nVertices = binaryReader.ReadInt32(); if (nVertices == 0) { continue; } } ++doodadId; Vector3 position = wmoPosition + (wmoRotation * new Vector3(doodad.Position.X, doodad.Position.Y, doodad.Position.Z)); Vector3 rotation; (new Quaternion(doodad.Rotation.X, doodad.Rotation.Y, doodad.Rotation.Z, doodad.Rotation.W).toRotationMatrix() * wmoRotation).toEulerAnglesXYZ(out rotation.Z, out rotation.X, out rotation.Y); rotation.Z = MathFunctions.toDegrees(rotation.Z); rotation.X = MathFunctions.toDegrees(rotation.X); rotation.Y = MathFunctions.toDegrees(rotation.Y); ushort nameSet = 0; // not used for models uint uniqueId = VmapFile.GenerateUniqueObjectId(wmo.UniqueId, doodadId); uint flags = ModelFlags.M2; if (mapID != originalMapId) { flags |= ModelFlags.ParentSpawn; } //write mapID, Flags, NameSet, UniqueId, Pos, Rot, Scale, name writer.Write(mapID); writer.Write(flags); writer.Write(nameSet); writer.Write(uniqueId); writer.WriteVector3(position); writer.WriteVector3(rotation); writer.Write(doodad.Scale); writer.Write(ModelInstName.GetByteCount()); writer.WriteString(ModelInstName); if (dirfileCache != null) { ADTOutputCache cacheModelData = new ADTOutputCache(); cacheModelData.Flags = flags & ~ModelFlags.ParentSpawn; MemoryStream stream = new MemoryStream(); BinaryWriter cacheData = new BinaryWriter(stream); cacheData.Write(nameSet); cacheData.Write(uniqueId); cacheData.WriteVector3(position); cacheData.WriteVector3(rotation); cacheData.Write(doodad.Scale); cacheData.Write(ModelInstName.GetByteCount()); cacheData.WriteString(ModelInstName); cacheModelData.Data = stream.ToArray(); dirfileCache.Add(cacheModelData); } } } }
public static bool ExtractSingleWmo(string fileName) { // Copy files from archive string plainName = fileName.GetPlainName(); if (File.Exists(Program.WmoDirectory + plainName)) { return(true); } int p = 0; // Select root wmo files int index = plainName.IndexOf('_'); if (index != -1) { string rchr = plainName.Substring(index); if (rchr != null) { for (int i = 0; i < 4; ++i) { char m = rchr[i]; if (char.IsDigit(m)) { p++; } } } } if (p == 3) { return(true); } bool file_ok = true; Console.WriteLine($"Extracting {fileName}"); WMORoot froot = new WMORoot(); if (!froot.open(fileName)) { Console.WriteLine("Couldn't open RootWmo!!!"); return(true); } using (BinaryWriter binaryWriter = new BinaryWriter(File.Open(Program.WmoDirectory + plainName, FileMode.Create, FileAccess.Write))) { froot.ConvertToVMAPRootWmo(binaryWriter); WmoDoodads[plainName] = froot.DoodadData; WMODoodadData doodads = WmoDoodads[plainName]; int Wmo_nVertices = 0; for (int i = 0; i < froot.groupFileDataIDs.Count; ++i) { WMOGroup fgroup = new WMOGroup(); if (!fgroup.open(froot.groupFileDataIDs[i], froot)) { Console.WriteLine($"Could not open all Group file for: {plainName}"); file_ok = false; break; } Wmo_nVertices += fgroup.ConvertToVMAPGroupWmo(binaryWriter, false); foreach (ushort groupReference in fgroup.DoodadReferences) { if (groupReference >= doodads.Spawns.Count) { continue; } uint doodadNameIndex = doodads.Spawns[groupReference].NameIndex; if (!froot.ValidDoodadNames.Contains(doodadNameIndex)) { continue; } doodads.References.Add(groupReference); } } binaryWriter.Seek(8, SeekOrigin.Begin); // store the correct no of vertices binaryWriter.Write(Wmo_nVertices); // Delete the extracted file in the case of an error if (!file_ok) { File.Delete(Program.WmoDirectory + fileName); } } return(true); }
public static bool ExtractSingleWmo(uint fileId) { // Copy files from archive string fileName = $"FILE{fileId:X8}.xxx"; if (File.Exists(Program.BuildingsDirectory + fileName)) { return(true); } bool fileOk = true; // Console.WriteLine($"Extracting {fileName}"); WMORoot wmoRoot = new(); if (!wmoRoot.Open(fileId)) { Console.WriteLine("Couldn't open RootWmo!!!"); return(true); } using (BinaryWriter binaryWriter = new(File.Open(Program.BuildingsDirectory + fileName, FileMode.Create, FileAccess.Write))) { wmoRoot.ConvertToVMAPRootWmo(binaryWriter); WmoDoodads[fileName] = wmoRoot.DoodadData; WMODoodadData doodads = WmoDoodads[fileName]; int wmoVertices = 0; for (int i = 0; i < wmoRoot.groupFileDataIDs.Count; ++i) { WMOGroup wmoGroup = new(); if (!wmoGroup.Open(wmoRoot.groupFileDataIDs[i], wmoRoot)) { Console.WriteLine($"Could not open all Group files for: {fileName}"); fileOk = false; break; } wmoVertices += wmoGroup.ConvertToVMAPGroupWmo(binaryWriter, false); foreach (ushort groupReference in wmoGroup.DoodadReferences) { if (groupReference >= doodads.Spawns.Count) { continue; } uint doodadNameIndex = doodads.Spawns[groupReference].NameIndex; if (!wmoRoot.ValidDoodadNames.Contains(doodadNameIndex)) { continue; } doodads.References.Add(groupReference); } } binaryWriter.Seek(8, SeekOrigin.Begin); // store the correct no of vertices binaryWriter.Write(wmoVertices); // Delete the extracted file in the case of an error if (!fileOk) { File.Delete(Program.BuildingsDirectory + fileName); } } return(true); }