From 662ef94d0c5593e83dedfe422930364cf5853afc Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Mon, 25 Mar 2024 20:55:31 +0100 Subject: [PATCH] Add a terrain border between caves and the ocean floor. Fixes #282 Also fixes #281 by making water degradable --- assets/cubyz/blocks/water.json | 1 + src/server/terrain/CaveBiomeMap.zig | 20 ++++++++------ src/server/terrain/CaveMap.zig | 2 +- .../terrain/cavegen/SurfaceGenerator.zig | 26 ++++++++++++++----- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/assets/cubyz/blocks/water.json b/assets/cubyz/blocks/water.json index 132b41d2..6aed13d8 100644 --- a/assets/cubyz/blocks/water.json +++ b/assets/cubyz/blocks/water.json @@ -5,6 +5,7 @@ ], "selectable" : false, "solid" : false, + "degradable" : true, "transparent" : true, "hasBackFace" : true, "absorbedLight" : 0x090501, diff --git a/src/server/terrain/CaveBiomeMap.zig b/src/server/terrain/CaveBiomeMap.zig index 855c64aa..925bb0e9 100644 --- a/src/server/terrain/CaveBiomeMap.zig +++ b/src/server/terrain/CaveBiomeMap.zig @@ -301,6 +301,17 @@ pub const InterpolatableCaveBiomeMapView = struct { return self.surfaceFragments[index].getBiome(wx, wy); } + pub fn getSurfaceHeight(self: InterpolatableCaveBiomeMapView, wx: i32, wy: i32) f32 { + var index: u8 = 0; + if(wx - self.surfaceFragments[0].pos.wx >= MapFragment.mapSize*self.pos.voxelSize) { + index += 2; + } + if(wy - self.surfaceFragments[0].pos.wy >= MapFragment.mapSize*self.pos.voxelSize) { + index += 1; + } + return self.surfaceFragments[index].getHeight(wx, wy); + } + noinline fn _getBiome(self: InterpolatableCaveBiomeMapView, wx: i32, wy: i32, wz: i32, map: u1) *const Biome { var index: u8 = 0; if(wx - self.fragments[0].pos.wx >= CaveBiomeMapFragment.caveBiomeMapSize) { @@ -388,14 +399,7 @@ pub const CaveBiomeMapView = struct { } pub fn getSurfaceHeight(self: CaveBiomeMapView, wx: i32, wy: i32) f32 { - var index: u8 = 0; - if(wx - self.super.surfaceFragments[0].pos.wx >= MapFragment.mapSize*self.super.pos.voxelSize) { - index += 2; - } - if(wy - self.super.surfaceFragments[0].pos.wy >= MapFragment.mapSize*self.super.pos.voxelSize) { - index += 1; - } - return self.super.surfaceFragments[index].getHeight(wx, wy); + return self.super.getSurfaceHeight(wx, wy); } pub fn getBiome(self: CaveBiomeMapView, relX: i32, relY: i32, relZ: i32) *const Biome { diff --git a/src/server/terrain/CaveMap.zig b/src/server/terrain/CaveMap.zig index 904a9710..b3c2b840 100644 --- a/src/server/terrain/CaveMap.zig +++ b/src/server/terrain/CaveMap.zig @@ -32,7 +32,7 @@ pub const CaveMapFragment = struct { }, .voxelShift = @ctz(voxelSize), }; - @memset(&self.data, 0); + @memset(&self.data, std.math.maxInt(u64)); } fn getIndex(x: i32, y: i32) usize { diff --git a/src/server/terrain/cavegen/SurfaceGenerator.zig b/src/server/terrain/cavegen/SurfaceGenerator.zig index 7af2f89f..6b094215 100644 --- a/src/server/terrain/cavegen/SurfaceGenerator.zig +++ b/src/server/terrain/cavegen/SurfaceGenerator.zig @@ -8,6 +8,7 @@ const terrain = main.server.terrain; const CaveMapFragment = terrain.CaveMap.CaveMapFragment; const SurfaceMap = terrain.SurfaceMap; const MapFragment = SurfaceMap.MapFragment; +const InterpolatableCaveBiomeMapView = terrain.CaveBiomeMap.InterpolatableCaveBiomeMapView; const vec = main.vec; const Vec3d = vec.Vec3d; const Vec3f = vec.Vec3f; @@ -15,7 +16,7 @@ const Vec3i = vec.Vec3i; pub const id = "cubyz:surface"; -pub const priority = 1024; +pub const priority = 131072; pub const generatorSeed = 0x7658930674389; @@ -29,13 +30,26 @@ pub fn deinit() void { pub fn generate(map: *CaveMapFragment, worldSeed: u64) void { _ = worldSeed; - const mapFragment = SurfaceMap.getOrGenerateFragment(map.pos.wx, map.pos.wy, map.pos.voxelSize); - defer mapFragment.deinit(); + const width = CaveMapFragment.width*map.pos.voxelSize; + const biomeMap = InterpolatableCaveBiomeMapView.init(map.pos, width); + defer biomeMap.deinit(); var x: u31 = 0; - while(x < CaveMapFragment.width*map.pos.voxelSize) : (x += map.pos.voxelSize) { + while(x < width) : (x += map.pos.voxelSize) { var y: u31 = 0; - while(y < CaveMapFragment.width*map.pos.voxelSize) : (y += map.pos.voxelSize) { - map.addRange(x, y, 0, @as(i32, @intFromFloat(mapFragment.getHeight(map.pos.wx + x, map.pos.wy + y))) - map.pos.wz); + while(y < width) : (y += map.pos.voxelSize) { + const height = biomeMap.getSurfaceHeight(map.pos.wx + x, map.pos.wy + y); + const smallestHeight: i32 = @intFromFloat(@floor(@min( + biomeMap.getSurfaceHeight(map.pos.wx + x + 1, map.pos.wy + y), + biomeMap.getSurfaceHeight(map.pos.wx + x, map.pos.wy + y + 1), + biomeMap.getSurfaceHeight(map.pos.wx + x - 1, map.pos.wy + y), + biomeMap.getSurfaceHeight(map.pos.wx + x, map.pos.wy + y - 1), + height, + ) - 0.5)); + const relativeHeight: i32 = @as(i32, @intFromFloat(height)) - map.pos.wz; + map.removeRange(x, y, relativeHeight, CaveMapFragment.height*map.pos.voxelSize); + if(smallestHeight < 1) { // Seal off caves that intersect the ocean floor. + map.addRange(x, y, smallestHeight -% 1 -% map.pos.wz, relativeHeight); + } } } }