Пример #1
0
        public void SaveChunk(BinaryWriter writer)
        {
            int unusedSize;
            var basePos = (int)writer.BaseStream.Position;

            writer.Write(0x4D434E4B);
            writer.Write(0);
            var header    = mHeader;
            var headerPos = writer.BaseStream.Position;
            var startPos  = writer.BaseStream.Position;

            writer.Write(header);

            SaveHeights(writer, basePos, ref header);
            SaveMccv(writer, basePos, ref header);
            SaveNormals(writer, basePos, ref header);

            // INFO: SaveAlpha must be called before SaveLayers since SaveAlpha modifies the layer flags
            int alphaChunkSize;
            var alphaStream = SaveAlpha(ref header, out alphaChunkSize);

            SaveLayers(writer, basePos, ref header);

            header.Mcrf = (int)writer.BaseStream.Position - basePos;
            var references = DoodadReferences.Concat(mWmoRefs).ToArray();

            writer.Write(0x4D435246);
            writer.Write(references.Length * 4);
            writer.WriteArray(references);
            header.NumDoodadRefs = DoodadReferences.Length;

            //SaveUnusedChunk(writer, 0x4D435246, basePos, out header.Mcrf, out unusedSize);
            SaveUnusedChunk(writer, 0x4D435348, basePos, out header.Mcsh, out unusedSize);

            // Noggit panics when MCAL is not after MCLY even though there is no reason
            // that any sane person would imply an order in an interchangeable file format,
            // but lets make them happy anyway.
            header.Mcal = (int)writer.BaseStream.Position - basePos;
            writer.Write(0x4D43414C);
            writer.Write(alphaChunkSize);
            writer.Write(alphaStream.ToArray());

            SaveUnusedChunks(writer, basePos, ref header);

            var endPos = writer.BaseStream.Position;

            writer.BaseStream.Position = headerPos;
            writer.Write(header);
            writer.BaseStream.Position = headerPos - 4;
            writer.Write((int)(endPos - startPos));
            writer.BaseStream.Position = endPos;
        }
Пример #2
0
Файл: Wmo.cs Проект: ywscr/Tools
        public bool open(uint fileId, WMORoot rootWmo)
        {
            Stream stream = Program.CascHandler.OpenFile((int)fileId);

            if (stream == null)
            {
                Console.WriteLine("No such file.");
                return(false);
            }

            using (BinaryReader reader = new BinaryReader(stream))
            {
                long fileLength = reader.BaseStream.Length;
                while (reader.BaseStream.Position < fileLength)
                {
                    string fourcc = reader.ReadStringFromChars(4, true);
                    uint   size   = reader.ReadUInt32();

                    if (fourcc == "MOGP")//Fix sizeoff = Data size.
                    {
                        size = 68;
                    }

                    long nextpos = reader.BaseStream.Position + size;

                    if (fourcc == "MOGP")//header
                    {
                        groupName     = reader.ReadInt32();
                        descGroupName = reader.ReadInt32();
                        mogpFlags     = reader.ReadInt32();

                        for (var i = 0; i < 3; ++i)
                        {
                            bbcorn1[i] = reader.ReadSingle();
                        }

                        for (var i = 0; i < 3; ++i)
                        {
                            bbcorn2[i] = reader.ReadSingle();
                        }

                        moprIdx     = reader.ReadUInt16();
                        moprNItems  = reader.ReadUInt16();
                        nBatchA     = reader.ReadUInt16();
                        nBatchB     = reader.ReadUInt16();
                        nBatchC     = reader.ReadUInt32();
                        fogIdx      = reader.ReadUInt32();
                        groupLiquid = reader.ReadUInt32();
                        groupWMOID  = reader.ReadUInt32();

                        // according to WoW.Dev Wiki:
                        if (Convert.ToBoolean(rootWmo.flags & 4))
                        {
                            groupLiquid = GetLiquidTypeId(groupLiquid);
                        }
                        else if (groupLiquid == 15)
                        {
                            groupLiquid = 0;
                        }
                        else
                        {
                            groupLiquid = GetLiquidTypeId(groupLiquid + 1);
                        }

                        if (groupLiquid != 0)
                        {
                            liquflags |= 2;
                        }
                    }
                    else if (fourcc == "MOPY")
                    {
                        mopy_size  = (int)size;
                        nTriangles = (int)size / 2;
                        MOPY       = reader.ReadString((int)size);
                    }
                    else if (fourcc == "MOVI")
                    {
                        MOVI = new ushort[size / 2];
                        for (var i = 0; i < size / 2; ++i)
                        {
                            MOVI[i] = reader.ReadUInt16();
                        }
                    }
                    else if (fourcc == "MOVT")
                    {
                        MOVT = new float[size / 4];
                        for (var i = 0; i < size / 4; ++i)
                        {
                            MOVT[i] = reader.ReadSingle();
                        }

                        nVertices = size / 12;
                    }
                    else if (fourcc == "MONR")
                    {
                    }
                    else if (fourcc == "MOTV")
                    {
                    }
                    else if (fourcc == "MOBA")
                    {
                        MOBA      = new ushort[size / 2];
                        moba_size = (int)(size / 2);

                        for (var i = 0; i < size / 2; ++i)
                        {
                            MOBA[i] = reader.ReadUInt16();
                        }
                    }
                    else if (fourcc == "MODR")
                    {
                        for (var i = 0; i < size / 2; ++i)
                        {
                            DoodadReferences.Add(reader.Read <ushort>());
                        }
                    }
                    else if (fourcc == "MLIQ")
                    {
                        liquflags  |= 1;
                        hlq         = reader.Read <WMOLiquidHeader>();
                        LiquEx_size = 8 * hlq.xverts * hlq.yverts;
                        LiquEx      = new WMOLiquidVert[hlq.xverts * hlq.yverts];
                        for (var i = 0; i < hlq.xverts * hlq.yverts; ++i)
                        {
                            LiquEx[i] = reader.Read <WMOLiquidVert>();
                        }

                        int nLiquBytes = hlq.xtiles * hlq.ytiles;
                        LiquBytes = reader.ReadBytes(nLiquBytes);

                        // Determine legacy liquid type
                        if (groupLiquid == 0)
                        {
                            for (int i = 0; i < hlq.xtiles * hlq.ytiles; ++i)
                            {
                                if ((LiquBytes[i] & 0xF) != 15)
                                {
                                    groupLiquid = GetLiquidTypeId((uint)(LiquBytes[i] & 0xF) + 1);
                                    break;
                                }
                            }
                        }

                        /* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
                         * llog << filename;
                         * llog << "\nbbox: " << bbcorn1[0] << ", " << bbcorn1[1] << ", " << bbcorn1[2] << " | " << bbcorn2[0] << ", " << bbcorn2[1] << ", " << bbcorn2[2];
                         * llog << "\nlpos: " << hlq->pos_x << ", " << hlq->pos_y << ", " << hlq->pos_z;
                         * llog << "\nx-/yvert: " << hlq->xverts << "/" << hlq->yverts << " size: " << size << " expected size: " << 30 + hlq->xverts*hlq->yverts*8 + hlq->xtiles*hlq->ytiles << std::endl;
                         * llog.close(); */
                    }
                    reader.BaseStream.Seek((int)nextpos, SeekOrigin.Begin);
                }
            }

            return(true);
        }