Beispiel #1
0
        public MultiComponentList(GenericReader reader)
        {
            int version = reader.ReadInt();

            m_Min    = reader.ReadPoint2D();
            m_Max    = reader.ReadPoint2D();
            m_Center = reader.ReadPoint2D();
            m_Width  = reader.ReadInt();
            m_Height = reader.ReadInt();

            int length = reader.ReadInt();

            MultiTileEntry[] allTiles = m_List = new MultiTileEntry[length];

            if (version == 0)
            {
                for (int i = 0; i < length; ++i)
                {
                    int id = reader.ReadShort();
                    if (id >= 0x4000)
                    {
                        id -= 0x4000;
                    }

                    allTiles[i].m_ItemID  = (ushort)id;
                    allTiles[i].m_OffsetX = reader.ReadShort();
                    allTiles[i].m_OffsetY = reader.ReadShort();
                    allTiles[i].m_OffsetZ = reader.ReadShort();
                    allTiles[i].m_Flags   = reader.ReadInt();
                }
            }
            else
            {
                for (int i = 0; i < length; ++i)
                {
                    allTiles[i].m_ItemID  = reader.ReadUShort();
                    allTiles[i].m_OffsetX = reader.ReadShort();
                    allTiles[i].m_OffsetY = reader.ReadShort();
                    allTiles[i].m_OffsetZ = reader.ReadShort();
                    allTiles[i].m_Flags   = reader.ReadInt();
                }
            }

            TileList[][] tiles = new TileList[m_Width][];
            m_Tiles = new StaticTile[m_Width][][];

            for (int x = 0; x < m_Width; ++x)
            {
                tiles[x]   = new TileList[m_Height];
                m_Tiles[x] = new StaticTile[m_Height][];

                for (int y = 0; y < m_Height; ++y)
                {
                    tiles[x][y] = new TileList();
                }
            }

            for (int i = 0; i < allTiles.Length; ++i)
            {
                if (i == 0 || allTiles[i].m_Flags != 0)
                {
                    int xOffset = allTiles[i].m_OffsetX + m_Center.X;
                    int yOffset = allTiles[i].m_OffsetY + m_Center.Y;

                    tiles[xOffset][yOffset].Add((ushort)allTiles[i].m_ItemID, (sbyte)allTiles[i].m_OffsetZ);
                }
            }

            for (int x = 0; x < m_Width; ++x)
            {
                for (int y = 0; y < m_Height; ++y)
                {
                    m_Tiles[x][y] = tiles[x][y].ToArray();
                }
            }
        }
Beispiel #2
0
        public MultiComponentList(BinaryReader reader, int count)
        {
            MultiTileEntry[] allTiles = m_List = new MultiTileEntry[count];

            for (int i = 0; i < count; ++i)
            {
                allTiles[i].m_ItemID  = reader.ReadUInt16();
                allTiles[i].m_OffsetX = reader.ReadInt16();
                allTiles[i].m_OffsetY = reader.ReadInt16();
                allTiles[i].m_OffsetZ = reader.ReadInt16();
                allTiles[i].m_Flags   = reader.ReadInt32();

                if (_PostHSFormat)
                {
                    reader.ReadInt32(); // ??
                }
                MultiTileEntry e = allTiles[i];

                if (i == 0 || e.m_Flags != 0)
                {
                    if (e.m_OffsetX < m_Min.X)
                    {
                        m_Min.X = e.m_OffsetX;
                    }

                    if (e.m_OffsetY < m_Min.Y)
                    {
                        m_Min.Y = e.m_OffsetY;
                    }

                    if (e.m_OffsetX > m_Max.X)
                    {
                        m_Max.X = e.m_OffsetX;
                    }

                    if (e.m_OffsetY > m_Max.Y)
                    {
                        m_Max.Y = e.m_OffsetY;
                    }
                }
            }

            m_Center = new Point2D(-m_Min.X, -m_Min.Y);
            m_Width  = (m_Max.X - m_Min.X) + 1;
            m_Height = (m_Max.Y - m_Min.Y) + 1;

            TileList[][] tiles = new TileList[m_Width][];
            m_Tiles = new StaticTile[m_Width][][];

            for (int x = 0; x < m_Width; ++x)
            {
                tiles[x]   = new TileList[m_Height];
                m_Tiles[x] = new StaticTile[m_Height][];

                for (int y = 0; y < m_Height; ++y)
                {
                    tiles[x][y] = new TileList();
                }
            }

            for (int i = 0; i < allTiles.Length; ++i)
            {
                if (i == 0 || allTiles[i].m_Flags != 0)
                {
                    int xOffset = allTiles[i].m_OffsetX + m_Center.X;
                    int yOffset = allTiles[i].m_OffsetY + m_Center.Y;

                    tiles[xOffset][yOffset].Add((ushort)allTiles[i].m_ItemID, (sbyte)allTiles[i].m_OffsetZ);
                }
            }

            for (int x = 0; x < m_Width; ++x)
            {
                for (int y = 0; y < m_Height; ++y)
                {
                    m_Tiles[x][y] = tiles[x][y].ToArray();
                }
            }
        }
Beispiel #3
0
        public void Resize(int newWidth, int newHeight)
        {
            int oldWidth = m_Width, oldHeight = m_Height;

            StaticTile[][][] oldTiles = m_Tiles;

            int totalLength           = 0;

            StaticTile[][][] newTiles = new StaticTile[newWidth][][];

            for (int x = 0; x < newWidth; ++x)
            {
                newTiles[x] = new StaticTile[newHeight][];

                for (int y = 0; y < newHeight; ++y)
                {
                    if (x < oldWidth && y < oldHeight)
                    {
                        newTiles[x][y] = oldTiles[x][y];
                    }
                    else
                    {
                        newTiles[x][y] = new StaticTile[0];
                    }

                    totalLength += newTiles[x][y].Length;
                }
            }

            m_Tiles  = newTiles;
            m_List   = new MultiTileEntry[totalLength];
            m_Width  = newWidth;
            m_Height = newHeight;

            m_Min = Point2D.Zero;
            m_Max = Point2D.Zero;

            int index = 0;

            for (int x = 0; x < newWidth; ++x)
            {
                for (int y = 0; y < newHeight; ++y)
                {
                    StaticTile[] tiles = newTiles[x][y];

                    for (int i = 0; i < tiles.Length; ++i)
                    {
                        StaticTile tile = tiles[i];

                        int vx = x - m_Center.X;
                        int vy = y - m_Center.Y;

                        if (vx < m_Min.X)
                        {
                            m_Min.X = vx;
                        }

                        if (vy < m_Min.Y)
                        {
                            m_Min.Y = vy;
                        }

                        if (vx > m_Max.X)
                        {
                            m_Max.X = vx;
                        }

                        if (vy > m_Max.Y)
                        {
                            m_Max.Y = vy;
                        }

                        m_List[index++] = new MultiTileEntry((ushort)tile.ID, (short)vx, (short)vy, (short)tile.Z, 1);
                    }
                }
            }
        }
Beispiel #4
0
        public void Add(int itemID, int x, int y, int z)
        {
            int vx = x + m_Center.X;
            int vy = y + m_Center.Y;

            if (vx >= 0 && vx < m_Width && vy >= 0 && vy < m_Height)
            {
                StaticTile[] oldTiles = m_Tiles[vx][vy];

                for (int i = oldTiles.Length - 1; i >= 0; --i)
                {
                    ItemData data = TileData.ItemTable[itemID & TileData.MaxItemValue];

                    if (oldTiles[i].Z == z && (oldTiles[i].Height > 0 == data.Height > 0))
                    {
                        bool newIsRoof = (data.Flags & TileFlag.Roof) != 0;
                        bool oldIsRoof = (TileData.ItemTable[oldTiles[i].ID & TileData.MaxItemValue].Flags & TileFlag.Roof) != 0;

                        if (newIsRoof == oldIsRoof)
                        {
                            Remove(oldTiles[i].ID, x, y, z);
                        }
                    }
                }

                oldTiles = m_Tiles[vx][vy];

                StaticTile[] newTiles = new StaticTile[oldTiles.Length + 1];

                for (int i = 0; i < oldTiles.Length; ++i)
                {
                    newTiles[i] = oldTiles[i];
                }

                newTiles[oldTiles.Length] = new StaticTile((ushort)itemID, (sbyte)z);

                m_Tiles[vx][vy] = newTiles;

                MultiTileEntry[] oldList = m_List;
                MultiTileEntry[] newList = new MultiTileEntry[oldList.Length + 1];

                for (int i = 0; i < oldList.Length; ++i)
                {
                    newList[i] = oldList[i];
                }

                newList[oldList.Length] = new MultiTileEntry((ushort)itemID, (short)x, (short)y, (short)z, 1);

                m_List = newList;

                if (x < m_Min.X)
                {
                    m_Min.X = x;
                }

                if (y < m_Min.Y)
                {
                    m_Min.Y = y;
                }

                if (x > m_Max.X)
                {
                    m_Max.X = x;
                }

                if (y > m_Max.Y)
                {
                    m_Max.Y = y;
                }
            }
        }
        private unsafe int PatchStatics(TileMatrix matrix, string dataPath, string indexPath, string lookupPath)
        {
            using (FileStream fsData = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                using (FileStream fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    using (FileStream fsLookup = new FileStream(lookupPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        BinaryReader indexReader  = new BinaryReader(fsIndex);
                        BinaryReader lookupReader = new BinaryReader(fsLookup);

                        int count = (int)(indexReader.BaseStream.Length / 4);

                        TileList[][] lists = new TileList[8][];

                        for (int x = 0; x < 8; ++x)
                        {
                            lists[x] = new TileList[8];

                            for (int y = 0; y < 8; ++y)
                            {
                                lists[x][y] = new TileList();
                            }
                        }

                        for (int i = 0; i < count; ++i)
                        {
                            int blockID = indexReader.ReadInt32();
                            int blockX  = blockID / matrix.BlockHeight;
                            int blockY  = blockID % matrix.BlockHeight;

                            int offset = lookupReader.ReadInt32();
                            int length = lookupReader.ReadInt32();
                            lookupReader.ReadInt32(); // Extra

                            if (offset < 0 || length <= 0)
                            {
                                matrix.SetStaticBlock(blockX, blockY, matrix.EmptyStaticBlock);
                                continue;
                            }

                            fsData.Seek(offset, SeekOrigin.Begin);

                            int tileCount = length / 7;

                            if (m_TileBuffer.Length < tileCount)
                            {
                                m_TileBuffer = new StaticTile[tileCount];
                            }

                            StaticTile[] staTiles = m_TileBuffer;

                            fixed(StaticTile *pTiles = staTiles)
                            {
#if !MONO
                                NativeReader.Read(fsData.SafeFileHandle.DangerousGetHandle(), pTiles, length);
#else
                                NativeReader.Read(fsData.Handle, pTiles, length);
#endif
                                StaticTile *pCur = pTiles, pEnd = pTiles + tileCount;

                                while (pCur < pEnd)
                                {
                                    lists[pCur->m_X & 0x7][pCur->m_Y & 0x7].Add((ushort)pCur->m_ID, pCur->m_Z);
                                    pCur = pCur + 1;
                                }

                                StaticTile[][][] tiles = new StaticTile[8][][];

                                for (int x = 0; x < 8; ++x)
                                {
                                    tiles[x] = new StaticTile[8][];

                                    for (int y = 0; y < 8; ++y)
                                    {
                                        tiles[x][y] = lists[x][y].ToArray();
                                    }
                                }

                                matrix.SetStaticBlock(blockX, blockY, tiles);
                            }
                        }

                        indexReader.Close();
                        lookupReader.Close();

                        return(count);
                    }
                }
            }
        }
        private unsafe StaticTile[][][] ReadStaticBlock(int x, int y)
        {
            try
            {
                m_IndexReader.BaseStream.Seek(((x * m_BlockHeight) + y) * 12, SeekOrigin.Begin);

                int lookup = m_IndexReader.ReadInt32();
                int length = m_IndexReader.ReadInt32();

                if (lookup < 0 || length <= 0)
                {
                    return(m_EmptyStaticBlock);
                }
                else
                {
                    int count = length / 7;

                    m_Statics.Seek(lookup, SeekOrigin.Begin);

                    if (m_TileBuffer.Length < count)
                    {
                        m_TileBuffer = new StaticTile[count];
                    }

                    StaticTile[] staTiles = m_TileBuffer;//new StaticTile[tileCount];

                    fixed(StaticTile *pTiles = staTiles)
                    {
#if !MONO
                        NativeReader.Read(m_Statics.SafeFileHandle.DangerousGetHandle(), pTiles, length);
#else
                        NativeReader.Read(m_Statics.Handle, pTiles, length);
#endif
                        if (m_Lists == null)
                        {
                            m_Lists = new TileList[8][];

                            for (int i = 0; i < 8; ++i)
                            {
                                m_Lists[i] = new TileList[8];

                                for (int j = 0; j < 8; ++j)
                                {
                                    m_Lists[i][j] = new TileList();
                                }
                            }
                        }

                        TileList[][] lists = m_Lists;

                        StaticTile *pCur = pTiles, pEnd = pTiles + count;

                        while (pCur < pEnd)
                        {
                            lists[pCur->m_X & 0x7][pCur->m_Y & 0x7].Add(pCur->m_ID, pCur->m_Z);
                            pCur = pCur + 1;
                        }

                        StaticTile[][][] tiles = new StaticTile[8][][];

                        for (int i = 0; i < 8; ++i)
                        {
                            tiles[i] = new StaticTile[8][];

                            for (int j = 0; j < 8; ++j)
                            {
                                tiles[i][j] = lists[i][j].ToArray();
                            }
                        }

                        return(tiles);
                    }
                }
            }
            catch (EndOfStreamException)
            {
                if (DateTime.UtcNow >= m_NextStaticWarning)
                {
                    Console.WriteLine("Warning: Static EOS for {0} ({1}, {2})", m_Owner, x, y);
                    m_NextStaticWarning = DateTime.UtcNow + TimeSpan.FromMinutes(1.0);
                }

                return(m_EmptyStaticBlock);
            }
        }
        public TileMatrix(Map owner, int fileIndex, int mapID, int width, int height)
        {
            lock (m_Instances)
            {
                for (int i = 0; i < m_Instances.Count; ++i)
                {
                    TileMatrix tm = m_Instances[i];

                    if (tm.m_FileIndex == fileIndex)
                    {
                        lock (m_FileShare)
                        {
                            lock (tm.m_FileShare)
                            {
                                tm.m_FileShare.Add(this);
                                m_FileShare.Add(tm);
                            }
                        }
                    }
                }

                m_Instances.Add(this);
            }

            m_FileIndex   = fileIndex;
            m_Width       = width;
            m_Height      = height;
            m_BlockWidth  = width >> 3;
            m_BlockHeight = height >> 3;

            m_Owner = owner;

            if (fileIndex != 0x7F)
            {
                string mapPath = Core.FindDataFile("map{0}.mul", fileIndex);

                if (File.Exists(mapPath))
                {
                    m_Map = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                }
                else
                {
                    mapPath = Core.FindDataFile("map{0}LegacyMUL.uop", fileIndex);

                    if (File.Exists(mapPath))
                    {
                        m_Map      = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                        m_MapIndex = new UOPIndex(m_Map);
                    }
                }

                string indexPath = Core.FindDataFile("staidx{0}.mul", fileIndex);

                if (File.Exists(indexPath))
                {
                    m_Index       = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    m_IndexReader = new BinaryReader(m_Index);
                }

                string staticsPath = Core.FindDataFile("statics{0}.mul", fileIndex);

                if (File.Exists(staticsPath))
                {
                    m_Statics = new FileStream(staticsPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                }
            }

            m_EmptyStaticBlock = new StaticTile[8][][];

            for (int i = 0; i < 8; ++i)
            {
                m_EmptyStaticBlock[i] = new StaticTile[8][];

                for (int j = 0; j < 8; ++j)
                {
                    m_EmptyStaticBlock[i][j] = new StaticTile[0];
                }
            }

            m_InvalidLandBlock = new LandTile[196];

            m_LandTiles     = new LandTile[m_BlockWidth][][];
            m_StaticTiles   = new StaticTile[m_BlockWidth][][][][];
            m_StaticPatches = new int[m_BlockWidth][];
            m_LandPatches   = new int[m_BlockWidth][];

            m_Patch = new TileMatrixPatch(this, mapID);
        }