示例#1
0
        public void Convert()
        {
            string directory = Path.GetFullPath(@"data\levels\ehz");

            Landscape landscape = new Landscape();
            int       chunkId   = 0;

            foreach (LayoutBlock chunk in mLayoutBlocks)
            {
                Landscape.Chunk lchunk = new Landscape.Chunk();
                for (int layer = 0; layer < 2; layer++)
                {
                    Landscape.Chunk.Layer lclayer = new Landscape.Chunk.Layer();

                    // Angles
                    for (int y = 0; y < 8; y++)
                    {
                        for (int x = 0; x < 8; x++)
                        {
                            LayoutBlock.LayoutBlockTile chunkBlock = chunk.Tiles[x, y];
                            if (chunkBlock.Index >= mTileBlocks.Count)
                            {
                                lclayer.Angles[x, y] = 0;
                                continue;
                            }

                            TileBlock block = mTileBlocks[chunkBlock.Index];
                            int       ci    = (layer == 0 ? block.SecondaryCollision : block.PrimaryCollision);
                            sbyte     angle = mCurveMapping[ci];
                            if (chunkBlock.X)
                            {
                                angle = (sbyte)-angle;
                            }
                            if (chunkBlock.Y)
                            {
                                angle = (sbyte)(-(angle + 64) - 64);
                            }

                            lclayer.Angles[x, y] = angle;
                        }
                    }

                    // LRB
                    for (int y = 0; y < 128; y++)
                    {
                        for (int x = 0; x < 128; x++)
                        {
                            int blockX = x / 16;
                            int blockY = y / 16;
                            int tileX  = (x % 16) / 2;
                            int tileY  = (y % 16) / 2;

                            LayoutBlock.LayoutBlockTile chunkBlock = chunk.Tiles[blockX, blockY];

                            if (layer == 0)
                            {
                                if ((chunkBlock.SS & 2) == 0)
                                {
                                    lclayer.CollisionLRB[x, y] = false;
                                    continue;
                                }
                            }
                            else
                            {
                                if ((chunkBlock.TT & 2) == 0)
                                {
                                    lclayer.CollisionLRB[x, y] = false;
                                    continue;
                                }
                            }

                            if (chunkBlock.Index >= mTileBlocks.Count)
                            {
                                lclayer.CollisionLRB[x, y] = false;
                                continue;
                            }

                            int px = x % 16;
                            int py = y % 16;
                            if (chunkBlock.X)
                            {
                                px = 15 - px;
                            }
                            if (chunkBlock.Y)
                            {
                                py = 15 - py;
                            }

                            TileBlock block     = mTileBlocks[chunkBlock.Index];
                            int       ci        = (layer == 0 ? block.SecondaryCollision : block.PrimaryCollision);
                            sbyte     collision = mCollisionArray1[ci * 16 + px];
                            bool      solid;
                            if (collision == 0)
                            {
                                solid = false;
                            }
                            else if (collision > 0)
                            {
                                solid = collision >= (16 - py);
                            }
                            else
                            {
                                throw new Exception();
                            }

                            lclayer.CollisionLRB[x, y] = solid;
                        }
                    }

                    // TOP
                    for (int y = 0; y < 128; y++)
                    {
                        for (int x = 0; x < 128; x++)
                        {
                            int blockX = x / 16;
                            int blockY = y / 16;
                            int tileX  = (x % 16) / 2;
                            int tileY  = (y % 16) / 2;

                            LayoutBlock.LayoutBlockTile chunkBlock = chunk.Tiles[blockX, blockY];

                            if (layer == 0)
                            {
                                if ((chunkBlock.SS & 1) == 0)
                                {
                                    lclayer.CollisionT[x, y] = false;
                                    continue;
                                }
                            }
                            else
                            {
                                if ((chunkBlock.TT & 1) == 0)
                                {
                                    lclayer.CollisionT[x, y] = false;
                                    continue;
                                }
                            }

                            if (chunkBlock.Index >= mTileBlocks.Count)
                            {
                                lclayer.CollisionT[x, y] = false;
                                continue;
                            }

                            int px = x % 16;
                            int py = y % 16;
                            if (chunkBlock.X)
                            {
                                px = 15 - px;
                            }
                            if (chunkBlock.Y)
                            {
                                py = 15 - py;
                            }

                            TileBlock block     = mTileBlocks[chunkBlock.Index];
                            int       ci        = (layer == 0 ? block.SecondaryCollision : block.PrimaryCollision);
                            sbyte     collision = mCollisionArray1[ci * 16 + px];
                            bool      solid;
                            if (collision == 0)
                            {
                                solid = false;
                            }
                            else if (collision > 0)
                            {
                                solid = collision >= (16 - py);
                            }
                            else
                            {
                                throw new Exception();
                            }

                            lclayer.CollisionT[x, y] = solid;
                        }
                    }

                    // Art
                    Landscape.Chunk.Layer.Image lcli = new Landscape.Chunk.Layer.Image();
                    lcli.AnimationDuration = 0;
                    lcli.AnimationFrames   = 1;
                    Color[] bits128 = GetFGChunkArt(chunkId, (layer == 0), (layer == 1));
                    Color[] bits512 = new Color[512 * 512];
                    for (int y = 0; y < 512; y++)
                    {
                        for (int x = 0; x < 512; x++)
                        {
                            bits512[y * 512 + x] = bits128[(y / 4) * 128 + (x / 4)];
                        }
                    }
                    lcli.FrameData = new byte[1][];

                    MemoryStream ms2 = new MemoryStream();
                    BinaryWriter bw2 = new BinaryWriter(ms2);
                    for (int i = 0; i < 512 * 512; i++)
                    {
                        bw2.Write(bits512[i].R);
                        bw2.Write(bits512[i].G);
                        bw2.Write(bits512[i].B);
                        bw2.Write(bits512[i].A);
                    }
                    lcli.FrameData[0] = ms2.ToArray();
                    ms2.Close();

                    lclayer.Art = lcli;

                    if (layer == 0)
                    {
                        lchunk.BackLayer = lclayer;
                    }
                    else
                    {
                        lchunk.FrontLayer = lclayer;
                    }
                }

                landscape.Chunks.Add(lchunk);

                chunkId++;
            }

            landscape.Save(directory + "\\landscape.dat");

            return;

            // Level
            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);

            // Layout
            bw.Write("Emerald Hill, Act 1");
            bw.Write("Sega");
            bw.Write(88);
            bw.Write(8);
            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 88; x++)
                {
                    bw.Write(mFGLayoutTiles[x, y]);
                }
            }

            // Objects
            List <object> objects = new List <object>();

            // Player start
            objects.Add(new { Id = 1, Subtype = 0, X = 0x0060, Y = 0x028F, Respawn = false, Xflip = false, Yflip = false });

            for (int i = 0; i < mObjects.Length; i += 6)
            {
                short x       = BitConverter.ToInt16(new byte[] { mObjects[i + 1], mObjects[i + 0] }, 0);
                short y       = BitConverter.ToInt16(new byte[] { mObjects[i + 3], (byte)(mObjects[i + 2] & 0x0F) }, 0);
                byte  id      = mObjects[i + 4];
                byte  subtype = mObjects[i + 5];
                bool  respawn = ((mObjects[i + 2] & 0x80) == 0);
                bool  xflip   = ((mObjects[i + 2] & 0x40) != 0);
                bool  yflip   = ((mObjects[i + 2] & 0x20) != 0);

                objects.Add(new { Id = (int)id, Subtype = (int)subtype, X = (int)x, Y = (int)y, Respawn = respawn, Xflip = xflip, Yflip = yflip });
            }

            for (int i = 0; i < mRings.Length; i += 4)
            {
                short x = BitConverter.ToInt16(new byte[] { mRings[i + 1], mRings[i + 0] }, 0);
                if (x == -1)
                {
                    break;
                }
                short y      = BitConverter.ToInt16(new byte[] { mRings[i + 3], (byte)(mRings[i + 2] & 0x0F) }, 0);
                int   t      = mRings[i + 2] >> 4;
                bool  column = ((t & 8) != 0);
                int   c      = (t & 7) + 1;

                for (int j = 0; j < c; j++)
                {
                    objects.Add(new { Id = 37, Subtype = 0, X = (int)x, Y = (int)y, Respawn = false, Xflip = false, Yflip = false });

                    if (column)
                    {
                        y += 24;
                    }
                    else
                    {
                        x += 24;
                    }
                }
            }

            bw.Write(objects.Count);
            foreach (dynamic obj in objects)
            {
                bw.Write(obj.Id);
                bw.Write(obj.Subtype);
                bw.Write(obj.X);
                bw.Write(obj.Y);
                bw.Write(obj.Respawn);
                bw.Write(obj.Xflip);
                bw.Write(obj.Yflip);
            }

            bw.Close();
            File.WriteAllBytes(directory + "\\act1.dat", ms.ToArray());
        }