Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/server/command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,18 @@ pub const BiomeId = struct {
}
};

pub const BlockId = struct {
block: main.blocks.Block,

pub fn parse(_: NeverFailingAllocator, name: []const u8, args: []const u8, errorMessage: *ListManaged(u8)) error{ParseError}!@This() {
const blockTyp = main.blocks.getBlockById(args) catch {
errorMessage.print("Couldn't find block for <{s}> with id \"{s}\"", .{name, args});
return error.ParseError;
};
return .{.block = .{.typ = blockTyp, .data = 0}};
}
};

pub const EntityModel = struct {
index: main.entityModel.EntityModelIndex,

Expand Down
1 change: 1 addition & 0 deletions src/server/command/_list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub const pos1 = @import("worldedit/pos1.zig");
pub const pos2 = @import("worldedit/pos2.zig");
pub const deselect = @import("worldedit/deselect.zig");
pub const copy = @import("worldedit/copy.zig");
pub const count = @import("worldedit/count.zig");
pub const paste = @import("worldedit/paste.zig");
pub const blueprint = @import("worldedit/blueprint.zig");
pub const rotate = @import("worldedit/rotate.zig");
Expand Down
64 changes: 64 additions & 0 deletions src/server/command/worldedit/count.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const std = @import("std");

const main = @import("main");
const command = main.server.command;
const Source = command.Source;

const Block = main.blocks.Block;
const Blueprint = main.blueprint.Blueprint;

pub const description = "Count block(s) appearance(s) in selection.";
pub const usage =
\\/count <blockId>
\\/count
;

pub const Args = union(enum) {
@"/count": struct { block: ?command.BlockId },
};

pub fn execute(args: Args, source: Source) void {
if (source != .user) {
source.sendMessage("Command cannot be run without a user", .{});
return;
}
const user = source.user;
const selection = command.getCurrentSelection(user) catch return;

var result = Blueprint.capture(main.stackAllocator, selection);

switch (result) {
.success => |*success| {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.success => |*success| {
.success => |*blueprint| {

defer success.deinit(main.stackAllocator);

var context: std.AutoHashMapUnmanaged(u16, u32) = .{};
defer context.deinit(main.stackAllocator.allocator);

success.apply(&context, countBlocks);

if (args.@"/count".block) |block| {
const count = context.get(block.block.typ) orelse 0;
user.sendMessage("#ffff00{s} #ffffff{d}", .{block.block.id(), count});
} else {
var iterator = context.iterator();
while (iterator.next()) |next| {
user.sendMessage("#ffff00{s} #ffffff{d}", .{(Block{.typ = next.key_ptr.*, .data = 0}).id(), next.value_ptr.*});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you print them sorted by count, descending?

}
}
},
.failure => |e| {
user.sendMessage("#ff0000Error while capturing block {}: {s}", .{e.pos, e.message});
std.log.warn("Error while capturing block {}: {s}", .{e.pos, e.message});
},
}
}

fn countBlocks(context: *std.AutoHashMapUnmanaged(u16, u32), current: Block) Block {
const result = context.getOrPut(main.stackAllocator.allocator, current.typ) catch unreachable;
if (result.found_existing) {
result.value_ptr.* = result.value_ptr.* + 1;
} else {
result.value_ptr.* = 1;
}
return current;
}
Loading