mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 03:06:55 -04:00
Add /rotate
command (#1225)
* Revert "Remove rotate command" This reverts commit 3a84e03d158e5cc038ae3e936384c348431a9ac4. * Fix stair rotation * Add rotate fn to Blueprint * Apply suggestions from code review Co-authored-by: IntegratedQuantum <43880493+IntegratedQuantum@users.noreply.github.com> * Replace cos sin with switch * Add angle parameter to /rotate * Update src/blueprint.zig * Apply review suggestions * Fix formatting issues * Update src/rotation.zig --------- Co-authored-by: IntegratedQuantum <43880493+IntegratedQuantum@users.noreply.github.com>
This commit is contained in:
parent
e815d98b89
commit
5845da7ca9
@ -10,6 +10,8 @@ const Array3D = main.utils.Array3D;
|
||||
const Block = main.blocks.Block;
|
||||
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
||||
const User = main.server.User;
|
||||
const ServerChunk = main.chunk.ServerChunk;
|
||||
const Degrees = main.rotation.Degrees;
|
||||
|
||||
const GameIdToBlueprintIdMapType = std.AutoHashMap(u16, u16);
|
||||
const BlockIdSizeType = u32;
|
||||
@ -36,6 +38,32 @@ pub const Blueprint = struct {
|
||||
pub fn clone(self: *Blueprint, allocator: NeverFailingAllocator) Blueprint {
|
||||
return .{.blocks = self.blocks.clone(allocator)};
|
||||
}
|
||||
pub fn rotateZ(self: Blueprint, allocator: NeverFailingAllocator, angle: Degrees) Blueprint {
|
||||
var new = Blueprint{
|
||||
.blocks = switch(angle) {
|
||||
.@"0", .@"180" => .init(allocator, self.blocks.width, self.blocks.depth, self.blocks.height),
|
||||
.@"90", .@"270" => .init(allocator, self.blocks.depth, self.blocks.width, self.blocks.height),
|
||||
},
|
||||
};
|
||||
|
||||
for(0..self.blocks.width) |xOld| {
|
||||
for(0..self.blocks.depth) |yOld| {
|
||||
const xNew, const yNew = switch(angle) {
|
||||
.@"0" => .{xOld, yOld},
|
||||
.@"90" => .{new.blocks.width - yOld - 1, xOld},
|
||||
.@"180" => .{new.blocks.width - xOld - 1, new.blocks.depth - yOld - 1},
|
||||
.@"270" => .{yOld, new.blocks.depth - xOld - 1},
|
||||
};
|
||||
|
||||
for(0..self.blocks.height) |z| {
|
||||
const block = self.blocks.get(xOld, yOld, z);
|
||||
new.blocks.set(xNew, yNew, z, block.rotateZ(angle));
|
||||
}
|
||||
}
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
const CaptureResult = union(enum) {
|
||||
success: Blueprint,
|
||||
failure: struct {pos: Vec3i, message: []const u8},
|
||||
|
@ -806,7 +806,7 @@ pub const RotationModes = struct {
|
||||
comptime var rotationTable: [4][256]u8 = undefined;
|
||||
comptime for(0..4) |a| {
|
||||
for(0..256) |old| {
|
||||
var new: u8 = 0;
|
||||
var new: u8 = 0b11_11_11_11;
|
||||
|
||||
for(0..2) |i| for(0..2) |j| for(0..2) |k| {
|
||||
const sin: f32 = @sin((std.math.pi/2.0)*@as(f32, @floatFromInt(a)));
|
||||
@ -819,7 +819,7 @@ pub const RotationModes = struct {
|
||||
const rY = @intFromBool(x*sin + y*cos > 0);
|
||||
|
||||
if(hasSubBlock(@intCast(old), @intCast(i), @intCast(j), @intCast(k))) {
|
||||
new |= subBlockMask(rX, rY, @intCast(k));
|
||||
new &= ~subBlockMask(rX, rY, @intCast(k));
|
||||
}
|
||||
};
|
||||
rotationTable[a][old] = new;
|
||||
|
@ -12,3 +12,4 @@ pub const deselect = @import("worldedit/deselect.zig");
|
||||
pub const copy = @import("worldedit/copy.zig");
|
||||
pub const paste = @import("worldedit/paste.zig");
|
||||
pub const blueprint = @import("worldedit/blueprint.zig");
|
||||
pub const rotate = @import("worldedit/rotate.zig");
|
||||
|
28
src/server/command/worldedit/rotate.zig
Normal file
28
src/server/command/worldedit/rotate.zig
Normal file
@ -0,0 +1,28 @@
|
||||
const std = @import("std");
|
||||
|
||||
const main = @import("root");
|
||||
const User = main.server.User;
|
||||
const Degrees = main.rotation.Degrees;
|
||||
|
||||
pub const description = "rotate clipboard content around Z axis counterclockwise.";
|
||||
pub const usage =
|
||||
\\/rotate
|
||||
\\/rotate <0/90/180/270>
|
||||
;
|
||||
|
||||
pub fn execute(args: []const u8, source: *User) void {
|
||||
var angle: Degrees = .@"90";
|
||||
if(args.len != 0) {
|
||||
angle = std.meta.stringToEnum(Degrees, args) orelse {
|
||||
source.sendMessage("#ff0000Error: Invalid angle '{s}'. Use 0, 90, 180 or 270.", .{args});
|
||||
return;
|
||||
};
|
||||
}
|
||||
if(source.worldEditData.clipboard == null) {
|
||||
source.sendMessage("#ff0000Error: No clipboard content to rotate.", .{});
|
||||
return;
|
||||
}
|
||||
const current = source.worldEditData.clipboard.?;
|
||||
defer current.deinit(main.globalAllocator);
|
||||
source.worldEditData.clipboard = current.rotateZ(main.globalAllocator, angle);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user