GetLandBlock() public method

public GetLandBlock ( int x, int y ) : Ultima.Tile[]
x int
y int
return Ultima.Tile[]
Exemplo n.º 1
0
        private unsafe short[] RenderBlock(int x, int y, bool drawStatics)
        {
            short[] data = new short[64];

            Tile[] tiles = m_Tiles.GetLandBlock(x, y);

            fixed(short *pColors = m_Colors)
            {
                fixed(int *pHeight = TileData.HeightTable)
                {
                    fixed(Tile *ptTiles = tiles)
                    {
                        Tile *pTiles = ptTiles;

                        fixed(short *pData = data)
                        {
                            short *pvData = pData;

                            if (drawStatics)
                            {
                                HuedTile[][][] statics = drawStatics ? m_Tiles.GetStaticBlock(x, y) : null;

                                for (int k = 0, v = 0; k < 8; ++k, v += 8)
                                {
                                    for (int p = 0; p < 8; ++p)
                                    {
                                        int highTop = -255;
                                        int highZ = -255;
                                        int highID = 0;
                                        int highHue = 0;
                                        int z, top;

                                        HuedTile[] curStatics = statics[p][k];

                                        if (curStatics.Length > 0)
                                        {
                                            fixed(HuedTile *phtStatics = curStatics)
                                            {
                                                HuedTile *pStatics    = phtStatics;
                                                HuedTile *pStaticsEnd = pStatics + curStatics.Length;

                                                while (pStatics < pStaticsEnd)
                                                {
                                                    z   = pStatics->m_Z;
                                                    top = z + pHeight[pStatics->m_ID & 0x3FFF];

                                                    if (top > highTop || (z > highZ && top >= highTop))
                                                    {
                                                        highTop = top;
                                                        highZ   = z;
                                                        highID  = pStatics->m_ID;
                                                        highHue = pStatics->m_Hue;
                                                    }

                                                    ++pStatics;
                                                }
                                            }
                                        }

                                        top = pTiles->m_Z;

                                        if (top > highTop)
                                        {
                                            highID  = pTiles->m_ID;
                                            highHue = 0;
                                        }

                                        if (highHue == 0)
                                        {
                                            *pvData++ = pColors[highID];
                                        }
                                        else
                                        {
                                            *pvData++ = Hues.GetHue(highHue - 1).Colors[(pColors[highID] >> 10) & 0x1F];
                                        }

                                        ++pTiles;
                                    }
                                }
                            }
                            else
                            {
                                Tile *pEnd = pTiles + 64;

                                while (pTiles < pEnd)
                                {
                                    *pvData++ = pColors[(pTiles++)->m_ID];
                                }
                            }
                        }
                    }
                }
            }

            return(data);
        }
Exemplo n.º 2
0
        private unsafe short[] RenderBlock(int x, int y, bool drawStatics, bool diff)
        {
            var data = new short[64];

            Tile[] tiles = m_Tiles.GetLandBlock(x, y, diff);

            fixed(short *pColors = RadarCol.Colors)
            {
                fixed(int *pHeight = TileData.HeightTable)
                {
                    fixed(Tile *ptTiles = tiles)
                    {
                        Tile *pTiles = ptTiles;

                        fixed(short *pData = data)
                        {
                            short *pvData = pData;

                            if (drawStatics)
                            {
                                HuedTile[][][] statics = drawStatics ? m_Tiles.GetStaticBlock(x, y, diff) : null;

                                for (int k = 0, v = 0; k < 8; ++k, v += 8)
                                {
                                    for (int p = 0; p < 8; ++p)
                                    {
                                        int  highTop = -255;
                                        int  highZ = -255;
                                        int  highID = 0;
                                        int  highHue = 0;
                                        int  z, top;
                                        bool highstatic = false;

                                        HuedTile[] curStatics = statics[p][k];

                                        if (curStatics.Length > 0)
                                        {
                                            fixed(HuedTile *phtStatics = curStatics)
                                            {
                                                HuedTile *pStatics    = phtStatics;
                                                HuedTile *pStaticsEnd = pStatics + curStatics.Length;

                                                while (pStatics < pStaticsEnd)
                                                {
                                                    z   = pStatics->m_Z;
                                                    top = z + pHeight[pStatics->ID];

                                                    if (top > highTop || (z > highZ && top >= highTop))
                                                    {
                                                        highTop    = top;
                                                        highZ      = z;
                                                        highID     = pStatics->ID;
                                                        highHue    = pStatics->Hue;
                                                        highstatic = true;
                                                    }

                                                    ++pStatics;
                                                }
                                            }
                                        }
                                        StaticTile[] pending = m_Tiles.GetPendingStatics(x, y);
                                        if (pending != null)
                                        {
                                            foreach (StaticTile penS in pending)
                                            {
                                                if (penS.m_X == p)
                                                {
                                                    if (penS.m_Y == k)
                                                    {
                                                        z   = penS.m_Z;
                                                        top = z + pHeight[penS.m_ID];

                                                        if (top > highTop || (z > highZ && top >= highTop))
                                                        {
                                                            highTop    = top;
                                                            highZ      = z;
                                                            highID     = penS.m_ID;
                                                            highHue    = penS.m_Hue;
                                                            highstatic = true;
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        top = pTiles->m_Z;

                                        if (top > highTop)
                                        {
                                            highID     = pTiles->m_ID;
                                            highHue    = 0;
                                            highstatic = false;
                                        }

                                        if (highHue == 0)
                                        {
                                            try
                                            {
                                                if (highstatic)
                                                {
                                                    *pvData++ = pColors[highID + 0x4000];
                                                }
                                                else
                                                {
                                                    *pvData++ = pColors[highID];
                                                }
                                            }
                                            catch
                                            { }
                                        }
                                        else
                                        {
                                            *pvData++ = Hues.GetHue(highHue - 1).Colors[(pColors[highID + 0x4000] >> 10) & 0x1F];
                                        }

                                        ++pTiles;
                                    }
                                }
                            }
                            else
                            {
                                Tile *pEnd = pTiles + 64;

                                while (pTiles < pEnd)
                                {
                                    *pvData++ = pColors[(pTiles++)->m_ID];
                                }
                            }
                        }
                    }
                }
            }

            return(data);
        }
Exemplo n.º 3
0
        private unsafe short[] RenderBlock(int x, int y, bool drawStatics, bool diff)
        {
            var data = new short[64];

            Tile[] tiles = _tiles.GetLandBlock(x, y, diff);

            fixed(short *pColors = RadarCol.Colors)
            {
                fixed(int *pHeight = TileData.HeightTable)
                fixed(Tile * ptTiles = tiles)
                {
                    Tile *pTiles = ptTiles;

                    fixed(short *pData = data)
                    {
                        short *pvData = pData;

                        if (drawStatics)
                        {
                            HuedTile[][][] statics = _tiles.GetStaticBlock(x, y, diff);

                            for (int k = 0; k < 8; ++k)
                            {
                                for (int p = 0; p < 8; ++p)
                                {
                                    int  highTop = -255;
                                    int  highZ = -255;
                                    int  highId = 0;
                                    int  highHue = 0;
                                    int  z, top;
                                    bool highStatic = false;

                                    HuedTile[] curStatics = statics[p][k];

                                    if (curStatics.Length > 0)
                                    {
                                        fixed(HuedTile *phtStatics = curStatics)
                                        {
                                            HuedTile *pStatics    = phtStatics;
                                            HuedTile *pStaticsEnd = pStatics + curStatics.Length;

                                            while (pStatics < pStaticsEnd)
                                            {
                                                z   = pStatics->Z;
                                                top = z + pHeight[pStatics->Id];

                                                if (top > highTop || (z > highZ && top >= highTop))
                                                {
                                                    highTop    = top;
                                                    highZ      = z;
                                                    highId     = pStatics->Id;
                                                    highHue    = pStatics->Hue;
                                                    highStatic = true;
                                                }

                                                ++pStatics;
                                            }
                                        }
                                    }

                                    StaticTile[] pending = _tiles.GetPendingStatics(x, y);
                                    if (pending != null)
                                    {
                                        foreach (StaticTile penS in pending)
                                        {
                                            if (penS.X != p || penS.Y != k)
                                            {
                                                continue;
                                            }

                                            z   = penS.Z;
                                            top = z + pHeight[penS.Id];

                                            if (top <= highTop && (z <= highZ || top < highTop))
                                            {
                                                continue;
                                            }

                                            highTop    = top;
                                            highZ      = z;
                                            highId     = penS.Id;
                                            highHue    = penS.Hue;
                                            highStatic = true;
                                        }
                                    }

                                    top = pTiles->Z;

                                    if (top > highTop)
                                    {
                                        highId     = pTiles->Id;
                                        highHue    = 0;
                                        highStatic = false;
                                    }

                                    if (highHue == 0)
                                    {
                                        try
                                        {
                                            if (highStatic)
                                            {
                                                *pvData++ = pColors[highId + 0x4000];
                                            }
                                            else
                                            {
                                                *pvData++ = pColors[highId];
                                            }
                                        }
                                        catch
                                        {
                                            // TODO: ignored?
                                            // ignored
                                        }
                                    }
                                    else
                                    {
                                        *pvData++ = Hues.GetHue(highHue - 1)
                                                    .Colors[(pColors[highId + 0x4000] >> 10) & 0x1F];
                                    }

                                    ++pTiles;
                                }
                            }
                        }
                        else
                        {
                            Tile *pEnd = pTiles + 64;

                            while (pTiles < pEnd)
                            {
                                *pvData++ = pColors[(pTiles++)->Id];
                            }
                        }
                    }
                }
            }

            return(data);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Generate in memmory new Facet from map & statics mul files		
        /// </summary>
        /// <param name="map">source map for generating facet</param>
        /// <param name="algorithm">type of algorithm which will be used for converting map to facet</param>
        public unsafe Facet(Map map, FacetGenAlgorithm algorithm)
        {
            if (map == null)
                throw new ArgumentNullException();

            m_Width = map.Width;
            m_Height = map.Height;
            m_FileIndex = map.FileIndex;
            m_FileName = Files.GetFilePath(String.Format("facet{0:D2}.mul", FileIndex));

            #region FacetGenAlgorithm.UltimaMap
            if (algorithm == FacetGenAlgorithm.UltimaMap)
            {
                Bitmap bmp = map.GetImage(0, 0, Width, Height, true);
                m_Bitmap = bmp.Clone(new Rectangle(0, 0, Width, Height), PixelFormat.Format16bppRgb555);
                bmp.Dispose();
                return;
            }
            #endregion FacetGenAlgorithm.UltimaMap

            m_Bitmap = new Bitmap(Width, Height, PixelFormat.Format16bppRgb555);
            BitmapData data = m_Bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format16bppRgb555);
            ushort* cur = (ushort*)data.Scan0;
            int stride = data.Stride >> 1;

            switch (algorithm)
            {
                #region FacetGenAlgorithm.Simple
                case FacetGenAlgorithm.Simple:
                    {
                        TileMatrix matrix = new TileMatrix(FileIndex, FileIndex, Width, Height, null);
                        int blocklength = Width >> 3;
                        Tile[][] land = new Tile[blocklength][];
                        HuedTile[][][][] item = new HuedTile[blocklength][][][];
                        HuedTileComparer comparator = new HuedTileComparer();

                        for (int h = 0; h < (Height >> 3); ++h)
                        {
                            for (int b = 0; b < blocklength; ++b)
                            {
                                land[b] = matrix.GetLandBlock(b, h);
                                item[b] = matrix.GetStaticBlock(b, h);
                            }

                            for (int y = 0; y < 8; ++y)
                            {
                                int i = -1;
                                for (int b = 0; b < blocklength; ++b)
                                {
                                    for (int x = 0; x < 8; ++x)
                                    {
                                        Tile landtile = land[b][(y << 3) + x];
                                        HuedTile[] itemtile = item[b][x][y];
                                        if (itemtile == null || itemtile.Length == 0)
                                        {
                                            if (Array.BinarySearch(nodrawland, landtile.ID) < 0)
                                                cur[++i] = (ushort)RadarCol.Colors[landtile.ID];
                                            else
                                                cur[++i] = 0x0000;
                                            continue;
                                        }

                                        Array.Sort(itemtile, comparator);

                                        cur[++i] = itemtile[0].Z < landtile.Z
                                                 ? (ushort)RadarCol.Colors[landtile.ID]
                                                 : (ushort)RadarCol.Colors[0x4000 + itemtile[0].ID];

                                        if (cur[i] == 0x0421 || cur[i] == 0x0000)
                                            if (Array.BinarySearch(nodrawland, landtile.ID) < 0)
                                                cur[++i] = (ushort)RadarCol.Colors[landtile.ID];
                                            else
                                                cur[++i] = 0x0000;
                                    }
                                }
                                cur += stride;
                            }
                        }
                        break;
                    }
                #endregion FacetGenAlgorithm.Simple

                #region FacetGenAlgorithm.AltMask
                case FacetGenAlgorithm.AltMask:
                    {
                        TileMatrix matrix = new TileMatrix(FileIndex, FileIndex, Width, Height, null);
                        int blocklength = Width >> 3;
                        Tile[][] land = new Tile[blocklength][];
                        HuedTile[][][][] item = new HuedTile[blocklength][][][];
                        HuedTileComparer comparator = new HuedTileComparer();

                        for (int h = 0; h < (Height >> 3); ++h)
                        {
                            for (int b = 0; b < blocklength; ++b)
                            {
                                land[b] = matrix.GetLandBlock(b, h);
                                item[b] = matrix.GetStaticBlock(b, h);
                            }

                            matrix.Dispose();

                            for (int y = 0; y < 8; ++y)
                            {
                                int i = -1;
                                for (int b = 0; b < blocklength; ++b)
                                {
                                    for (int x = 0; x < 8; ++x)
                                    {
                                        Tile landtile = land[b][(y << 3) + x];
                                        HuedTile[] itemtile = item[b][x][y];
                                        bool drawland = false;

                                        if (itemtile == null || itemtile.Length == 0)
                                        {
                                            if (Array.BinarySearch(nodrawland, landtile.ID) >= 0)
                                                cur[++i] = 0x0000;
                                            else
                                            {
                                                cur[++i] = (ushort)RadarCol.Colors[landtile.ID];
                                                drawland = true;
                                            }
                                        }
                                        else
                                        {
                                            Array.Sort(itemtile, comparator);

                                            ushort landcolor = (ushort)RadarCol.Colors[landtile.ID];
                                            ushort itemcolor = 0x0000;
                                            int iu = 0;
                                            for (int u = 0; u < itemtile.Length; ++u)
                                            {
                                                iu = u;
                                                if (Array.BinarySearch(nodrawitem, itemtile[u].ID) >= 0)
                                                    continue;
                                                itemcolor = (ushort)RadarCol.Colors[0x4000 + itemtile[u].ID];
                                                if (itemcolor == 0x0000 || itemcolor == 0x0421)
                                                    if ((u + 1 < itemtile.Length) && (itemtile[u].Z >= landtile.Z))
                                                        continue;
                                                    else
                                                    {
                                                        itemcolor = 0x0000;
                                                        break;
                                                    }
                                                break;
                                            }

                                            if (itemcolor == 0x0000 || itemtile[iu].Z < landtile.Z)
                                            {
                                                if (Array.BinarySearch(nodrawland, landtile.ID) >= 0)
                                                    cur[++i] = 0x0000;
                                                else
                                                {
                                                    cur[++i] = landcolor;
                                                    drawland = true;
                                                }
                                            }
                                            else
                                                cur[++i] = itemcolor;
                                        }

                                        if (drawland && ((TileData.LandTable[landtile.ID].Flags & TileFlag.Wet) == 0))
                                        {
                                            short inc = (short)(0 - (landtile.Z / 20));

                                            short maskR = (short)(((cur[i] & 0x7C00) >> 10) + inc);
                                            maskR = Math.Min(Math.Max((short)0x00, maskR), (short)0x1F);
                                            short maskG = (short)(((cur[i] & 0x03E0) >> 5) + inc);
                                            maskG = Math.Min(Math.Max((short)0x00, maskG), (short)0x1F);
                                            short maskB = (short)(((cur[i] & 0x001F) >> 0) + inc);
                                            maskB = Math.Min(Math.Max((short)0x00, maskB), (short)0x1F);

                                            cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                        }
                                        else
                                        {
                                            ushort maskR = (ushort)((cur[i] & 0x7C00) >> 10);
                                            if (maskR > 0)
                                                --maskR;
                                            ushort maskG = (ushort)((cur[i] & 0x03E0) >> 5);
                                            if (maskG > 0)
                                                --maskG;
                                            ushort maskB = (ushort)((cur[i] & 0x001F) >> 0);
                                            if (maskB > 0)
                                                --maskB;
                                            cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                        }
                                    }
                                }
                                cur += stride;
                            }
                        }
                        break;
                    }
                #endregion FacetGenAlgorithm.AltMask

                #region FacetGenAlgorithm.AltMaskNoise
                case FacetGenAlgorithm.AltMaskNoise:
                    {
                        Random random = new Random();
                        TileMatrix matrix = new TileMatrix(FileIndex, FileIndex, Width, Height, null);
                        int blocklength = Width >> 3;
                        Tile[][] land = new Tile[blocklength][];
                        HuedTile[][][][] item = new HuedTile[blocklength][][][];
                        HuedTileComparer comparator = new HuedTileComparer();

                        for (int h = 0; h < (Height >> 3); ++h)
                        {
                            for (int b = 0; b < blocklength; ++b)
                            {
                                land[b] = matrix.ReadLandBlock(b, h);
                                item[b] = matrix.ReadStaticBlock(b, h);
                            }

                            for (int y = 0; y < 8; ++y)
                            {
                                int i = -1;
                                for (int b = 0; b < blocklength; ++b)
                                {
                                    for (int x = 0; x < 8; ++x)
                                    {
                                        Tile landtile = land[b][(y << 3) + x];
                                        HuedTile[] itemtile = item[b][x][y];
                                        bool drawland = false;

                                        if (itemtile == null || itemtile.Length == 0)
                                        {
                                            if (Array.BinarySearch(nodrawland, landtile.ID) >= 0)
                                                cur[++i] = 0x0000;
                                            else
                                            {
                                                cur[++i] = (ushort)RadarCol.Colors[landtile.ID];
                                                drawland = true;
                                            }
                                        }
                                        else
                                        {
                                            Array.Sort(itemtile, comparator);

                                            ushort landcolor = (ushort)RadarCol.Colors[landtile.ID];
                                            ushort itemcolor = 0x0000;
                                            int iu = 0;
                                            for (int u = 0; u < itemtile.Length; ++u)
                                            {
                                                iu = u;
                                                if (Array.BinarySearch(nodrawitem, itemtile[u].ID) >= 0)
                                                    continue;
                                                itemcolor = (ushort)RadarCol.Colors[0x4000 + itemtile[u].ID];
                                                if (itemcolor == 0x0000 || itemcolor == 0x0421 )
                                                    if ((u + 1 < itemtile.Length) && (itemtile[u].Z >= landtile.Z))
                                                        continue;
                                                    else
                                                    {
                                                        itemcolor = 0x0000;
                                                        break;
                                                    }
                                                break;
                                            }

                                            if (itemcolor == 0x0000 || itemtile[iu].Z < landtile.Z)
                                            {
                                                if (Array.BinarySearch(nodrawland, landtile.ID) >= 0)
                                                    cur[++i] = 0x0000;
                                                else
                                                {
                                                    cur[++i] = landcolor;
                                                    drawland = true;
                                                }
                                            }
                                            else
                                                cur[++i] = itemcolor;
                                        }

                                        if (drawland && ((TileData.LandTable[landtile.ID].Flags & TileFlag.Wet) == 0))
                                        {
                                            short inc = (short)(0 - (landtile.Z / 25));

                                            short maskR = (short)(((cur[i] & 0x7C00) >> 10) + inc);
                                            short maskG = (short)(((cur[i] & 0x03E0) >> 5) + inc);
                                            short maskB = (short)(((cur[i] & 0x001F) >> 0) + inc);

                                            inc = (short)(random.Next(-1, 2));
                                            maskR += inc;
                                            inc = (short)(random.Next(-1, 2));
                                            maskG += inc;
                                            inc = (short)(random.Next(-1, 2));
                                            maskB += inc;

                                            maskR = Math.Min(Math.Max((short)0x00, maskR), (short)0x1F);
                                            maskG = Math.Min(Math.Max((short)0x00, maskG), (short)0x1F);
                                            maskB = Math.Min(Math.Max((short)0x00, maskB), (short)0x1F);

                                            cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                        }
                                        else
                                        {
                                            ushort maskR = (ushort)((cur[i] & 0x7C00) >> 10);
                                            if (maskR > 0)
                                                --maskR;
                                            ushort maskG = (ushort)((cur[i] & 0x03E0) >> 5);
                                            if (maskG > 0)
                                                --maskG;
                                            ushort maskB = (ushort)((cur[i] & 0x001F) >> 0);
                                            if (maskB > 0)
                                                --maskB;
                                            cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                        }
                                    }
                                }
                                cur += stride;
                            }

                        }
                        break;
                    }
                #endregion FacetGenAlgorithm.AltMaskNoise

                #region FacetGenAlgorithm.Improved
                case FacetGenAlgorithm.Improved:
                    {
                        Random random = new Random();
                        TileMatrix matrix = new TileMatrix(FileIndex, FileIndex, Width, Height, null);
                        int blocklength = Width >> 3;
                        Tile[][] land = new Tile[blocklength][];
                        HuedTile[][][][] item = new HuedTile[blocklength][][][];
                        HuedTileComparer comparator = new HuedTileComparer();

                        for (int h = 0; h < (Height >> 3); ++h)
                        {
                            for (int b = 0; b < blocklength; ++b)
                            {
                                land[b] = matrix.GetLandBlock(b, h);
                                item[b] = matrix.GetStaticBlock(b, h);
                            }

                            for (int y = 0; y < 8; ++y)
                            {
                                int i = -1;
                                for (int b = 0; b < blocklength; ++b)
                                {
                                    for (int x = 0; x < 8; ++x)
                                    {
                                        Tile landtile = land[b][(y << 3) + x];
                                        HuedTile[] itemtile = item[b][x][y];
                                        bool drawland = false;

                                        if (itemtile == null || itemtile.Length == 0)
                                        {
                                            cur[++i] = (ushort)RadarCol.Colors[landtile.ID];
                                            drawland = true;
                                        }
                                        else
                                        {
                                            Array.Sort(itemtile, comparator);

                                            ushort landcolor = (ushort)RadarCol.Colors[landtile.ID];
                                            ushort itemcolor = 0x0000;
                                            int iu = 0;
                                            for (int u = 0; u < itemtile.Length; ++u)
                                            {
                                                iu = u;
                                                itemcolor = (ushort)RadarCol.Colors[0x4000 + itemtile[u].ID];
                                                if (itemcolor == 0x0000 || itemcolor == 0x0421)
                                                    if ((u + 1 < itemtile.Length) && (itemtile[u].Z >= landtile.Z))
                                                        continue;
                                                    else
                                                    {
                                                        itemcolor = 0x0000;
                                                        break;
                                                    }
                                                break;
                                            }

                                            if (itemcolor == 0x0000 || itemtile[iu].Z < landtile.Z)
                                            {
                                                cur[++i] = landcolor;
                                                drawland = true;
                                            }
                                            else
                                                cur[++i] = itemcolor;
                                        }

                                        if (drawland)
                                        {
                                            short inc = (short)(0 - (landtile.Z / 20));
                                            //
                                            inc *= 3;
                                            if (inc == 0)
                                                switch (random.Next(0, 2))
                                                {
                                                    case 0: inc = -1; break;
                                                    case 1: inc = 1; break;
                                                }
                                            short dir = (short)((inc >= 0) ? 1 : -1);

                                            short maskR = (short)((cur[i] & 0x7C00) >> 10);
                                            short maskG = (short)((cur[i] & 0x03E0) >> 5);
                                            short maskB = (short)((cur[i] & 0x001F) >> 0);

                                            for (short rand = 0; rand < dir * inc; ++rand)
                                                switch (random.Next(0, 3))
                                                {
                                                    case 0: maskR += dir; break;
                                                    case 1: maskG += dir; break;
                                                    case 2: maskB += dir; break;
                                                }

                                            maskR = Math.Min(Math.Max((short)0x00, maskR), (short)0x1F);
                                            maskG = Math.Min(Math.Max((short)0x00, maskG), (short)0x1F);
                                            maskB = Math.Min(Math.Max((short)0x00, maskB), (short)0x1F);
                                            /*
                                            short maskR = (short)(((cur[i] & 0x7C00) >> 10) + inc);
                                            maskR = Math.Min(Math.Max((short)0x00, maskR), (short)0x1F);
                                            short maskG = (short)(((cur[i] & 0x03E0) >> 5) + inc);
                                            maskG = Math.Min(Math.Max((short)0x00, maskG), (short)0x1F);
                                            short maskB = (short)(((cur[i] & 0x001F) >> 0) + inc);
                                            maskB = Math.Min(Math.Max((short)0x00, maskB), (short)0x1F);
                                            */
                                            cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                        }
                                        else
                                        {
                                            ushort maskR = (ushort)((cur[i] & 0x7C00) >> 10);
                                            if (maskR > 0)
                                                --maskR;
                                            ushort maskG = (ushort)((cur[i] & 0x03E0) >> 5);
                                            if (maskG > 0)
                                                --maskG;
                                            ushort maskB = (ushort)((cur[i] & 0x001F) >> 0);
                                            if (maskB > 0)
                                                --maskB;
                                            cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                        }
                                    }
                                }
                                cur += stride;
                            }
                        }
                        break;
                    }
                #endregion FacetGenAlgorithm.Improved
            }

            m_Bitmap.UnlockBits(data);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Generate in memmory new Facet from map & statics mul files
        /// </summary>
        /// <param name="map">source map for generating facet</param>
        /// <param name="algorithm">type of algorithm which will be used for converting map to facet</param>
        public unsafe Facet(Map map, FacetGenAlgorithm algorithm)
        {
            if (map == null)
            {
                throw new ArgumentNullException();
            }

            m_Width     = map.Width;
            m_Height    = map.Height;
            m_FileIndex = map.FileIndex;
            m_FileName  = Files.GetFilePath(String.Format("facet{0:D2}.mul", FileIndex));

            #region FacetGenAlgorithm.UltimaMap
            if (algorithm == FacetGenAlgorithm.UltimaMap)
            {
                Bitmap bmp = map.GetImage(0, 0, Width, Height, true);
                m_Bitmap = bmp.Clone(new Rectangle(0, 0, Width, Height), PixelFormat.Format16bppRgb555);
                bmp.Dispose();
                return;
            }
            #endregion FacetGenAlgorithm.UltimaMap

            m_Bitmap = new Bitmap(Width, Height, PixelFormat.Format16bppRgb555);
            BitmapData data   = m_Bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format16bppRgb555);
            ushort *   cur    = (ushort *)data.Scan0;
            int        stride = data.Stride >> 1;

            switch (algorithm)
            {
                #region FacetGenAlgorithm.Simple
            case FacetGenAlgorithm.Simple:
            {
                TileMatrix       matrix      = new TileMatrix(FileIndex, FileIndex, Width, Height, null);
                int              blocklength = Width >> 3;
                Tile[][]         land        = new Tile[blocklength][];
                HuedTile[][][][] item        = new HuedTile[blocklength][][][];
                HuedTileComparer comparator  = new HuedTileComparer();

                for (int h = 0; h < (Height >> 3); ++h)
                {
                    for (int b = 0; b < blocklength; ++b)
                    {
                        land[b] = matrix.GetLandBlock(b, h);
                        item[b] = matrix.GetStaticBlock(b, h);
                    }

                    for (int y = 0; y < 8; ++y)
                    {
                        int i = -1;
                        for (int b = 0; b < blocklength; ++b)
                        {
                            for (int x = 0; x < 8; ++x)
                            {
                                Tile       landtile = land[b][(y << 3) + x];
                                HuedTile[] itemtile = item[b][x][y];
                                if (itemtile == null || itemtile.Length == 0)
                                {
                                    if (Array.BinarySearch(nodrawland, landtile.ID) < 0)
                                    {
                                        cur[++i] = (ushort)RadarCol.Colors[landtile.ID];
                                    }
                                    else
                                    {
                                        cur[++i] = 0x0000;
                                    }
                                    continue;
                                }

                                Array.Sort(itemtile, comparator);

                                cur[++i] = itemtile[0].Z < landtile.Z
                                                 ? (ushort)RadarCol.Colors[landtile.ID]
                                                 : (ushort)RadarCol.Colors[0x4000 + itemtile[0].ID];

                                if (cur[i] == 0x0421 || cur[i] == 0x0000)
                                {
                                    if (Array.BinarySearch(nodrawland, landtile.ID) < 0)
                                    {
                                        cur[++i] = (ushort)RadarCol.Colors[landtile.ID];
                                    }
                                    else
                                    {
                                        cur[++i] = 0x0000;
                                    }
                                }
                            }
                        }
                        cur += stride;
                    }
                }
                break;
            }
                #endregion FacetGenAlgorithm.Simple

                #region FacetGenAlgorithm.AltMask
            case FacetGenAlgorithm.AltMask:
            {
                TileMatrix       matrix      = new TileMatrix(FileIndex, FileIndex, Width, Height, null);
                int              blocklength = Width >> 3;
                Tile[][]         land        = new Tile[blocklength][];
                HuedTile[][][][] item        = new HuedTile[blocklength][][][];
                HuedTileComparer comparator  = new HuedTileComparer();

                for (int h = 0; h < (Height >> 3); ++h)
                {
                    for (int b = 0; b < blocklength; ++b)
                    {
                        land[b] = matrix.GetLandBlock(b, h);
                        item[b] = matrix.GetStaticBlock(b, h);
                    }

                    matrix.Dispose();

                    for (int y = 0; y < 8; ++y)
                    {
                        int i = -1;
                        for (int b = 0; b < blocklength; ++b)
                        {
                            for (int x = 0; x < 8; ++x)
                            {
                                Tile       landtile = land[b][(y << 3) + x];
                                HuedTile[] itemtile = item[b][x][y];
                                bool       drawland = false;

                                if (itemtile == null || itemtile.Length == 0)
                                {
                                    if (Array.BinarySearch(nodrawland, landtile.ID) >= 0)
                                    {
                                        cur[++i] = 0x0000;
                                    }
                                    else
                                    {
                                        cur[++i] = (ushort)RadarCol.Colors[landtile.ID];
                                        drawland = true;
                                    }
                                }
                                else
                                {
                                    Array.Sort(itemtile, comparator);

                                    ushort landcolor = (ushort)RadarCol.Colors[landtile.ID];
                                    ushort itemcolor = 0x0000;
                                    int    iu        = 0;
                                    for (int u = 0; u < itemtile.Length; ++u)
                                    {
                                        iu = u;
                                        if (Array.BinarySearch(nodrawitem, itemtile[u].ID) >= 0)
                                        {
                                            continue;
                                        }
                                        itemcolor = (ushort)RadarCol.Colors[0x4000 + itemtile[u].ID];
                                        if (itemcolor == 0x0000 || itemcolor == 0x0421)
                                        {
                                            if ((u + 1 < itemtile.Length) && (itemtile[u].Z >= landtile.Z))
                                            {
                                                continue;
                                            }
                                            else
                                            {
                                                itemcolor = 0x0000;
                                                break;
                                            }
                                        }
                                        break;
                                    }

                                    if (itemcolor == 0x0000 || itemtile[iu].Z < landtile.Z)
                                    {
                                        if (Array.BinarySearch(nodrawland, landtile.ID) >= 0)
                                        {
                                            cur[++i] = 0x0000;
                                        }
                                        else
                                        {
                                            cur[++i] = landcolor;
                                            drawland = true;
                                        }
                                    }
                                    else
                                    {
                                        cur[++i] = itemcolor;
                                    }
                                }

                                if (drawland && ((TileData.LandTable[landtile.ID].Flags & TileFlag.Wet) == 0))
                                {
                                    short inc = (short)(0 - (landtile.Z / 20));

                                    short maskR = (short)(((cur[i] & 0x7C00) >> 10) + inc);
                                    maskR = Math.Min(Math.Max((short)0x00, maskR), (short)0x1F);
                                    short maskG = (short)(((cur[i] & 0x03E0) >> 5) + inc);
                                    maskG = Math.Min(Math.Max((short)0x00, maskG), (short)0x1F);
                                    short maskB = (short)(((cur[i] & 0x001F) >> 0) + inc);
                                    maskB = Math.Min(Math.Max((short)0x00, maskB), (short)0x1F);

                                    cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                }
                                else
                                {
                                    ushort maskR = (ushort)((cur[i] & 0x7C00) >> 10);
                                    if (maskR > 0)
                                    {
                                        --maskR;
                                    }
                                    ushort maskG = (ushort)((cur[i] & 0x03E0) >> 5);
                                    if (maskG > 0)
                                    {
                                        --maskG;
                                    }
                                    ushort maskB = (ushort)((cur[i] & 0x001F) >> 0);
                                    if (maskB > 0)
                                    {
                                        --maskB;
                                    }
                                    cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                }
                            }
                        }
                        cur += stride;
                    }
                }
                break;
            }
                #endregion FacetGenAlgorithm.AltMask

                #region FacetGenAlgorithm.AltMaskNoise
            case FacetGenAlgorithm.AltMaskNoise:
            {
                Random           random      = new Random();
                TileMatrix       matrix      = new TileMatrix(FileIndex, FileIndex, Width, Height, null);
                int              blocklength = Width >> 3;
                Tile[][]         land        = new Tile[blocklength][];
                HuedTile[][][][] item        = new HuedTile[blocklength][][][];
                HuedTileComparer comparator  = new HuedTileComparer();

                for (int h = 0; h < (Height >> 3); ++h)
                {
                    for (int b = 0; b < blocklength; ++b)
                    {
                        land[b] = matrix.ReadLandBlock(b, h);
                        item[b] = matrix.ReadStaticBlock(b, h);
                    }

                    for (int y = 0; y < 8; ++y)
                    {
                        int i = -1;
                        for (int b = 0; b < blocklength; ++b)
                        {
                            for (int x = 0; x < 8; ++x)
                            {
                                Tile       landtile = land[b][(y << 3) + x];
                                HuedTile[] itemtile = item[b][x][y];
                                bool       drawland = false;

                                if (itemtile == null || itemtile.Length == 0)
                                {
                                    if (Array.BinarySearch(nodrawland, landtile.ID) >= 0)
                                    {
                                        cur[++i] = 0x0000;
                                    }
                                    else
                                    {
                                        cur[++i] = (ushort)RadarCol.Colors[landtile.ID];
                                        drawland = true;
                                    }
                                }
                                else
                                {
                                    Array.Sort(itemtile, comparator);

                                    ushort landcolor = (ushort)RadarCol.Colors[landtile.ID];
                                    ushort itemcolor = 0x0000;
                                    int    iu        = 0;
                                    for (int u = 0; u < itemtile.Length; ++u)
                                    {
                                        iu = u;
                                        if (Array.BinarySearch(nodrawitem, itemtile[u].ID) >= 0)
                                        {
                                            continue;
                                        }
                                        itemcolor = (ushort)RadarCol.Colors[0x4000 + itemtile[u].ID];
                                        if (itemcolor == 0x0000 || itemcolor == 0x0421)
                                        {
                                            if ((u + 1 < itemtile.Length) && (itemtile[u].Z >= landtile.Z))
                                            {
                                                continue;
                                            }
                                            else
                                            {
                                                itemcolor = 0x0000;
                                                break;
                                            }
                                        }
                                        break;
                                    }

                                    if (itemcolor == 0x0000 || itemtile[iu].Z < landtile.Z)
                                    {
                                        if (Array.BinarySearch(nodrawland, landtile.ID) >= 0)
                                        {
                                            cur[++i] = 0x0000;
                                        }
                                        else
                                        {
                                            cur[++i] = landcolor;
                                            drawland = true;
                                        }
                                    }
                                    else
                                    {
                                        cur[++i] = itemcolor;
                                    }
                                }

                                if (drawland && ((TileData.LandTable[landtile.ID].Flags & TileFlag.Wet) == 0))
                                {
                                    short inc = (short)(0 - (landtile.Z / 25));

                                    short maskR = (short)(((cur[i] & 0x7C00) >> 10) + inc);
                                    short maskG = (short)(((cur[i] & 0x03E0) >> 5) + inc);
                                    short maskB = (short)(((cur[i] & 0x001F) >> 0) + inc);

                                    inc    = (short)(random.Next(-1, 2));
                                    maskR += inc;
                                    inc    = (short)(random.Next(-1, 2));
                                    maskG += inc;
                                    inc    = (short)(random.Next(-1, 2));
                                    maskB += inc;

                                    maskR = Math.Min(Math.Max((short)0x00, maskR), (short)0x1F);
                                    maskG = Math.Min(Math.Max((short)0x00, maskG), (short)0x1F);
                                    maskB = Math.Min(Math.Max((short)0x00, maskB), (short)0x1F);

                                    cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                }
                                else
                                {
                                    ushort maskR = (ushort)((cur[i] & 0x7C00) >> 10);
                                    if (maskR > 0)
                                    {
                                        --maskR;
                                    }
                                    ushort maskG = (ushort)((cur[i] & 0x03E0) >> 5);
                                    if (maskG > 0)
                                    {
                                        --maskG;
                                    }
                                    ushort maskB = (ushort)((cur[i] & 0x001F) >> 0);
                                    if (maskB > 0)
                                    {
                                        --maskB;
                                    }
                                    cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                }
                            }
                        }
                        cur += stride;
                    }
                }
                break;
            }
                #endregion FacetGenAlgorithm.AltMaskNoise

                #region FacetGenAlgorithm.Improved
            case FacetGenAlgorithm.Improved:
            {
                Random           random      = new Random();
                TileMatrix       matrix      = new TileMatrix(FileIndex, FileIndex, Width, Height, null);
                int              blocklength = Width >> 3;
                Tile[][]         land        = new Tile[blocklength][];
                HuedTile[][][][] item        = new HuedTile[blocklength][][][];
                HuedTileComparer comparator  = new HuedTileComparer();

                for (int h = 0; h < (Height >> 3); ++h)
                {
                    for (int b = 0; b < blocklength; ++b)
                    {
                        land[b] = matrix.GetLandBlock(b, h);
                        item[b] = matrix.GetStaticBlock(b, h);
                    }

                    for (int y = 0; y < 8; ++y)
                    {
                        int i = -1;
                        for (int b = 0; b < blocklength; ++b)
                        {
                            for (int x = 0; x < 8; ++x)
                            {
                                Tile       landtile = land[b][(y << 3) + x];
                                HuedTile[] itemtile = item[b][x][y];
                                bool       drawland = false;

                                if (itemtile == null || itemtile.Length == 0)
                                {
                                    cur[++i] = (ushort)RadarCol.Colors[landtile.ID];
                                    drawland = true;
                                }
                                else
                                {
                                    Array.Sort(itemtile, comparator);

                                    ushort landcolor = (ushort)RadarCol.Colors[landtile.ID];
                                    ushort itemcolor = 0x0000;
                                    int    iu        = 0;
                                    for (int u = 0; u < itemtile.Length; ++u)
                                    {
                                        iu        = u;
                                        itemcolor = (ushort)RadarCol.Colors[0x4000 + itemtile[u].ID];
                                        if (itemcolor == 0x0000 || itemcolor == 0x0421)
                                        {
                                            if ((u + 1 < itemtile.Length) && (itemtile[u].Z >= landtile.Z))
                                            {
                                                continue;
                                            }
                                            else
                                            {
                                                itemcolor = 0x0000;
                                                break;
                                            }
                                        }
                                        break;
                                    }

                                    if (itemcolor == 0x0000 || itemtile[iu].Z < landtile.Z)
                                    {
                                        cur[++i] = landcolor;
                                        drawland = true;
                                    }
                                    else
                                    {
                                        cur[++i] = itemcolor;
                                    }
                                }

                                if (drawland)
                                {
                                    short inc = (short)(0 - (landtile.Z / 20));
                                    //
                                    inc *= 3;
                                    if (inc == 0)
                                    {
                                        switch (random.Next(0, 2))
                                        {
                                        case 0: inc = -1; break;

                                        case 1: inc = 1; break;
                                        }
                                    }
                                    short dir = (short)((inc >= 0) ? 1 : -1);

                                    short maskR = (short)((cur[i] & 0x7C00) >> 10);
                                    short maskG = (short)((cur[i] & 0x03E0) >> 5);
                                    short maskB = (short)((cur[i] & 0x001F) >> 0);

                                    for (short rand = 0; rand < dir * inc; ++rand)
                                    {
                                        switch (random.Next(0, 3))
                                        {
                                        case 0: maskR += dir; break;

                                        case 1: maskG += dir; break;

                                        case 2: maskB += dir; break;
                                        }
                                    }

                                    maskR = Math.Min(Math.Max((short)0x00, maskR), (short)0x1F);
                                    maskG = Math.Min(Math.Max((short)0x00, maskG), (short)0x1F);
                                    maskB = Math.Min(Math.Max((short)0x00, maskB), (short)0x1F);

                                    /*
                                     * short maskR = (short)(((cur[i] & 0x7C00) >> 10) + inc);
                                     * maskR = Math.Min(Math.Max((short)0x00, maskR), (short)0x1F);
                                     * short maskG = (short)(((cur[i] & 0x03E0) >> 5) + inc);
                                     * maskG = Math.Min(Math.Max((short)0x00, maskG), (short)0x1F);
                                     * short maskB = (short)(((cur[i] & 0x001F) >> 0) + inc);
                                     * maskB = Math.Min(Math.Max((short)0x00, maskB), (short)0x1F);
                                     */
                                    cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                }
                                else
                                {
                                    ushort maskR = (ushort)((cur[i] & 0x7C00) >> 10);
                                    if (maskR > 0)
                                    {
                                        --maskR;
                                    }
                                    ushort maskG = (ushort)((cur[i] & 0x03E0) >> 5);
                                    if (maskG > 0)
                                    {
                                        --maskG;
                                    }
                                    ushort maskB = (ushort)((cur[i] & 0x001F) >> 0);
                                    if (maskB > 0)
                                    {
                                        --maskB;
                                    }
                                    cur[i] = (ushort)((maskR << 10) | (maskG << 5) | (maskB << 0));
                                }
                            }
                        }
                        cur += stride;
                    }
                }
                break;
            }
                #endregion FacetGenAlgorithm.Improved
            }

            m_Bitmap.UnlockBits(data);
        }