コード例 #1
0
ファイル: GameTime.cs プロジェクト: shawarma-golem/ACE
        public static GameTime Read(DatReader datReader)
        {
            GameTime obj = new GameTime();

            obj.ZeroTimeOfYear = datReader.ReadUInt64();
            obj.ZeroYear       = datReader.ReadUInt32();
            obj.DayLength      = datReader.ReadUInt32();
            obj.DaysPerYear    = datReader.ReadUInt32();
            obj.YearSpec       = datReader.ReadPString();
            datReader.AlignBoundary();

            uint numTimesOfDay = datReader.ReadUInt32();

            for (uint i = 0; i < numTimesOfDay; i++)
            {
                obj.TimesOfDay.Add(TimeOfDay.Read(datReader));
            }

            uint numDaysOfTheWeek = datReader.ReadUInt32();

            for (uint i = 0; i < numDaysOfTheWeek; i++)
            {
                obj.DaysOfTheWeek.Add(datReader.ReadPString());
                datReader.AlignBoundary();
            }

            uint numSeasons = datReader.ReadUInt32();

            for (uint i = 0; i < numSeasons; i++)
            {
                obj.Seasons.Add(Season.Read(datReader));
            }

            return(obj);
        }
コード例 #2
0
        public static MotionData Read(DatReader datReader)
        {
            MotionData md = new Entity.MotionData();

            byte numAnims = datReader.ReadByte();

            md.Bitfield  = datReader.ReadByte();
            md.Bitfield2 = datReader.ReadByte();
            datReader.AlignBoundary();

            for (byte i = 0; i < numAnims; i++)
            {
                AnimData animData = new AnimData();
                animData.AnimId    = datReader.ReadUInt32();
                animData.LowFrame  = datReader.ReadUInt32();
                animData.HighFrame = datReader.ReadUInt32();
                animData.Framerate = datReader.ReadSingle();
                md.Anims.Add(animData);
            }

            if ((md.Bitfield2 & 1) > 0)
            {
                md.Velocity = new AceVector3(datReader.ReadSingle(), datReader.ReadSingle(), datReader.ReadSingle());
            }

            if ((md.Bitfield2 & 2) > 0)
            {
                md.Omega = new AceVector3(datReader.ReadSingle(), datReader.ReadSingle(), datReader.ReadSingle());
            }

            return(md);
        }
コード例 #3
0
ファイル: Season.cs プロジェクト: shawarma-golem/ACE
        public static Season Read(DatReader datReader)
        {
            Season obj = new Season();

            obj.StartDate = datReader.ReadUInt32();
            obj.Name      = datReader.ReadPString();
            datReader.AlignBoundary();
            return(obj);
        }
コード例 #4
0
ファイル: TimeOfDay.cs プロジェクト: shawarma-golem/ACE
        public static TimeOfDay Read(DatReader datReader)
        {
            TimeOfDay obj = new TimeOfDay();

            obj.Start   = datReader.ReadUInt32();
            obj.IsNight = datReader.ReadUInt32();
            obj.Name    = datReader.ReadPString();
            datReader.AlignBoundary();
            return(obj);
        }
コード例 #5
0
ファイル: CellStruct.cs プロジェクト: shawarma-golem/ACE
        public static CellStruct Read(DatReader datReader)
        {
            CellStruct obj = new CellStruct();

            uint numPolygons        = datReader.ReadUInt32();
            uint numPhysicsPolygons = datReader.ReadUInt32();
            uint numPortals         = datReader.ReadUInt32();

            obj.VertexArray = CVertexArray.Read(datReader);

            for (uint i = 0; i < numPolygons; i++)
            {
                ushort poly_id = datReader.ReadUInt16();
                obj.Polygons.Add(poly_id, Polygon.Read(datReader));
            }

            for (uint i = 0; i < numPortals; i++)
            {
                obj.Portals.Add(datReader.ReadUInt16());
            }

            datReader.AlignBoundary();

            obj.CellBSP = BSPTree.Read(datReader, BSPType.Cell);

            for (uint i = 0; i < numPhysicsPolygons; i++)
            {
                ushort poly_id = datReader.ReadUInt16();
                obj.PhysicsPolygons.Add(poly_id, Polygon.Read(datReader));
            }
            obj.PhysicsBSP = BSPTree.Read(datReader, BSPType.Physics);

            uint hasDrawingBSP = datReader.ReadUInt32();

            if (hasDrawingBSP != 0)
            {
                obj.DrawingBSP = BSPTree.Read(datReader, BSPType.Drawing);
            }

            datReader.AlignBoundary();

            return(obj);
        }
コード例 #6
0
ファイル: ObjDesc.cs プロジェクト: shawarma-golem/ACE
        public static ObjDesc ReadFromDat(ref DatReader datReader)
        {
            ObjDesc od = new ObjDesc();

            datReader.AlignBoundary(); // Align to the DWORD boundary before and after the ObjDesc
            datReader.ReadByte();      // ObjDesc always starts with 11.
            int numPalettes          = datReader.ReadByte();
            int numTextureMapChanges = datReader.ReadByte();
            int numAnimPartChanges   = datReader.ReadByte();

            for (int k = 0; k < numPalettes; k++)
            {
                // TODO - This isn't actually used anywhere in the CharGen system, so let's find a test care to make sure this is accurate!
                SubPalette subpalette = new SubPalette();
                subpalette.SubID     = datReader.ReadUInt16();
                subpalette.SubID     = datReader.ReadUInt16();
                subpalette.NumColors = Convert.ToUInt16(datReader.ReadByte());
                od.SubPalettes.Add(subpalette);
            }
            for (int k = 0; k < numTextureMapChanges; k++)
            {
                TextureMapChange texturechange = new TextureMapChange();
                texturechange.PartIndex  = datReader.ReadByte();
                texturechange.OldTexture = datReader.ReadUInt16();
                texturechange.NewTexture = datReader.ReadUInt16();
                od.TextureChanges.Add(texturechange);
            }
            for (int k = 0; k < numAnimPartChanges; k++)
            {
                AnimationPartChange apchange = new AnimationPartChange();
                apchange.PartIndex = datReader.ReadByte();
                apchange.PartID    = datReader.ReadUInt16();
                if (apchange.PartID == 0x8000) // To be honest, I'm not quite sure WHAT this is/means, but the math works out
                {
                    apchange.PartID = datReader.ReadUInt16();
                }
                apchange.PartID += 0x01000000u; // convert to full uint value
                od.AnimPartChanges.Add(apchange);
            }
            datReader.AlignBoundary(); // Align to the DWORD boundary before and after the ObjDesc

            return(od);
        }
コード例 #7
0
ファイル: RegionDesc.cs プロジェクト: shawarma-golem/ACE
        public static RegionDesc ReadFromDat()
        {
            // Check the FileCache so we don't need to hit the FileSystem repeatedly
            if (DatManager.PortalDat.FileCache.ContainsKey(REGION_ID))
            {
                return((RegionDesc)DatManager.PortalDat.FileCache[REGION_ID]);
            }
            else
            {
                DatReader  datReader = DatManager.PortalDat.GetReaderForFile(REGION_ID);
                RegionDesc region    = new RegionDesc();

                region.FileId     = datReader.ReadUInt32();
                region.BLoaded    = datReader.ReadUInt32();
                region.TimeStamp  = datReader.ReadUInt32();
                region.RegionName = datReader.ReadPString(); // "Dereth"
                datReader.AlignBoundary();
                region.PartsMask = datReader.ReadUInt32();

                // There are 7 x 4 byte entries here that are "unknown". We will just skip them.
                datReader.Offset += (7 * 4);

                region.LandDefs = LandDefs.Read(datReader);
                region.GameTime = GameTime.Read(datReader);

                region.PNext = datReader.ReadUInt32();

                if ((region.PNext & 0x10) > 0)
                {
                    region.SkyInfo = SkyDesc.Read(datReader);
                }

                if ((region.PNext & 0x01) > 0)
                {
                    region.SoundInfo = SoundDesc.Read(datReader);
                }

                if ((region.PNext & 0x02) > 0)
                {
                    region.SceneInfo = SceneDesc.Read(datReader);
                }

                region.TerrainInfo = TerrainDesc.Read(datReader);

                if ((region.PNext & 0x0200) > 0)
                {
                    region.RegionMisc = RegionMisc.Read(datReader);
                }

                DatManager.PortalDat.FileCache[REGION_ID] = region;
                return(region);
            }
        }
コード例 #8
0
ファイル: SpellComponentsTable.cs プロジェクト: jumpcakes/ACE
        public static SpellComponentsTable ReadFromDat()
        {
            // Check the FileCache so we don't need to hit the FileSystem repeatedly
            if (DatManager.PortalDat.FileCache.ContainsKey(0x0E00000F))
            {
                return((SpellComponentsTable)DatManager.PortalDat.FileCache[0x0E00000F]);
            }
            else
            {
                // Create the datReader for the proper file
                DatReader            datReader = DatManager.PortalDat.GetReaderForFile(0x0E00000F);
                SpellComponentsTable comps     = new SpellComponentsTable();

                comps.FileId = datReader.ReadUInt32();
                uint numComps = datReader.ReadUInt16(); // Should be 163 or 0xA3
                datReader.AlignBoundary();
                // loop through the entire file...
                for (uint i = 0; i < numComps; i++)
                {
                    SpellComponentBase newComp = new SpellComponentBase();
                    uint compId = datReader.ReadUInt32();
                    newComp.Name = datReader.ReadObfuscatedString();
                    datReader.AlignBoundary();
                    newComp.Category = datReader.ReadUInt32();
                    newComp.Icon     = datReader.ReadUInt32();
                    newComp.Type     = datReader.ReadUInt32();
                    newComp.Gesture  = datReader.ReadUInt32();
                    newComp.Time     = datReader.ReadSingle();
                    newComp.Text     = datReader.ReadObfuscatedString();
                    datReader.AlignBoundary();
                    newComp.CDM = datReader.ReadSingle();
                    comps.SpellComponents.Add(compId, newComp);
                }

                DatManager.PortalDat.FileCache[0x0E00000F] = comps;
                return(comps);
            }
        }
コード例 #9
0
ファイル: Generator.cs プロジェクト: shawarma-golem/ACE
        public Generator GetNextGenerator(DatReader datReader)
        {
            Name = datReader.ReadObfuscatedString();
            datReader.AlignBoundary();
            Id    = datReader.ReadInt32();
            Count = datReader.ReadInt32();

            // Console.WriteLine($"{Id:X8} {Count:X8} {Name}");

            for (var i = 0; i < Count; i++)
            {
                var child = new Generator();
                child = child.GetNextGenerator(datReader);
                Items.Add(child);
            }
            return(this);
        }
コード例 #10
0
ファイル: TerrainType.cs プロジェクト: shawarma-golem/ACE
        public static TerrainType Read(DatReader datReader)
        {
            TerrainType obj = new TerrainType();

            obj.TerrainName = datReader.ReadPString();
            datReader.AlignBoundary();

            obj.TerrainColor = datReader.ReadUInt32();

            uint num_stypes = datReader.ReadUInt32();

            for (uint i = 0; i < num_stypes; i++)
            {
                obj.SceneTypes.Add(datReader.ReadUInt32());
            }

            return(obj);
        }
コード例 #11
0
        public static DayGroup Read(DatReader datReader)
        {
            DayGroup obj = new DayGroup();

            obj.ChanceOfOccur = datReader.ReadSingle();
            obj.DayName       = datReader.ReadPString();
            datReader.AlignBoundary();

            uint num_sky_objects = datReader.ReadUInt32();

            for (uint i = 0; i < num_sky_objects; i++)
            {
                obj.SkyObjects.Add(SkyObject.Read(datReader));
            }

            uint num_sky_times = datReader.ReadUInt32();

            for (uint i = 0; i < num_sky_times; i++)
            {
                obj.SkyTime.Add(SkyTimeOfDay.Read(datReader));
            }

            return(obj);
        }
コード例 #12
0
ファイル: ClothingTable.cs プロジェクト: dawsonscully/ACE
        } = new Dictionary <uint, CloSubPalEffect>();                                                                           // uint is a non-zero index

        public static ClothingTable ReadFromDat(uint fileId)
        {
            ClothingTable ct        = new ClothingTable();
            DatReader     datReader = DatManager.PortalDat.GetReaderForFile(fileId);

            ct.Id = datReader.ReadUInt32();

            uint numClothingEffects = datReader.ReadUInt16();

            datReader.Offset += 2;
            for (uint i = 0; i < numClothingEffects; i++)
            {
                ClothingBaseEffect cb = new ClothingBaseEffect();
                cb.SetupModel = datReader.ReadUInt32();
                int numObjectEffects = datReader.ReadInt32();
                for (int j = 0; j < numObjectEffects; j++)
                {
                    CloObjectEffect cloObjEffect = new CloObjectEffect();
                    cloObjEffect.Index   = datReader.ReadUInt32();
                    cloObjEffect.ModelId = datReader.ReadUInt32();
                    uint numTextureEffects = datReader.ReadUInt32();

                    for (uint k = 0; k < numTextureEffects; k++)
                    {
                        CloTextureEffect cloTexEffect = new CloTextureEffect();
                        cloTexEffect.OldTexture = datReader.ReadUInt32();
                        cloTexEffect.NewTexture = datReader.ReadUInt32();
                        cloObjEffect.CloTextureEffects.Add(cloTexEffect);
                    }

                    cb.CloObjectEffects.Add(cloObjEffect);
                }
                ct.ClothingBaseEffects.Add(cb.SetupModel, cb);
            }

            ushort numSubPalEffects = datReader.ReadUInt16();

            for (uint i = 0; i < numSubPalEffects; i++)
            {
                datReader.AlignBoundary();
                CloSubPalEffect cloSubPalEffect = new CloSubPalEffect();
                uint            subPalIdx       = datReader.ReadUInt32();
                cloSubPalEffect.Icon = datReader.ReadUInt32();
                uint numPalettes = datReader.ReadUInt32();
                for (uint j = 0; j < numPalettes; j++)
                {
                    CloSubPalette cloSubPalette = new CloSubPalette();
                    uint          length        = datReader.ReadUInt32();
                    for (uint k = 0; k < length; k++)
                    {
                        CloSubPalleteRange range = new CloSubPalleteRange();
                        range.Offset    = datReader.ReadUInt32();
                        range.NumColors = datReader.ReadUInt32();
                        cloSubPalette.Ranges.Add(range);
                    }
                    cloSubPalette.PaletteSet = datReader.ReadUInt32();
                    cloSubPalEffect.CloSubPalettes.Add(cloSubPalette);
                }
                ct.ClothingSubPalEffects.Add(subPalIdx, cloSubPalEffect);
            }
            return(ct);
        }
コード例 #13
0
ファイル: SpellTable.cs プロジェクト: fantoms/ACE
        public static SpellTable ReadFromDat()
        {
            // Check the FileCache so we don't need to hit the FileSystem repeatedly
            if (DatManager.PortalDat.FileCache.ContainsKey(0x0E00000E))
            {
                return((SpellTable)DatManager.PortalDat.FileCache[0x0E00000E]);
            }
            else
            {
                // Create the datReader for the proper file
                DatReader  datReader = DatManager.PortalDat.GetReaderForFile(0x0E00000E);
                SpellTable spells    = new SpellTable();

                spells.FileId = datReader.ReadUInt32();
                uint spellCount = datReader.ReadUInt16();
                spells.SpellBaseHash = datReader.ReadUInt16();

                for (uint i = 0; i < spellCount; i++)
                {
                    SpellBase newSpell = new SpellBase();
                    uint      spellId  = datReader.ReadUInt32();
                    newSpell.Name = datReader.ReadObfuscatedString();
                    datReader.AlignBoundary();
                    newSpell.Desc = datReader.ReadObfuscatedString();
                    datReader.AlignBoundary();
                    newSpell.School            = (MagicSchool)datReader.ReadUInt32();
                    newSpell.Icon              = datReader.ReadUInt32();
                    newSpell.Category          = datReader.ReadUInt32();
                    newSpell.Bitfield          = datReader.ReadUInt32();
                    newSpell.BaseMana          = datReader.ReadUInt32();
                    newSpell.BaseRangeConstant = datReader.ReadSingle();
                    newSpell.BaseRangeMod      = datReader.ReadSingle();
                    newSpell.Power             = datReader.ReadUInt32();
                    newSpell.SpellEconomyMod   = datReader.ReadSingle();
                    newSpell.FormulaVersion    = datReader.ReadUInt32();
                    newSpell.ComponentLoss     = datReader.ReadUInt32();
                    newSpell.MetaSpellType     = (SpellType)datReader.ReadUInt32();
                    newSpell.MetaSpellId       = datReader.ReadUInt32();

                    switch (newSpell.MetaSpellType)
                    {
                    case SpellType.Enchantment:
                    case SpellType.FellowEnchantment:
                    {
                        newSpell.Duration        = datReader.ReadDouble();
                        newSpell.DegradeModifier = datReader.ReadSingle();
                        newSpell.DegradeLimit    = datReader.ReadSingle();
                        break;
                    }

                    case SpellType.PortalSummon:
                    {
                        newSpell.PortalLifetime = datReader.ReadDouble();
                        break;
                    }
                    }

                    // Components : Load them first, then decrypt them. More efficient to hash all at once.
                    List <uint> rawComps = new List <uint>();
                    for (uint j = 0; j < 8; j++)
                    {
                        uint comp = datReader.ReadUInt32();
                        // We will only add the comp if it is valid
                        if (comp > 0)
                        {
                            rawComps.Add(comp);
                        }
                    }
                    // Get the decryped component values
                    newSpell.Formula = DecryptFormula(rawComps, newSpell.Name, newSpell.Desc);

                    newSpell.CasterEffect           = datReader.ReadUInt32();
                    newSpell.TargetEffect           = datReader.ReadUInt32();
                    newSpell.FizzleEffect           = datReader.ReadUInt32();
                    newSpell.RecoveryInterval       = datReader.ReadDouble();
                    newSpell.RecoveryAmount         = datReader.ReadSingle();
                    newSpell.DisplayOrder           = datReader.ReadUInt32();
                    newSpell.NonComponentTargetType = datReader.ReadUInt32();
                    newSpell.ManaMod = datReader.ReadUInt32();

                    spells.Spells.Add(spellId, newSpell);
                }

                DatManager.PortalDat.FileCache[0x0E00000E] = spells;
                return(spells);
            }
        }
コード例 #14
0
ファイル: Contract.cs プロジェクト: shawarma-golem/ACE
        public static Contract Read(DatReader datReader)
        {
            Contract obj = new Contract();

            obj.Version      = datReader.ReadUInt32();
            obj.ContractId   = datReader.ReadUInt32();
            obj.ContractName = datReader.ReadPString();
            datReader.AlignBoundary();

            obj.Description = datReader.ReadPString();
            datReader.AlignBoundary();
            obj.DescriptionProgress = datReader.ReadPString();
            datReader.AlignBoundary();

            obj.NameNPCStart = datReader.ReadPString();
            datReader.AlignBoundary();
            obj.NameNPCEnd = datReader.ReadPString();
            datReader.AlignBoundary();

            obj.QuestflagStamped = datReader.ReadPString();
            datReader.AlignBoundary();
            obj.QuestflagStarted = datReader.ReadPString();
            datReader.AlignBoundary();
            obj.QuestflagFinished = datReader.ReadPString();
            datReader.AlignBoundary();
            obj.QuestflagProgress = datReader.ReadPString();
            datReader.AlignBoundary();
            obj.QuestflagTimer = datReader.ReadPString();
            datReader.AlignBoundary();
            obj.QuestflagRepeatTime = datReader.ReadPString();
            datReader.AlignBoundary();

            obj.LocationNPCStart  = PositionExtensions.ReadLandblockPosition(datReader);
            obj.LocationNPCEnd    = PositionExtensions.ReadLandblockPosition(datReader);
            obj.LocationQuestArea = PositionExtensions.ReadLandblockPosition(datReader);

            return(obj);
        }
コード例 #15
0
        } = new Dictionary <uint, CloSubPalEffect>();                                                                           // uint is a non-zero index

        public static ClothingTable ReadFromDat(uint fileId)
        {
            // Check the FileCache so we don't need to hit the FileSystem repeatedly
            if (DatManager.PortalDat.FileCache.ContainsKey(fileId))
            {
                return((ClothingTable)DatManager.PortalDat.FileCache[fileId]);
            }
            else
            {
                ClothingTable ct        = new ClothingTable();
                DatReader     datReader = DatManager.PortalDat.GetReaderForFile(fileId);

                ct.Id = datReader.ReadUInt32();

                uint numClothingEffects = datReader.ReadUInt16();
                datReader.Offset += 2;
                for (uint i = 0; i < numClothingEffects; i++)
                {
                    ClothingBaseEffect cb = new ClothingBaseEffect();
                    cb.SetupModel = datReader.ReadUInt32();
                    int numObjectEffects = datReader.ReadInt32();
                    for (int j = 0; j < numObjectEffects; j++)
                    {
                        CloObjectEffect cloObjEffect = new CloObjectEffect();
                        cloObjEffect.Index   = datReader.ReadUInt32();
                        cloObjEffect.ModelId = datReader.ReadUInt32();
                        uint numTextureEffects = datReader.ReadUInt32();

                        for (uint k = 0; k < numTextureEffects; k++)
                        {
                            CloTextureEffect cloTexEffect = new CloTextureEffect();
                            cloTexEffect.OldTexture = datReader.ReadUInt32();
                            cloTexEffect.NewTexture = datReader.ReadUInt32();
                            cloObjEffect.CloTextureEffects.Add(cloTexEffect);
                        }

                        cb.CloObjectEffects.Add(cloObjEffect);
                    }
                    ct.ClothingBaseEffects.Add(cb.SetupModel, cb);
                }

                ushort numSubPalEffects = datReader.ReadUInt16();
                for (uint i = 0; i < numSubPalEffects; i++)
                {
                    datReader.AlignBoundary();
                    CloSubPalEffect cloSubPalEffect = new CloSubPalEffect();
                    uint            subPalIdx       = datReader.ReadUInt32();
                    cloSubPalEffect.Icon = datReader.ReadUInt32();
                    uint numPalettes = datReader.ReadUInt32();
                    for (uint j = 0; j < numPalettes; j++)
                    {
                        CloSubPalette cloSubPalette = new CloSubPalette();
                        uint          length        = datReader.ReadUInt32();
                        for (uint k = 0; k < length; k++)
                        {
                            CloSubPalleteRange range = new CloSubPalleteRange();
                            range.Offset    = datReader.ReadUInt32();
                            range.NumColors = datReader.ReadUInt32();
                            cloSubPalette.Ranges.Add(range);
                        }
                        cloSubPalette.PaletteSet = datReader.ReadUInt32();
                        cloSubPalEffect.CloSubPalettes.Add(cloSubPalette);
                    }
                    ct.ClothingSubPalEffects.Add(subPalIdx, cloSubPalEffect);
                }

                // Store this object in the FileCache
                DatManager.PortalDat.FileCache[fileId] = ct;
                return(ct);
            }
        }
コード例 #16
0
        public static CLandblockInfo ReadFromDat(uint landblockId)
        {
            // Check if landblockId is a full dword. We just need the hiword for the landblockId
            if ((landblockId >> 16) != 0)
            {
                landblockId = landblockId >> 16;
            }

            // The file index is CELL + 0xFFFF. e.g. a cell of 1234, the file index would be 0x1234FFFE.
            uint landblockFileIndex = (landblockId << 16) + 0xFFFE;

            // Check the FileCache so we don't need to hit the FileSystem repeatedly
            if (DatManager.CellDat.FileCache.ContainsKey(landblockFileIndex))
            {
                return((CLandblockInfo)DatManager.CellDat.FileCache[landblockFileIndex]);
            }
            else
            {
                CLandblockInfo c = new CLandblockInfo();
                if (DatManager.CellDat.AllFiles.ContainsKey(landblockFileIndex))
                {
                    DatReader datReader = DatManager.CellDat.GetReaderForFile(landblockFileIndex);

                    uint file_id = datReader.ReadUInt32();
                    c.NumCells = datReader.ReadUInt32();

                    uint num_objects = datReader.ReadUInt32();
                    for (uint i = 0; i < num_objects; i++)
                    {
                        c.ObjectIds.Add(datReader.ReadUInt32());

                        Position objPosition = new Position();
                        objPosition.PositionX = datReader.ReadSingle();
                        objPosition.PositionY = datReader.ReadSingle();
                        objPosition.PositionZ = datReader.ReadSingle();
                        objPosition.RotationW = datReader.ReadSingle();
                        objPosition.RotationX = datReader.ReadSingle();
                        objPosition.RotationY = datReader.ReadSingle();
                        objPosition.RotationZ = datReader.ReadSingle();
                        c.ObjectFrames.Add(objPosition);
                    }

                    ushort num_buildings = datReader.ReadUInt16();
                    c.PackMask = datReader.ReadUInt16();

                    for (uint i = 0; i < num_buildings; i++)
                    {
                        BuildInfo b = new BuildInfo();
                        b.ModelId = datReader.ReadUInt32();

                        // position
                        b.Frame.PositionX = datReader.ReadSingle();
                        b.Frame.PositionY = datReader.ReadSingle();
                        b.Frame.PositionZ = datReader.ReadSingle();
                        b.Frame.RotationW = datReader.ReadSingle();
                        b.Frame.RotationX = datReader.ReadSingle();
                        b.Frame.RotationY = datReader.ReadSingle();
                        b.Frame.RotationZ = datReader.ReadSingle();

                        b.NumLeaves = datReader.ReadUInt32();
                        uint num_portals = datReader.ReadUInt32();

                        for (uint j = 0; j < num_portals; j++)
                        {
                            CBldPortal cbp = new CBldPortal();
                            cbp.Flags      = datReader.ReadUInt16();
                            cbp.ExactMatch = (ushort)(cbp.Flags & 1);
                            cbp.PortalSide = (ushort)((cbp.Flags >> 1) & 1);

                            cbp.OtherCellId   = (landblockId << 16) + datReader.ReadUInt16();
                            cbp.OtherPortalId = (landblockId << 16) + datReader.ReadUInt16();

                            ushort num_stabs = datReader.ReadUInt16();
                            for (ushort k = 0; k < num_stabs; k++)
                            {
                                cbp.StabList.Add((landblockId << 16) + datReader.ReadUInt16());
                            }

                            datReader.AlignBoundary();
                            b.Portals.Add(cbp);
                        }

                        c.Buildings.Add(b);
                    }

                    if ((c.PackMask & 1) == 1)
                    {
                        ushort num_restiction_table = datReader.ReadUInt16();
                        c.UnknownShort = datReader.ReadUInt16(); // seems to always be 0x0008 ... packed val?
                        for (ushort i = 0; i < num_restiction_table; i++)
                        {
                            RestrictionTable r = new RestrictionTable();
                            r.Landblock = datReader.ReadUInt32();
                            r.Iid       = datReader.ReadUInt32();
                            c.Restriction_table.Add(r);
                        }
                    }

                    // Store this object in the FileCache
                    DatManager.CellDat.FileCache[landblockFileIndex] = c;
                }

                return(c);
            }
        }