From a7052d25f52465dc11c48b052a8dcad1425971f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Wi=C5=9Bniewski?= Date: Sun, 30 Mar 2025 17:03:19 +0200 Subject: [PATCH] Add `/redo` command (#1238) * Add undo and redo commands * Remove unintended change * Remove redo code * Revert "Remove redo code" This reverts commit 80aeca1dc2d0f7b3f3570b95937a8f7fd87cac5d. * Fix variable name in /redo * Update import --- src/server/command/_list.zig | 1 + src/server/command/worldedit/paste.zig | 1 + src/server/command/worldedit/redo.zig | 37 ++++++++++++++++++++++++++ src/server/command/worldedit/undo.zig | 14 ++++++++++ src/server/server.zig | 4 ++- 5 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/server/command/worldedit/redo.zig diff --git a/src/server/command/_list.zig b/src/server/command/_list.zig index 77e407ab..e70188d7 100644 --- a/src/server/command/_list.zig +++ b/src/server/command/_list.zig @@ -7,6 +7,7 @@ pub const time = @import("time.zig"); pub const tp = @import("tp.zig"); pub const undo = @import("worldedit/undo.zig"); +pub const redo = @import("worldedit/redo.zig"); pub const pos1 = @import("worldedit/pos1.zig"); pub const pos2 = @import("worldedit/pos2.zig"); pub const deselect = @import("worldedit/deselect.zig"); diff --git a/src/server/command/worldedit/paste.zig b/src/server/command/worldedit/paste.zig index 27da5afb..8bace8da 100644 --- a/src/server/command/worldedit/paste.zig +++ b/src/server/command/worldedit/paste.zig @@ -31,6 +31,7 @@ pub fn execute(args: []const u8, source: *User) void { switch(undo) { .success => |blueprint| { source.worldEditData.undoHistory.push(.init(blueprint, pos, "paste")); + source.worldEditData.redoHistory.clear(); }, .failure => { source.sendMessage("#ff0000Error: Could not capture undo history.", .{}); diff --git a/src/server/command/worldedit/redo.zig b/src/server/command/worldedit/redo.zig new file mode 100644 index 00000000..dbef436f --- /dev/null +++ b/src/server/command/worldedit/redo.zig @@ -0,0 +1,37 @@ +const std = @import("std"); + +const main = @import("main"); +const User = main.server.User; + +const Block = main.blocks.Block; +const Blueprint = main.blueprint.Blueprint; + +pub const description = "Redo last change done to world with world editing commands."; +pub const usage = "/redo"; + +pub fn execute(args: []const u8, source: *User) void { + if(args.len != 0) { + source.sendMessage("#ff0000Too many arguments for command /redo. Expected no arguments.", .{}); + return; + } + if(source.worldEditData.redoHistory.pop()) |action| { + const undo = Blueprint.capture(main.globalAllocator, action.position, .{ + action.position[0] + @as(i32, @intCast(action.blueprint.blocks.width)) - 1, + 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); + + switch(undo) { + .success => |blueprint| { + source.worldEditData.undoHistory.push(.init(blueprint, action.position, action.message)); + }, + .failure => { + source.sendMessage("#ff0000Error: Could not capture undo history.", .{}); + }, + } + source.sendMessage("#00ff00Re-done last {s}.", .{action.message}); + } else { + source.sendMessage("#ccccccNothing to redo.", .{}); + } +} diff --git a/src/server/command/worldedit/undo.zig b/src/server/command/worldedit/undo.zig index a7cefc48..5849d52b 100644 --- a/src/server/command/worldedit/undo.zig +++ b/src/server/command/worldedit/undo.zig @@ -15,7 +15,21 @@ pub fn execute(args: []const u8, source: *User) void { return; } if(source.worldEditData.undoHistory.pop()) |action| { + const redo = Blueprint.capture(main.globalAllocator, action.position, .{ + action.position[0] + @as(i32, @intCast(action.blueprint.blocks.width)) - 1, + 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); + + switch(redo) { + .success => |blueprint| { + source.worldEditData.redoHistory.push(.init(blueprint, action.position, action.message)); + }, + .failure => { + source.sendMessage("#ff0000Error: Could not capture redo history.", .{}); + }, + } source.sendMessage("#00ff00Un-done last {s}.", .{action.message}); } else { source.sendMessage("#ccccccNothing to undo.", .{}); diff --git a/src/server/server.zig b/src/server/server.zig index 232a17c5..9ce286f6 100644 --- a/src/server/server.zig +++ b/src/server/server.zig @@ -30,6 +30,7 @@ pub const WorldEditData = struct { selectionPosition2: ?Vec3i = null, clipboard: ?Blueprint = null, undoHistory: History, + redoHistory: History, const History = struct { changes: CircularBufferQueue(Value), @@ -69,13 +70,14 @@ pub const WorldEditData = struct { } }; pub fn init() WorldEditData { - return .{.undoHistory = History.init()}; + return .{.undoHistory = History.init(), .redoHistory = History.init()}; } pub fn deinit(self: *WorldEditData) void { if(self.clipboard != null) { self.clipboard.?.deinit(main.globalAllocator); } self.undoHistory.deinit(); + self.redoHistory.deinit(); } };