mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 03:06:55 -04:00
Add block pattern parsing (#1237)
* Revert "Remove pattern code from PR" This reverts commit d9296b00cff93e7f0bd0962f012aa98f3ec39915. * Apply review requests * Update import * Rename pattern.zig to Pattern.zig * Fix compilation errors * Remove code comment
This commit is contained in:
parent
8d54e187cf
commit
d9dc3f1a22
52
src/server/command/worldedit/Pattern.zig
Normal file
52
src/server/command/worldedit/Pattern.zig
Normal file
@ -0,0 +1,52 @@
|
||||
const std = @import("std");
|
||||
|
||||
const main = @import("main");
|
||||
const AliasTable = main.utils.AliasTable;
|
||||
const Block = main.blocks.Block;
|
||||
const ListUnmanaged = main.ListUnmanaged;
|
||||
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
||||
|
||||
blocks: AliasTable(Entry),
|
||||
|
||||
const Entry = struct {
|
||||
block: Block,
|
||||
chance: f32,
|
||||
};
|
||||
|
||||
pub fn initFromString(allocator: NeverFailingAllocator, source: []const u8) !@This() {
|
||||
var specifiers = std.mem.splitScalar(u8, source, ',');
|
||||
var totalWeight: f32 = 0;
|
||||
|
||||
var weightedEntries: ListUnmanaged(struct {block: Block, weight: f32}) = .{};
|
||||
defer weightedEntries.deinit(main.stackAllocator);
|
||||
|
||||
while(specifiers.next()) |specifier| {
|
||||
var iterator = std.mem.splitScalar(u8, specifier, '%');
|
||||
|
||||
var weight: f32 = undefined;
|
||||
var block = main.blocks.parseBlock(iterator.rest());
|
||||
|
||||
const first = iterator.first();
|
||||
|
||||
weight = std.fmt.parseFloat(f32, first) catch blk: {
|
||||
// To distinguish somehow between mistyped numeric values and actual block IDs we check for addon name separator.
|
||||
if(!std.mem.containsAtLeastScalar(u8, first, 1, ':')) return error.PatternSyntaxError;
|
||||
block = main.blocks.parseBlock(first);
|
||||
break :blk 1.0;
|
||||
};
|
||||
totalWeight += weight;
|
||||
weightedEntries.append(main.stackAllocator, .{.block = block, .weight = weight});
|
||||
}
|
||||
|
||||
const entries = allocator.alloc(Entry, weightedEntries.items.len);
|
||||
for(weightedEntries.items, 0..) |entry, i| {
|
||||
entries[i] = .{.block = entry.block, .chance = entry.weight/totalWeight};
|
||||
}
|
||||
|
||||
return .{.blocks = .init(allocator, entries)};
|
||||
}
|
||||
|
||||
pub fn deinit(self: @This(), allocator: NeverFailingAllocator) void {
|
||||
self.blocks.deinit(allocator);
|
||||
allocator.free(self.blocks.items);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user