internal static void CutCallback( Player player, Position[] marks, object tag ) { int sx = Math.Min( marks[0].X, marks[1].X ); int ex = Math.Max( marks[0].X, marks[1].X ); int sy = Math.Min( marks[0].Y, marks[1].Y ); int ey = Math.Max( marks[0].Y, marks[1].Y ); int sh = Math.Min( marks[0].H, marks[1].H ); int eh = Math.Max( marks[0].H, marks[1].H ); byte fillType = (byte)tag; int volume = (ex - sx + 1) * (ey - sy + 1) * (eh - sh + 1); if( !player.CanDraw( volume ) ) { player.MessageNow( String.Format( "You are only allowed to run commands that affect up to {0} blocks. This one would affect {1} blocks.", player.Info.Rank.DrawLimit, volume ) ); return; } // remember dimensions and orientation CopyInformation copyInfo = new CopyInformation { WidthX = marks[1].X - marks[0].X, WidthY = marks[1].Y - marks[0].Y, Height = marks[1].H - marks[0].H, Buffer = new byte[ex - sx + 1, ey - sy + 1, eh - sh + 1] }; player.UndoBuffer.Clear(); int blocks = 0, blocksDenied = 0; bool cannotUndo = false; for( int x = sx; x <= ex; x++ ) { for( int y = sy; y <= ey; y++ ) { for( int h = sh; h <= eh; h++ ) { copyInfo.Buffer[x - sx, y - sy, h - sh] = player.World.Map.GetBlockByte( x, y, h ); DrawOneBlock( player, fillType, x, y, h, ref blocks, ref blocksDenied, ref cannotUndo ); } } } player.CopyInformation = copyInfo; player.MessageNow( "{0} blocks were cut. You can now &H/paste", volume ); player.MessageNow( "Origin at {0} {1}{2} corner.", (copyInfo.Height > 0 ? "bottom" : "top"), (copyInfo.WidthY > 0 ? "south" : "north"), (copyInfo.WidthX > 0 ? "west" : "east") ); Logger.Log( "{0} cut {1} blocks from {2}, replacing {3} blocks with {4}.", LogType.UserActivity, player.Name, volume, player.World.Name, blocks, (Block)fillType ); player.UndoBuffer.TrimExcess(); Server.RequestGC(); }
internal static void CopyCallback( Player player, Position[] marks, object tag ) { int sx = Math.Min( marks[0].X, marks[1].X ); int ex = Math.Max( marks[0].X, marks[1].X ); int sy = Math.Min( marks[0].Y, marks[1].Y ); int ey = Math.Max( marks[0].Y, marks[1].Y ); int sh = Math.Min( marks[0].H, marks[1].H ); int eh = Math.Max( marks[0].H, marks[1].H ); int volume = (ex - sx + 1) * (ey - sy + 1) * (eh - sh + 1); if( !player.CanDraw( volume ) ) { player.MessageNow( String.Format( "You are only allowed to run commands that affect up to {0} blocks. This one would affect {1} blocks.", player.Info.Rank.DrawLimit, volume ) ); return; } // remember dimensions and orientation CopyInformation copyInfo = new CopyInformation { WidthX = marks[1].X - marks[0].X, WidthY = marks[1].Y - marks[0].Y, Height = marks[1].H - marks[0].H, Buffer = new byte[ex - sx + 1, ey - sy + 1, eh - sh + 1] }; for( int x = sx; x <= ex; x++ ) { for( int y = sy; y <= ey; y++ ) { for( int h = sh; h <= eh; h++ ) { copyInfo.Buffer[x - sx, y - sy, h - sh] = player.World.Map.GetBlockByte( x, y, h ); } } } player.CopyInformation = copyInfo; player.MessageNow( "{0} blocks were copied. You can now &H/paste", volume ); player.MessageNow( "Origin at {0} {1}{2} corner.", (copyInfo.Height > 0 ? "bottom" : "top"), (copyInfo.WidthY > 0 ? "south" : "north"), (copyInfo.WidthX > 0 ? "west" : "east") ); Logger.Log( "{0} copied {1} blocks from {2}.", LogType.UserActivity, player.Name, volume, player.World.Name ); }