public static AreaPlane ReadFrom(BinaryReader br) { var areaPlane = new AreaPlane(); areaPlane.Version = br.ReadByte(); if (areaPlane.Version >= 240) { areaPlane.Unk1 = br.ReadByte(); areaPlane.Unk2 = br.ReadByte(); areaPlane.Unk3 = br.ReadByte(); areaPlane.Unk4 = br.ReadByte(); } areaPlane.Size = br.ReadByte(); for (var i = 0; i < MaterialSlotCount; ++i) { if (areaPlane.Version >= 240) { areaPlane.MaterialSlots[i] = br.ReadInt32(); } else { areaPlane.MaterialSlots[i] = br.ReadByte(); } } areaPlane.ShowPlane = br.ReadByte(); areaPlane.UseTiles = br.ReadByte(); br.Read(areaPlane.MaterialSlotIndexes, 0, MaterialSlotIndexCount); areaPlane.MinHeight = br.ReadSingle(); areaPlane.MaxHeight = br.ReadSingle(); if (areaPlane.Version == 1 || areaPlane.Version == 241) { areaPlane.Unk5 = br.ReadSingle(); areaPlane.Unk6 = br.ReadSingle(); } var planeCount = areaPlane.Size * areaPlane.Size; areaPlane.Planes = new List <Plane>(planeCount); for (var i = 0; i < planeCount; ++i) { var plane = Plane.ReadFrom(br); areaPlane.Planes.Add(plane); } areaPlane.Squares = new List <Square>(SquareCount); for (var i = 0; i < SquareCount; ++i) { var square = Square.ReadFrom(br); areaPlane.Squares.Add(square); } return(areaPlane); }
/// <summary> /// Reads area from stream and returns it. /// </summary> /// <param name="stream"></param> /// <returns></returns> public static Area ReadFrom(Stream stream) { using (var br = new BinaryReader(stream)) { var area = new Area(); area.Version = br.ReadInt16(); //if (area.Version == 200) // throw new UnsupportedVersionException(); area.Unk8 = br.ReadInt16(); area.Length = br.ReadInt32(); area.Id = br.ReadUInt16(); area.RegionId = br.ReadUInt16(); area.ServerName = br.ReadWString(); area.Name = br.ReadWString(); area.PlaneX = br.ReadInt32(); area.PlaneY = br.ReadInt32(); area.Unk1 = br.ReadInt32(); area.Unk2 = br.ReadInt32(); var eventCount = br.ReadInt32(); var propCount = br.ReadInt32(); area.Unk3 = br.ReadSingle(); area.Unk4 = br.ReadSingle(); area.Unk5 = br.ReadInt32(); area.Unk6 = br.ReadInt32(); area.Unk7 = br.ReadInt32(); area.BottomLeft = br.ReadVector3F_XZY(); area.BottomRight = br.ReadVector3F_XZY(); area.TopRight = br.ReadVector3F_XZY(); area.TopLeft = br.ReadVector3F_XZY(); if (area.Version == 203) { area.Unk9 = br.ReadInt32(); } area.Version2 = br.ReadInt32(); var propCount2 = br.ReadInt32(); area.Props = new List <Prop>(propCount2); for (var i = 0; i < propCount2; ++i) { var prop = Prop.ReadFrom(area, br); area.Props.Add(prop); } area.Events = new List <Event>(eventCount); for (var i = 0; i < eventCount; ++i) { var evnt = Event.ReadFrom(area, br); area.Events.Add(evnt); } var areaPlanesCount = (area.PlaneX * area.PlaneY); area.AreaPlanes = new List <AreaPlane>(areaPlanesCount); for (var i = 0; i < areaPlanesCount; ++i) { var plane = AreaPlane.ReadFrom(br, area.Version); area.AreaPlanes.Add(plane); } // Usually 65|68 bytes follow the planes, purpose unknown // and why they appear hasn't been researched yet, neither // why the lengths differ. var length = (int)(br.BaseStream.Length - br.BaseStream.Position); area.Unk10 = br.ReadBytes(length); if (length != 65 && length != 68) { throw new FormatException($"Expected 65|68 byte tail, got {length}."); } if (br.BaseStream.Position != br.BaseStream.Length) { throw new FormatException($"Area file '{area.Name}' longer or shorter than expected."); } return(area); } }