diff --git a/src/blocks.zig b/src/blocks.zig index 11ef3e53..d301d752 100644 --- a/src/blocks.zig +++ b/src/blocks.zig @@ -20,6 +20,7 @@ const Entity = main.server.Entity; const entity_data = @import("entity_data.zig"); const EntityDataClass = entity_data.EntityDataClass; const sbb = main.server.terrain.structure_building_blocks; +const blueprint = main.blueprint; var arena = main.heap.NeverFailingArenaAllocator.init(main.globalAllocator); const allocator = arena.allocator(); @@ -207,6 +208,7 @@ pub fn finishBlocks(zonElements: std.StringHashMap(ZonElement)) void { registerLodReplacement(i, zonElements.get(_id[i]) orelse continue); registerOpaqueVariant(i, zonElements.get(_id[i]) orelse continue); } + blueprint.registerVoidBlock(parseBlock("cubyz:void")); } pub fn reset() void { diff --git a/src/blueprint.zig b/src/blueprint.zig index f1aa1a0f..c103919c 100644 --- a/src/blueprint.zig +++ b/src/blueprint.zig @@ -21,6 +21,7 @@ const BinaryWriter = main.utils.BinaryWriter; const BinaryReader = main.utils.BinaryReader; pub const blueprintVersion = 0; +var voidType: ?u16 = null; pub const BlueprintCompression = enum(u16) { deflate, @@ -104,7 +105,10 @@ pub const Blueprint = struct { } return .{.success = self}; } - pub fn paste(self: Blueprint, pos: Vec3i) void { + pub const PasteFlags = struct { + preserveVoid: bool = false, + }; + pub fn paste(self: Blueprint, pos: Vec3i, flags: PasteFlags) void { const startX = pos[0]; const startY = pos[1]; const startZ = pos[2]; @@ -119,7 +123,8 @@ pub const Blueprint = struct { const worldZ = startZ +% @as(i32, @intCast(z)); const block = self.blocks.get(x, y, z); - _ = main.server.world.?.updateBlock(worldX, worldY, worldZ, block); + if(block.typ != voidType or flags.preserveVoid) + _ = main.server.world.?.updateBlock(worldX, worldY, worldZ, block); } } } @@ -270,3 +275,8 @@ pub const Blueprint = struct { } } }; + +pub fn registerVoidBlock(block: Block) void { + voidType = block.typ; + std.debug.assert(voidType != 0); +} diff --git a/src/server/command/worldedit/paste.zig b/src/server/command/worldedit/paste.zig index 8bace8da..b0ce655b 100644 --- a/src/server/command/worldedit/paste.zig +++ b/src/server/command/worldedit/paste.zig @@ -10,13 +10,22 @@ const copy = @import("copy.zig"); const Block = main.blocks.Block; const Blueprint = main.blueprint.Blueprint; -pub const description = "Paste clipboard content to current player position."; -pub const usage = "/paste"; +pub const description = + \\Paste clipboard content to current player position. + \\'-v' - Enable preserving void blocks. By default, void blocks are not preserved. +; +pub const usage = "/paste [-v]"; pub fn execute(args: []const u8, source: *User) void { + var flags = Blueprint.PasteFlags{}; + if(args.len != 0) { - source.sendMessage("#ff0000Too many arguments for command /paste. Expected no arguments.", .{}); - return; + if(std.mem.eql(u8, args, "-v")) { + flags.preserveVoid = true; + } else { + source.sendMessage("#ff0000Argument(s) '{s}' not recognized.", .{args}); + return; + } } if(source.worldEditData.clipboard) |clipboard| { @@ -38,7 +47,7 @@ pub fn execute(args: []const u8, source: *User) void { }, } - clipboard.paste(pos); + clipboard.paste(pos, flags); } else { source.sendMessage("#ff0000Error: No clipboard content to paste.", .{}); } diff --git a/src/server/command/worldedit/redo.zig b/src/server/command/worldedit/redo.zig index dbef436f..d1ed1ae2 100644 --- a/src/server/command/worldedit/redo.zig +++ b/src/server/command/worldedit/redo.zig @@ -20,7 +20,7 @@ pub fn execute(args: []const u8, source: *User) void { action.position[1] + @as(i32, @intCast(action.blueprint.blocks.depth)) - 1, action.position[2] + @as(i32, @intCast(action.blueprint.blocks.height)) - 1, }); - action.blueprint.paste(action.position); + action.blueprint.paste(action.position, .{.preserveVoid = true}); switch(undo) { .success => |blueprint| { diff --git a/src/server/command/worldedit/undo.zig b/src/server/command/worldedit/undo.zig index 5849d52b..7e5d6997 100644 --- a/src/server/command/worldedit/undo.zig +++ b/src/server/command/worldedit/undo.zig @@ -20,7 +20,7 @@ pub fn execute(args: []const u8, source: *User) void { action.position[1] + @as(i32, @intCast(action.blueprint.blocks.depth)) - 1, action.position[2] + @as(i32, @intCast(action.blueprint.blocks.height)) - 1, }); - action.blueprint.paste(action.position); + action.blueprint.paste(action.position, .{.preserveVoid = true}); switch(redo) { .success => |blueprint| {