예제 #1
0
        static void UndoBlock(UndoFormatArgs args, Level lvl, UndoFormatEntry P)
        {
            byte lvlBlock = lvl.GetTile(P.X, P.Y, P.Z);

            if (lvlBlock == P.NewBlock || Block.Convert(lvlBlock) == Block.water ||
                Block.Convert(lvlBlock) == Block.lava || lvlBlock == Block.grass)
            {
                if (args.Player != null)
                {
                    DrawOpBlock block;
                    block.X     = P.X; block.Y = P.Y; block.Z = P.Z;
                    block.Block = P.Block; block.ExtBlock = P.ExtBlock;
                    args.Output(block);
                }
                else
                {
                    Player.GlobalBlockchange(lvl, P.X, P.Y, P.Z, P.Block, P.ExtBlock); // TODO: rewrite this :/
                    lvl.SetTile(P.X, P.Y, P.Z, P.Block);
                    if (P.Block != Block.custom_block)
                    {
                        return;
                    }
                    lvl.SetExtTile(P.X, P.Y, P.Z, P.ExtBlock);
                }
            }
        }
예제 #2
0
        public override void EnumerateEntries(Stream s, UndoFormatArgs args)
        {
            List <ChunkHeader> list = new List <ChunkHeader>();
            UndoFormatEntry    pos;
            DateTime           time;

            ReadHeaders(list, s);
            for (int i = list.Count - 1; i >= 0; i--)
            {
                ChunkHeader chunk = list[i];
                // Can we safely discard the entire chunk?
                bool inRange = chunk.BaseTime.AddTicks((65536 >> 2) * TimeSpan.TicksPerSecond) >= args.Start;
                if (!inRange)
                {
                    args.Finished = true; return;
                }
                if (!args.Map.CaselessEq(chunk.LevelName))
                {
                    continue;
                }

                s.Seek(chunk.DataPosition, SeekOrigin.Begin);
                if (args.Temp == null)
                {
                    args.Temp = new byte[ushort.MaxValue * entrySize];
                }
                s.Read(args.Temp, 0, chunk.Entries * entrySize);
                byte[] temp = args.Temp;

                for (int j = chunk.Entries - 1; j >= 0; j--)
                {
                    int    offset = j * entrySize;
                    ushort flags  = U16(temp, offset + 0);
                    // upper 2 bits for 'ext' or 'physics' type, lower 14 bits for time delta.

                    // TODO: should this be instead:
                    // int delta = Flags & 0x3FFF;
                    // timeDeltaSeconds = delta >= 0x2000 ? (short)(delta - 16384) : (short)delta;
                    time = chunk.BaseTime.AddTicks((flags & 0x3FFF) * TimeSpan.TicksPerSecond);
                    if (time < args.Start)
                    {
                        args.Finished = true; return;
                    }
                    if (time > args.End)
                    {
                        continue;
                    }

                    int index = I32(temp, offset + 2);
                    pos.X = (ushort)(index % chunk.Width);
                    pos.Y = (ushort)((index / chunk.Width) / chunk.Length);
                    pos.Z = (ushort)((index / chunk.Width) % chunk.Length);

                    pos.Block    = Block.FromRaw(temp[offset + 6], (flags & (1 << 14)) != 0);
                    pos.NewBlock = Block.FromRaw(temp[offset + 7], (flags & (1 << 15)) != 0);
                    args.Output(pos);
                }
            }
        }
예제 #3
0
        public override void EnumerateEntries(Stream s, UndoFormatArgs args)
        {
            List <ChunkHeader> list = new List <ChunkHeader>();
            UndoFormatEntry    pos;
            DateTime           time;

            ReadHeaders(list, s);
            for (int i = list.Count - 1; i >= 0; i--)
            {
                ChunkHeader chunk = list[i];
                // Can we safely discard the entire chunk?
                bool inRange = chunk.BaseTime.AddTicks(65536 * TimeSpan.TicksPerSecond) >= args.Start;
                if (!inRange)
                {
                    args.Stop = true; return;
                }
                if (!args.LevelName.CaselessEq(chunk.LevelName))
                {
                    continue;
                }

                s.Seek(chunk.DataPosition, SeekOrigin.Begin);
                if (args.Temp == null)
                {
                    args.Temp = new byte[ushort.MaxValue * entrySize];
                }
                s.Read(args.Temp, 0, chunk.Entries * entrySize);
                byte[] temp = args.Temp;

                for (int j = chunk.Entries - 1; j >= 0; j--)
                {
                    int offset = j * entrySize;
                    time = chunk.BaseTime.AddTicks(U16(temp, offset + 0) * TimeSpan.TicksPerSecond);
                    if (time < args.Start)
                    {
                        args.Stop = true; return;
                    }
                    if (time > args.End)
                    {
                        continue;
                    }

                    pos.X = U16(temp, offset + 2);
                    pos.Y = U16(temp, offset + 4);
                    pos.Z = U16(temp, offset + 6);

                    pos.Block.BlockID    = temp[offset + 8];
                    pos.Block.ExtID      = temp[offset + 9];
                    pos.NewBlock.BlockID = temp[offset + 10];
                    pos.NewBlock.ExtID   = temp[offset + 11];
                    args.Output(pos);
                }
            }
        }
예제 #4
0
        public static void DoRedo(Stream s, UndoFormat format, UndoFormatArgs args)
        {
            DrawOpBlock block;

            foreach (UndoFormatEntry P in format.GetEntries(s, args))
            {
                if (P.Time > args.End)
                {
                    continue;
                }

                block.X     = P.X; block.Y = P.Y; block.Z = P.Z;
                block.Block = P.Block; block.ExtBlock = P.ExtBlock;
                args.Output(block);
            }
        }
예제 #5
0
        public override void EnumerateEntries(Stream s, UndoFormatArgs args)
        {
            UndoFormatEntry pos = default(UndoFormatEntry);

            string[] lines = new StreamReader(s).ReadToEnd().SplitSpaces();
            DateTime time;

            // because we have space to end of each entry, need to subtract one otherwise we'll start at a "".
            const int items = 7;

            for (int i = (lines.Length - 1) / items; i > 0; i--)
            {
                // line format: mapName x y z date oldblock newblock
                string timeRaw = lines[(i * items) - 3].Replace('&', ' ');
                time = DateTime.Parse(timeRaw, CultureInfo.InvariantCulture);
                if (time < args.Start)
                {
                    args.Stop = true; return;
                }
                if (time > args.End)
                {
                    continue;
                }

                string map = lines[(i * items) - 7];
                if (!args.LevelName.CaselessEq(map))
                {
                    continue;
                }

                pos.X = ushort.Parse(lines[(i * items) - 6]);
                pos.Y = ushort.Parse(lines[(i * items) - 5]);
                pos.Z = ushort.Parse(lines[(i * items) - 4]);

                pos.Block.BlockID    = byte.Parse(lines[(i * items) - 2]);
                pos.NewBlock.BlockID = byte.Parse(lines[(i * items) - 1]);
                args.Output(pos);
            }
        }