diff --git a/assets/cubyz/biomes/forest/base.zig.zon b/assets/cubyz/biomes/forest/base.zig.zon index 7fb037f8..f6662642 100644 --- a/assets/cubyz/biomes/forest/base.zig.zon +++ b/assets/cubyz/biomes/forest/base.zig.zon @@ -21,7 +21,7 @@ }, .{ .id = "cubyz:sbb", - .structure = "cubyz:tree/birch/forest_generator", + .structure = "cubyz:tree/birch/mixed_forest_generator", .placeMode = .degradable, .chance = 0.1, }, diff --git a/assets/cubyz/biomes/forest/birch.zig.zon b/assets/cubyz/biomes/forest/birch.zig.zon index c7d7a083..f1c4febf 100644 --- a/assets/cubyz/biomes/forest/birch.zig.zon +++ b/assets/cubyz/biomes/forest/birch.zig.zon @@ -25,7 +25,7 @@ }, .{ .id = "cubyz:sbb", - .structure = "cubyz:tree/birch/birch_forest_generator", + .structure = "cubyz:tree/birch/forest_generator", .placeMode = .degradable, .chance = 0.2, }, diff --git a/assets/cubyz/sbb/tree/birch/1/base/base.blp b/assets/cubyz/sbb/tree/birch/1/base/base.blp deleted file mode 100644 index 1d61f924..00000000 Binary files a/assets/cubyz/sbb/tree/birch/1/base/base.blp and /dev/null differ diff --git a/assets/cubyz/sbb/tree/birch/1/root/1.zig.zon b/assets/cubyz/sbb/tree/birch/1/root/1.zig.zon deleted file mode 100644 index 13e13181..00000000 --- a/assets/cubyz/sbb/tree/birch/1/root/1.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/root/1", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/1/root/2.zig.zon b/assets/cubyz/sbb/tree/birch/1/root/2.zig.zon deleted file mode 100644 index 13e13181..00000000 --- a/assets/cubyz/sbb/tree/birch/1/root/2.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/root/1", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/1/root/3.zig.zon b/assets/cubyz/sbb/tree/birch/1/root/3.zig.zon deleted file mode 100644 index 13e13181..00000000 --- a/assets/cubyz/sbb/tree/birch/1/root/3.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/root/1", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/1/small_branch/1.zig.zon b/assets/cubyz/sbb/tree/birch/1/small_branch/1.zig.zon deleted file mode 100644 index f36a86bb..00000000 --- a/assets/cubyz/sbb/tree/birch/1/small_branch/1.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/small_branch/1", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/1/small_branch/2.zig.zon b/assets/cubyz/sbb/tree/birch/1/small_branch/2.zig.zon deleted file mode 100644 index 938e4b75..00000000 --- a/assets/cubyz/sbb/tree/birch/1/small_branch/2.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/small_branch/2", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/1/small_branch/3.zig.zon b/assets/cubyz/sbb/tree/birch/1/small_branch/3.zig.zon deleted file mode 100644 index e73c6369..00000000 --- a/assets/cubyz/sbb/tree/birch/1/small_branch/3.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/small_branch/3", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/1/stub/1.zig.zon b/assets/cubyz/sbb/tree/birch/1/stub/1.zig.zon deleted file mode 100644 index 5c3ebce8..00000000 --- a/assets/cubyz/sbb/tree/birch/1/stub/1.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/stub/1", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/1/stub/2.zig.zon b/assets/cubyz/sbb/tree/birch/1/stub/2.zig.zon deleted file mode 100644 index 9873bcd8..00000000 --- a/assets/cubyz/sbb/tree/birch/1/stub/2.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/stub/2", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/1/stub/3.zig.zon b/assets/cubyz/sbb/tree/birch/1/stub/3.zig.zon deleted file mode 100644 index 93fab06b..00000000 --- a/assets/cubyz/sbb/tree/birch/1/stub/3.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/stub/3", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/1/stub/4.zig.zon b/assets/cubyz/sbb/tree/birch/1/stub/4.zig.zon deleted file mode 100644 index 249944eb..00000000 --- a/assets/cubyz/sbb/tree/birch/1/stub/4.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/stub/4", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/1/top/1.zig.zon b/assets/cubyz/sbb/tree/birch/1/top/1.zig.zon deleted file mode 100644 index 97d5f6bb..00000000 --- a/assets/cubyz/sbb/tree/birch/1/top/1.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/top/1", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/1/top/2.zig.zon b/assets/cubyz/sbb/tree/birch/1/top/2.zig.zon deleted file mode 100644 index 8bdff392..00000000 --- a/assets/cubyz/sbb/tree/birch/1/top/2.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/birch/1/top/2", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/birch/birch_forest_generator.zig.zon b/assets/cubyz/sbb/tree/birch/birch_forest_generator.zig.zon deleted file mode 100644 index b9043a05..00000000 --- a/assets/cubyz/sbb/tree/birch/birch_forest_generator.zig.zon +++ /dev/null @@ -1,11 +0,0 @@ -.{ - .blueprint = "cubyz:generator", - .children = .{ - .crimson = .{ - .{.structure = "cubyz:tree/birch/1/tree/1", .chance = 0.2}, - .{.structure = "cubyz:tree/birch/1/tree/2", .chance = 0.2}, - .{.structure = "cubyz:tree/birch/1/tree/3", .chance = 0.2}, - .{.structure = "cubyz:tree/birch/1/tree/4", .chance = 0.4}, - }, - }, -} diff --git a/assets/cubyz/sbb/generator.blp b/assets/cubyz/sbb/tree/birch/forest_generator.blp similarity index 100% rename from assets/cubyz/sbb/generator.blp rename to assets/cubyz/sbb/tree/birch/forest_generator.blp diff --git a/assets/cubyz/sbb/tree/birch/forest_generator.zig.zon b/assets/cubyz/sbb/tree/birch/forest_generator.zig.zon index 0733a4ad..e90cc40a 100644 --- a/assets/cubyz/sbb/tree/birch/forest_generator.zig.zon +++ b/assets/cubyz/sbb/tree/birch/forest_generator.zig.zon @@ -1,11 +1,11 @@ .{ - .blueprint = "cubyz:generator", + .blueprint = "cubyz:tree/birch/forest_generator", .children = .{ .crimson = .{ - .{.structure = "cubyz:tree/birch/1/tree/1"}, - .{.structure = "cubyz:tree/birch/1/tree/2"}, - .{.structure = "cubyz:tree/birch/1/tree/3"}, - .{.structure = "cubyz:tree/birch/1/tree/4"}, + .{.structure = "cubyz:tree/birch/1/tree/1", .chance = 0.2}, + .{.structure = "cubyz:tree/birch/1/tree/2", .chance = 0.2}, + .{.structure = "cubyz:tree/birch/1/tree/3", .chance = 0.2}, + .{.structure = "cubyz:tree/birch/1/tree/4", .chance = 0.4}, }, }, } diff --git a/assets/cubyz/sbb/tree/birch/mixed_forest_generator.zig.zon b/assets/cubyz/sbb/tree/birch/mixed_forest_generator.zig.zon new file mode 100644 index 00000000..e8d86aa5 --- /dev/null +++ b/assets/cubyz/sbb/tree/birch/mixed_forest_generator.zig.zon @@ -0,0 +1,11 @@ +.{ + .blueprint = "cubyz:tree/birch/forest_generator", + .children = .{ + .crimson = .{ + .{.structure = "cubyz:tree/birch/1/tree/1"}, + .{.structure = "cubyz:tree/birch/1/tree/2"}, + .{.structure = "cubyz:tree/birch/1/tree/3"}, + .{.structure = "cubyz:tree/birch/1/tree/4"}, + }, + }, +} diff --git a/assets/cubyz/sbb/tree/oak/1/leaf/1.zig.zon b/assets/cubyz/sbb/tree/oak/1/leaf/1.zig.zon deleted file mode 100644 index cd25fdb0..00000000 --- a/assets/cubyz/sbb/tree/oak/1/leaf/1.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/leaf/1", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/leaf/2.zig.zon b/assets/cubyz/sbb/tree/oak/1/leaf/2.zig.zon deleted file mode 100644 index 402920ad..00000000 --- a/assets/cubyz/sbb/tree/oak/1/leaf/2.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/leaf/2", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/leaf/3.zig.zon b/assets/cubyz/sbb/tree/oak/1/leaf/3.zig.zon deleted file mode 100644 index df71bed7..00000000 --- a/assets/cubyz/sbb/tree/oak/1/leaf/3.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/leaf/3", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/root/1.zig.zon b/assets/cubyz/sbb/tree/oak/1/root/1.zig.zon deleted file mode 100644 index cec30951..00000000 --- a/assets/cubyz/sbb/tree/oak/1/root/1.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/root/1", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/root/2.zig.zon b/assets/cubyz/sbb/tree/oak/1/root/2.zig.zon deleted file mode 100644 index ea486593..00000000 --- a/assets/cubyz/sbb/tree/oak/1/root/2.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/root/2", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/root/3.zig.zon b/assets/cubyz/sbb/tree/oak/1/root/3.zig.zon deleted file mode 100644 index f6069da7..00000000 --- a/assets/cubyz/sbb/tree/oak/1/root/3.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/root/3", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/root/4.zig.zon b/assets/cubyz/sbb/tree/oak/1/root/4.zig.zon deleted file mode 100644 index f96a0db9..00000000 --- a/assets/cubyz/sbb/tree/oak/1/root/4.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/root/4", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/root/5.zig.zon b/assets/cubyz/sbb/tree/oak/1/root/5.zig.zon deleted file mode 100644 index 4656b684..00000000 --- a/assets/cubyz/sbb/tree/oak/1/root/5.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/root/5", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/root/6.zig.zon b/assets/cubyz/sbb/tree/oak/1/root/6.zig.zon deleted file mode 100644 index 8d52cb30..00000000 --- a/assets/cubyz/sbb/tree/oak/1/root/6.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/root/6", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/stub/1.zig.zon b/assets/cubyz/sbb/tree/oak/1/stub/1.zig.zon deleted file mode 100644 index 016fceb6..00000000 --- a/assets/cubyz/sbb/tree/oak/1/stub/1.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/stub/1", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/stub/2.zig.zon b/assets/cubyz/sbb/tree/oak/1/stub/2.zig.zon deleted file mode 100644 index 31c9241d..00000000 --- a/assets/cubyz/sbb/tree/oak/1/stub/2.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/stub/2", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/stub/3.zig.zon b/assets/cubyz/sbb/tree/oak/1/stub/3.zig.zon deleted file mode 100644 index dc5a5923..00000000 --- a/assets/cubyz/sbb/tree/oak/1/stub/3.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/stub/3", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/1/stub/4.zig.zon b/assets/cubyz/sbb/tree/oak/1/stub/4.zig.zon deleted file mode 100644 index 6b2c7ea2..00000000 --- a/assets/cubyz/sbb/tree/oak/1/stub/4.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .blueprint = "cubyz:tree/oak/1/stub/4", - .children = .{}, -} diff --git a/assets/cubyz/sbb/tree/oak/forest_generator.blp b/assets/cubyz/sbb/tree/oak/forest_generator.blp new file mode 100644 index 00000000..5876e6d3 Binary files /dev/null and b/assets/cubyz/sbb/tree/oak/forest_generator.blp differ diff --git a/assets/cubyz/sbb/tree/oak/forest_generator.zig.zon b/assets/cubyz/sbb/tree/oak/forest_generator.zig.zon index 6639f18b..86a5aab5 100644 --- a/assets/cubyz/sbb/tree/oak/forest_generator.zig.zon +++ b/assets/cubyz/sbb/tree/oak/forest_generator.zig.zon @@ -1,5 +1,5 @@ .{ - .blueprint = "cubyz:generator", + .blueprint = "cubyz:tree/oak/forest_generator", .children = .{ .crimson = .{ .{.structure = "cubyz:tree/oak/1/base/1", .chance = 0.5}, diff --git a/assets/cubyz/sbb/tree/oak/grassland_generator.zig.zon b/assets/cubyz/sbb/tree/oak/grassland_generator.zig.zon index 075c59ba..dcddb96f 100644 --- a/assets/cubyz/sbb/tree/oak/grassland_generator.zig.zon +++ b/assets/cubyz/sbb/tree/oak/grassland_generator.zig.zon @@ -1,5 +1,5 @@ .{ - .blueprint = "cubyz:generator", + .blueprint = "cubyz:tree/oak/forest_generator", .children = .{ .crimson = .{ .{.structure = "cubyz:tree/oak/1/base/1"}, diff --git a/src/server/terrain/structure_building_blocks.zig b/src/server/terrain/structure_building_blocks.zig index 649d8abc..01d98011 100644 --- a/src/server/terrain/structure_building_blocks.zig +++ b/src/server/terrain/structure_building_blocks.zig @@ -46,6 +46,10 @@ const BlueprintEntry = struct { pub inline fn pos(self: StructureBlock) Vec3i { return Vec3i{self.x, self.y, self.z}; } + + pub fn id(self: StructureBlock) []const u8 { + return childBlockStringId.items[self.index]; + } }; fn init(blueprint: Blueprint, stringId: []const u8) !BlueprintEntry { @@ -120,10 +124,14 @@ pub const StructureBuildingBlock = struct { std.log.err("['{s}'] Missing blueprint field.", .{stringId}); return error.MissingBlueprintIdField; }; - const blueprints = blueprintCache.get(blueprintId) orelse { + const blueprintsTemplate = blueprintCache.get(blueprintId) orelse { std.log.err("['{s}'] Could not find blueprint '{s}'.", .{stringId, blueprintId}); return error.MissingBlueprint; }; + + const blueprints = arenaAllocator.create([4]BlueprintEntry); + blueprints.* = blueprintsTemplate.*; + const self = StructureBuildingBlock{ .id = stringId, .children = arenaAllocator.alloc(AliasTable(Child), childBlockStringId.items.len), @@ -133,8 +141,54 @@ pub const StructureBuildingBlock = struct { for(childBlockStringId.items, 0..) |colorName, colorIndex| { self.children[colorIndex] = try initChildTableFromZon(stringId, colorName, colorIndex, childrenZon.getChild(colorName)); } + self.updateBlueprintChildLists(); return self; } + pub fn updateBlueprintChildLists(self: StructureBuildingBlock) void { + for(self.children, 0..) |child, index| found: { + if(child.items.len == 0) continue; + + for(self.blueprints[0].childBlocks) |blueprintChild| { + if(blueprintChild.index != index) continue; + break :found; + } + std.log.err("['{s}'] Blueprint doesn't contain child '{s}' but configuration for it was specified.", .{self.id, childBlockStringId.items[index]}); + } + for(self.blueprints, 0..) |*blueprint, index| { + var childBlocks: ListUnmanaged(BlueprintEntry.StructureBlock) = .{}; + defer childBlocks.deinit(main.stackAllocator); + + for(blueprint.childBlocks) |child| { + if(self.children[child.index].items.len == 0) { + if(index == 0) std.log.err("['{s}'] Missing child structure configuration for child '{s}'", .{self.id, child.id()}); + continue; + } + childBlocks.append(main.stackAllocator, child); + } + blueprint.childBlocks = arenaAllocator.dupe(BlueprintEntry.StructureBlock, childBlocks.items); + } + } + pub fn initInline(sbbId: []const u8) !StructureBuildingBlock { + const blueprintsTemplate = blueprintCache.get(sbbId) orelse { + std.log.err("['{s}'] Could not find blueprint '{s}'.", .{sbbId, sbbId}); + return error.MissingBlueprint; + }; + + const blueprints = arenaAllocator.create([4]BlueprintEntry); + blueprints.* = blueprintsTemplate.*; + for(blueprints, 0..) |*blueprint, index| { + if(index == 0) { + for(blueprint.childBlocks) |child| std.log.err("['{s}'] Missing child structure configuration for child '{s}'", .{sbbId, child.id()}); + } + blueprint.childBlocks = &.{}; + } + + return .{ + .id = sbbId, + .children = &.{}, + .blueprints = blueprints, + }; + } pub fn getBlueprint(self: StructureBuildingBlock, rotation: Degrees) *BlueprintEntry { return &self.blueprints[@intFromEnum(rotation)]; } @@ -150,8 +204,8 @@ fn initChildTableFromZon(parentId: []const u8, colorName: []const u8, colorIndex return .init(arenaAllocator, &.{}); } if(zon.array.items.len == 0) { - std.log.err("['{s}'->'{s}'] Empty children list.", .{parentId, colorName}); - return error.EmptyChildrenList; + std.log.err("['{s}'->'{s}'] Empty children list not allowed. Remove 'children' field or add child structure configurations.", .{parentId, colorName}); + return .init(arenaAllocator, &.{}); } const list = arenaAllocator.alloc(Child, zon.array.items.len); for(zon.array.items, 0..) |entry, childIndex| { @@ -193,16 +247,38 @@ pub fn registerSBB(structures: *Assets.ZonHashMap) !void { std.log.debug("Registered structure building block: '{s}'", .{entry.key_ptr.*}); } } + { + var keyIterator = blueprintCache.keyIterator(); + while(keyIterator.next()) |key_ptr| { + const blueprintId = key_ptr.*; + + if(structureCache.contains(blueprintId)) continue; + + const value = StructureBuildingBlock.initInline(blueprintId) catch |err| { + std.log.err("Could not register inline structure building block '{s}' ({s})", .{blueprintId, @errorName(err)}); + continue; + }; + const key = arenaAllocator.dupe(u8, blueprintId); + structureCache.put(arenaAllocator.allocator, key, value) catch unreachable; + std.log.debug("Registered inline structure building block: '{s}'", .{blueprintId}); + } + } { for(childrenToResolve.items) |entry| { const parent = structureCache.getPtr(entry.parentId).?; - const child = structureCache.getPtr(entry.structureId) orelse { - std.log.err("Could not find child structure '{s}' for child resolution.", .{entry.structureId}); + const child = getByStringId(entry.structureId) orelse { + std.log.err("Could not find child structure nor blueprint '{s}' for child resolution.", .{entry.structureId}); continue; }; + if(parent.children.len <= entry.colorIndex) { + main.utils.panicWithMessage("Error resolving child structure '{s}'->'{s}'->'{d}' to '{s}'", .{entry.parentId, entry.colorName, entry.childIndex, entry.structureId}); + } + + const childColor = parent.children[entry.colorIndex]; + std.log.debug("Resolved child structure '{s}'->'{s}'->'{d}' to '{s}'", .{entry.parentId, entry.colorName, entry.childIndex, entry.structureId}); - parent.children[entry.colorIndex].items[entry.childIndex].structure = child; + childColor.items[entry.childIndex].structure = child; } } } diff --git a/src/utils.zig b/src/utils.zig index 92c9e990..263a3885 100644 --- a/src/utils.zig +++ b/src/utils.zig @@ -2212,3 +2212,8 @@ test "NamedCallbacks registers functions" { try std.testing.expectEqual(null, testFunctions.getFunctionPointer("functionTest")); try std.testing.expectEqual(null, testFunctions.getFunctionPointer("wrongSignatureFunction")); } + +pub fn panicWithMessage(comptime fmt: []const u8, args: anytype) void { + const message = std.fmt.allocPrint(main.stackAllocator.allocator, fmt, args) catch unreachable; + @panic(message); +}