diff --git a/src/blocks.zig b/src/blocks.zig index 32b512387b..8b912567a1 100644 --- a/src/blocks.zig +++ b/src/blocks.zig @@ -66,6 +66,8 @@ pub const Ore = struct { maxHeight: i32, minHeight: i32, + targetTags: []const Tag, + blockType: u16, seed: u64, }; @@ -214,6 +216,8 @@ pub fn register(_: []const u8, id: []const u8, zon: ZonElement) u16 { std.log.err("Ore must have rotation mode \"cubyz:ore\"!", .{}); break :blk; } + const targetBlockTags = Tag.loadTagsFromZon(main.stackAllocator, oreProperties.getChild("targetTags")); + defer main.stackAllocator.free(targetBlockTags); ores.append(main.worldArena, .{ .veins = oreProperties.get(f32, "veins") orelse 0, .size = oreProperties.get(f32, "size") orelse 0, @@ -221,6 +225,7 @@ pub fn register(_: []const u8, id: []const u8, zon: ZonElement) u16 { .minHeight = oreProperties.get(i32, "minHeight") orelse std.math.minInt(i32), .density = oreProperties.get(f32, "density") orelse 0.5, .blockType = @intCast(size), + .targetTags = targetBlockTags, .seed = std.hash.Wyhash.hash(0, id), }); } diff --git a/src/server/terrain/chunkgen/OreGenerator.zig b/src/server/terrain/chunkgen/OreGenerator.zig index ce5d191b79..32ee278e73 100644 --- a/src/server/terrain/chunkgen/OreGenerator.zig +++ b/src/server/terrain/chunkgen/OreGenerator.zig @@ -96,18 +96,20 @@ fn considerCoordinates(ore: *const main.blocks.Ore, relX: f32, relY: f32, relZ: zMin = @max(zMin, 0); zMax = @min(zMax, chunk.super.width); var curZ = zMin; - while (curZ < zMax) : (curZ += 1) { + outer: while (curZ < zMax) : (curZ += 1) { const distToCenterZ = (@as(f32, @floatFromInt(curZ)) - veinRelZ)/radius; const distSqr = xyDistSqr + distToCenterZ*distToCenterZ; - if (distSqr < 1) { - // Add some roughness. The ore density gets smaller at the edges: - if ((1 - distSqr)*ore.density >= random.nextFloat(&veinSeed)) { - const stoneBlock = chunk.getBlock(curX, curY, curZ); - if (chunk.getBlock(curX, curY, curZ).allowOres()) { - chunk.updateBlockInGeneration(curX, curY, curZ, .{.typ = ore.blockType, .data = stoneBlock.typ}); - } + if (distSqr >= 1) continue; + // Add some roughness. The ore density gets smaller at the edges: + if ((1 - distSqr)*ore.density < random.nextFloat(&veinSeed)) continue; + const stoneBlock = chunk.getBlock(curX, curY, curZ); + if (!stoneBlock.allowOres()) continue; + for (ore.targetTags) |tag| { + if (!stoneBlock.hasTag(tag)) { + continue :outer; } } + chunk.updateBlockInGeneration(curX, curY, curZ, .{.typ = ore.blockType, .data = stoneBlock.typ}); } } }