Add a priority system for biome structures.

This solves a big part of the degradability problem and allows removing non_degradable_oak_leaves.
This commit is contained in:
IntegratedQuantum 2024-12-02 21:13:56 +01:00
parent 1455605387
commit 4ca28668f1
5 changed files with 23 additions and 15 deletions

View File

@ -21,7 +21,7 @@
.structures = .{ .structures = .{
.{ .{
.id = "cubyz:simple_tree", .id = "cubyz:simple_tree",
.leaves = "cubyz:non_degradable_oak_leaves", .leaves = "cubyz:oak_leaves",
.log = "cubyz:oak_log", .log = "cubyz:oak_log",
.top = "cubyz:oak_top", .top = "cubyz:oak_top",
.chance = 0.48, .chance = 0.48,
@ -40,6 +40,7 @@
.height_variation = 0, .height_variation = 0,
.leafRadius = 16, .leafRadius = 16,
.leafRadius_variation = 3, .leafRadius_variation = 3,
.priority = 0.1,
}, },
.{ .{
.id = "cubyz:simple_tree", .id = "cubyz:simple_tree",
@ -52,6 +53,7 @@
.height_variation = 0, .height_variation = 0,
.leafRadius = 16, .leafRadius = 16,
.leafRadius_variation = 3, .leafRadius_variation = 3,
.priority = 0.1,
}, },
.{ .{
.id = "cubyz:simple_tree", .id = "cubyz:simple_tree",
@ -64,6 +66,7 @@
.height_variation = 0, .height_variation = 0,
.leafRadius = 16, .leafRadius = 16,
.leafRadius_variation = 3, .leafRadius_variation = 3,
.priority = 0.1,
}, },
.{ .{
.id = "cubyz:simple_tree", .id = "cubyz:simple_tree",
@ -76,6 +79,7 @@
.height_variation = 0, .height_variation = 0,
.leafRadius = 16, .leafRadius = 16,
.leafRadius_variation = 3, .leafRadius_variation = 3,
.priority = 0.1,
}, },
.{ .{
.id = "cubyz:simple_tree", .id = "cubyz:simple_tree",
@ -88,6 +92,7 @@
.height_variation = 0, .height_variation = 0,
.leafRadius = 16, .leafRadius = 16,
.leafRadius_variation = 3, .leafRadius_variation = 3,
.priority = 0.1,
}, },
.{ .{
.id = "cubyz:simple_tree", .id = "cubyz:simple_tree",
@ -100,6 +105,7 @@
.height_variation = 0, .height_variation = 0,
.leafRadius = 16, .leafRadius = 16,
.leafRadius_variation = 3, .leafRadius_variation = 3,
.priority = 0.1,
}, },
}, },
} }

View File

@ -1,14 +0,0 @@
.{
.class = .leaf,
.hasItem = false,
.hardness = 0.4,
.drops = .{
"cubyz:oak_leaves",
"0.1 cubyz:apple",
},
.degradable = false,
.alwaysViewThrough = true,
.absorbedLight = 0x121012,
.model = "cubyz:cube",
.texture = "cubyz:oak_leaves",
}

View File

@ -16,10 +16,15 @@ const TerrainGenerationProfile = terrain.TerrainGenerationProfile;
pub const Structure = struct { pub const Structure = struct {
generateFn: *const fn(self: *const anyopaque, chunk: *ServerChunk, caveMap: terrain.CaveMap.CaveMapView) void, generateFn: *const fn(self: *const anyopaque, chunk: *ServerChunk, caveMap: terrain.CaveMap.CaveMapView) void,
data: *const anyopaque, data: *const anyopaque,
priority: f32,
pub fn generate(self: Structure, chunk: *ServerChunk, caveMap: terrain.CaveMap.CaveMapView) void { pub fn generate(self: Structure, chunk: *ServerChunk, caveMap: terrain.CaveMap.CaveMapView) void {
self.generateFn(self.data, chunk, caveMap); self.generateFn(self.data, chunk, caveMap);
} }
fn lessThan(_: void, lhs: Structure, rhs: Structure) bool {
return lhs.priority < rhs.priority;
}
}; };
pub const StructureMapFragment = struct { pub const StructureMapFragment = struct {
@ -54,6 +59,12 @@ pub const StructureMapFragment = struct {
main.globalAllocator.destroy(self); main.globalAllocator.destroy(self);
} }
fn finishGeneration(self: *StructureMapFragment) void {
for(&self.data) |list| {
std.sort.insertion(Structure, list.items, {}, Structure.lessThan);
}
}
fn getIndex(self: *const StructureMapFragment, x: i32, y: i32, z: i32) usize { fn getIndex(self: *const StructureMapFragment, x: i32, y: i32, z: i32) usize {
std.debug.assert(x >= 0 and x < size*self.pos.voxelSize and y >= 0 and y < size*self.pos.voxelSize and z >= 0 and z < size*self.pos.voxelSize); // Coordinates out of range. std.debug.assert(x >= 0 and x < size*self.pos.voxelSize and y >= 0 and y < size*self.pos.voxelSize and z >= 0 and z < size*self.pos.voxelSize); // Coordinates out of range.
return @intCast(((x >> main.chunk.chunkShift+self.voxelShift)*chunkedSize + (y >> main.chunk.chunkShift+self.voxelShift))*chunkedSize + (z >> main.chunk.chunkShift+self.voxelShift)); return @intCast(((x >> main.chunk.chunkShift+self.voxelShift)*chunkedSize + (y >> main.chunk.chunkShift+self.voxelShift))*chunkedSize + (z >> main.chunk.chunkShift+self.voxelShift));
@ -151,6 +162,7 @@ fn cacheInit(pos: ChunkPosition) *StructureMapFragment {
for(profile.structureMapGenerators) |generator| { for(profile.structureMapGenerators) |generator| {
generator.generate(mapFragment, profile.seed ^ generator.generatorSeed); generator.generate(mapFragment, profile.seed ^ generator.generatorSeed);
} }
mapFragment.finishGeneration();
_ = @atomicRmw(u16, &mapFragment.refCount.raw, .Add, 1, .monotonic); _ = @atomicRmw(u16, &mapFragment.refCount.raw, .Add, 1, .monotonic);
return mapFragment; return mapFragment;
} }

View File

@ -28,6 +28,7 @@ pub const SimpleStructureModel = struct { // MARK: SimpleStructureModel
vtable: VTable, vtable: VTable,
data: *anyopaque, data: *anyopaque,
chance: f32, chance: f32,
priority: f32,
generationMode: GenerationMode, generationMode: GenerationMode,
pub fn initModel(parameters: ZonElement) ?SimpleStructureModel { pub fn initModel(parameters: ZonElement) ?SimpleStructureModel {
@ -40,6 +41,7 @@ pub const SimpleStructureModel = struct { // MARK: SimpleStructureModel
.vtable = vtable, .vtable = vtable,
.data = vtable.loadModel(arena.allocator(), parameters), .data = vtable.loadModel(arena.allocator(), parameters),
.chance = parameters.get(f32, "chance", 0.1), .chance = parameters.get(f32, "chance", 0.1),
.priority = parameters.get(f32, "priority", 1),
.generationMode = std.meta.stringToEnum(GenerationMode, parameters.get([]const u8, "generationMode", "")) orelse vtable.generationMode, .generationMode = std.meta.stringToEnum(GenerationMode, parameters.get([]const u8, "generationMode", "")) orelse vtable.generationMode,
}; };
} }

View File

@ -64,6 +64,7 @@ pub fn generate(map: *StructureMapFragment, worldSeed: u64) void {
map.addStructure(.{ map.addStructure(.{
.data = @ptrCast(data), .data = @ptrCast(data),
.generateFn = &SimpleStructure.generate, .generateFn = &SimpleStructure.generate,
.priority = model.priority,
}, .{px -% margin, py -% margin, relZ -% margin -% 15}, .{px +% margin, py +% margin, relZ +% margin +% 15}); }, .{px -% margin, py -% margin, relZ -% margin -% 15}, .{px +% margin, py +% margin, relZ +% margin +% 15});
break; break;
} else { } else {
@ -102,6 +103,7 @@ pub fn generate(map: *StructureMapFragment, worldSeed: u64) void {
map.addStructure(.{ map.addStructure(.{
.data = @ptrCast(data), .data = @ptrCast(data),
.generateFn = &SimpleStructure.generate, .generateFn = &SimpleStructure.generate,
.priority = model.priority,
}, .{px -% margin, py -% margin, relZ -% margin -% 15}, .{px +% margin, py +% margin, relZ +% margin +% 15}); }, .{px -% margin, py -% margin, relZ -% margin -% 15}, .{px +% margin, py +% margin, relZ +% margin +% 15});
break; break;
} else { } else {