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); } } }
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); } } }
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); } } }
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); } }
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); } }