mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 03:06:55 -04:00
Make sure sub biomes never extent beyond their parent biome.
Also allow subbiomes to extent further if their parent radius is not precisely known. fixes #917 fixes #1027
This commit is contained in:
parent
e7ecd161ce
commit
62f6c5a106
@ -265,11 +265,25 @@ const GenerationStructure = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn drawCircleOnTheMap(map: *ClimateMapFragment, biome: *const Biome, biomeRadius: f32, wx: i32, wy: i32, width: u31, height: u31, pos: Vec2i) void {
|
||||
fn drawCircleOnTheMap(map: *ClimateMapFragment, biome: *const Biome, biomeRadius: f32, wx: i32, wy: i32, width: u31, height: u31, pos: Vec2i, comptime skipMismatched: bool, parentBiome: *const Biome) !void {
|
||||
const relPos = @as(Vec2f, @floatFromInt(pos -% Vec2i{wx, wy}))/@as(Vec2f, @splat(terrain.SurfaceMap.MapFragment.biomeSize));
|
||||
const relRadius = biomeRadius/terrain.SurfaceMap.MapFragment.biomeSize;
|
||||
const min = @floor(@max(Vec2f{0, 0}, relPos - @as(Vec2f, @splat(relRadius))));
|
||||
const max = @ceil(@min(@as(Vec2f, @floatFromInt(Vec2i{width, height}))/@as(Vec2f, @splat(terrain.SurfaceMap.MapFragment.biomeSize)), relPos + @as(Vec2f, @splat(relRadius))));
|
||||
if(skipMismatched) {
|
||||
var x: f32 = min[0];
|
||||
while(x < max[0]) : (x += 1) {
|
||||
var y: f32 = min[1];
|
||||
while(y < max[1]) : (y += 1) {
|
||||
const distSquare = vec.lengthSquare(Vec2f{x, y} - relPos);
|
||||
if(distSquare < relRadius*relRadius) {
|
||||
if(map.map[@intFromFloat(x)][@intFromFloat(y)].biome != parentBiome) {
|
||||
return error.biomeMismatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var x: f32 = min[0];
|
||||
while(x < max[0]) : (x += 1) {
|
||||
var y: f32 = min[1];
|
||||
@ -290,7 +304,7 @@ const GenerationStructure = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn addSubBiomesOf(biome: BiomePoint, map: *ClimateMapFragment, extraBiomes: *main.List(BiomePoint), wx: i32, wy: i32, width: u31, height: u31, worldSeed: u64) void {
|
||||
fn addSubBiomesOf(biome: BiomePoint, map: *ClimateMapFragment, extraBiomes: *main.List(BiomePoint), wx: i32, wy: i32, width: u31, height: u31, worldSeed: u64, comptime radius: enum{known, unknown}) void {
|
||||
var seed = random.initSeed2D(worldSeed, @bitCast(biome.pos));
|
||||
var biomeCount: f32 = undefined;
|
||||
if(biome.biome.subBiomeTotalChance > biome.biome.maxSubBiomeCount) {
|
||||
@ -302,22 +316,31 @@ const GenerationStructure = struct {
|
||||
}
|
||||
biomeCount = @min(biomeCount, biome.biome.maxSubBiomeCount);
|
||||
var i: f32 = 0;
|
||||
var fails: usize = 0;
|
||||
while(i < biomeCount) : (i += 1) {
|
||||
if(biomeCount - i < random.nextFloat(&seed)) break;
|
||||
const subBiome = biome.biome.subBiomes.sample(&seed).*;
|
||||
const radius = subBiome.radius + subBiome.radiusVariation*random.nextFloatSigned(&seed);
|
||||
var maxCenterOffset: f32 = biome.radius - radius - 32;
|
||||
const subRadius = subBiome.radius + subBiome.radiusVariation*random.nextFloatSigned(&seed);
|
||||
var maxCenterOffset: f32 = biome.radius - subRadius;
|
||||
if(radius == .unknown) {
|
||||
maxCenterOffset += biome.radius/2;
|
||||
}
|
||||
if(maxCenterOffset < 0) {
|
||||
maxCenterOffset = 0;
|
||||
}
|
||||
const point = biome.pos +% @as(Vec2i, @intFromFloat(random.nextPointInUnitCircle(&seed)*@as(Vec2f, @splat(maxCenterOffset))));
|
||||
drawCircleOnTheMap(map, subBiome, radius, wx, wy, width, height, point);
|
||||
drawCircleOnTheMap(map, subBiome, subRadius, wx, wy, width, height, point, radius == .unknown, biome.biome) catch if(radius == .unknown) {
|
||||
fails += 1;
|
||||
if(fails < @as(usize, @intFromFloat(biomeCount))) {
|
||||
i -= 1;
|
||||
}
|
||||
};
|
||||
extraBiomes.append(.{
|
||||
.biome = subBiome,
|
||||
.pos = point,
|
||||
.height = random.nextFloat(&seed)*@as(f32, @floatFromInt(subBiome.maxHeight - subBiome.minHeight)) + @as(f32, @floatFromInt(subBiome.minHeight)),
|
||||
.weight = 1.0/(std.math.pi*radius*radius),
|
||||
.radius = radius,
|
||||
.weight = 1.0/(std.math.pi*subRadius*subRadius),
|
||||
.radius = subRadius,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -390,12 +413,12 @@ const GenerationStructure = struct {
|
||||
defer extraBiomes.deinit();
|
||||
for(self.chunks.mem) |chunk| {
|
||||
for(chunk.biomesSortedByX) |biome| {
|
||||
addSubBiomesOf(biome, map, &extraBiomes, map.pos.wx, map.pos.wy, width, height, worldSeed);
|
||||
addSubBiomesOf(biome, map, &extraBiomes, map.pos.wx, map.pos.wy, width, height, worldSeed, .unknown);
|
||||
}
|
||||
}
|
||||
// Add some sub-sub(-sub)*-biomes
|
||||
while(extraBiomes.popOrNull()) |biomePoint| {
|
||||
addSubBiomesOf(biomePoint, map, &extraBiomes, map.pos.wx, map.pos.wy, width, height, worldSeed);
|
||||
addSubBiomesOf(biomePoint, map, &extraBiomes, map.pos.wx, map.pos.wy, width, height, worldSeed, .known);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user