mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00

I also removed the unused BufferFallbackAllocator which was from a time where I was still experimenting with different allocators.
174 lines
6.2 KiB
Zig
174 lines
6.2 KiB
Zig
const std = @import("std");
|
|
|
|
const main = @import("root");
|
|
const ZonElement = main.ZonElement;
|
|
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
|
|
|
|
pub const biomes = @import("biomes.zig");
|
|
pub const noise = @import("noise/noise.zig");
|
|
const Biome = biomes.Biome;
|
|
|
|
pub const ClimateMap = @import("ClimateMap.zig");
|
|
|
|
pub const SurfaceMap = @import("SurfaceMap.zig");
|
|
|
|
pub const LightMap = @import("LightMap.zig");
|
|
|
|
pub const CaveBiomeMap = @import("CaveBiomeMap.zig");
|
|
|
|
pub const CaveMap = @import("CaveMap.zig");
|
|
|
|
pub const StructureMap = @import("StructureMap.zig");
|
|
|
|
/// A generator for setting the actual Blocks in each Chunk.
|
|
pub const BlockGenerator = struct {
|
|
init: *const fn(parameters: ZonElement) void,
|
|
deinit: *const fn() void,
|
|
generate: *const fn(seed: u64, chunk: *main.chunk.ServerChunk, caveMap: CaveMap.CaveMapView, biomeMap: CaveBiomeMap.CaveBiomeMapView) void,
|
|
/// Used to prioritize certain generators over others.
|
|
priority: i32,
|
|
/// To avoid duplicate seeds in similar generation algorithms, the SurfaceGenerator xors the world-seed with the generator specific seed.
|
|
generatorSeed: u64,
|
|
|
|
var generatorRegistry: std.StringHashMapUnmanaged(BlockGenerator) = .{};
|
|
|
|
pub fn registerGenerator(comptime GeneratorType: type) void {
|
|
const self = BlockGenerator{
|
|
.init = &GeneratorType.init,
|
|
.deinit = &GeneratorType.deinit,
|
|
.generate = &GeneratorType.generate,
|
|
.priority = GeneratorType.priority,
|
|
.generatorSeed = GeneratorType.generatorSeed,
|
|
};
|
|
generatorRegistry.put(main.globalAllocator.allocator, GeneratorType.id, self) catch unreachable;
|
|
}
|
|
|
|
fn getAndInitGenerators(allocator: NeverFailingAllocator, settings: ZonElement) []BlockGenerator {
|
|
const list = allocator.alloc(BlockGenerator, generatorRegistry.size);
|
|
var iterator = generatorRegistry.iterator();
|
|
var i: usize = 0;
|
|
while(iterator.next()) |generator| {
|
|
list[i] = generator.value_ptr.*;
|
|
list[i].init(settings.getChild(generator.key_ptr.*));
|
|
i += 1;
|
|
}
|
|
const lessThan = struct {
|
|
fn lessThan(_: void, lhs: BlockGenerator, rhs: BlockGenerator) bool {
|
|
return lhs.priority < rhs.priority;
|
|
}
|
|
}.lessThan;
|
|
std.sort.insertion(BlockGenerator, list, {}, lessThan);
|
|
return list;
|
|
}
|
|
};
|
|
|
|
/// Lists all the Generators and Biomes that should be used for a given world.
|
|
/// TODO: Generator/Biome blackslisting (from the world creation menu).
|
|
/// TODO: Generator settings (from the world creation menu).
|
|
pub const TerrainGenerationProfile = struct {
|
|
mapFragmentGenerator: SurfaceMap.MapGenerator = undefined,
|
|
climateGenerator: ClimateMap.ClimateMapGenerator = undefined,
|
|
caveBiomeGenerators: []CaveBiomeMap.CaveBiomeGenerator = undefined,
|
|
caveGenerators: []CaveMap.CaveGenerator = undefined,
|
|
structureMapGenerators: []StructureMap.StructureMapGenerator = undefined,
|
|
generators: []BlockGenerator = undefined,
|
|
climateWavelengths: [5]f32 = undefined,
|
|
seed: u64,
|
|
|
|
pub fn init(settings: ZonElement, seed: u64) !TerrainGenerationProfile {
|
|
var self = TerrainGenerationProfile{
|
|
.seed = seed,
|
|
};
|
|
var generator = settings.getChild("mapGenerator");
|
|
self.mapFragmentGenerator = try SurfaceMap.MapGenerator.getGeneratorById(generator.get([]const u8, "id", "cubyz:mapgen_v1"));
|
|
self.mapFragmentGenerator.init(generator);
|
|
|
|
generator = settings.getChild("climateGenerator");
|
|
self.climateGenerator = try ClimateMap.ClimateMapGenerator.getGeneratorById(generator.get([]const u8, "id", "cubyz:polar_circles"));
|
|
self.climateGenerator.init(generator);
|
|
|
|
generator = settings.getChild("caveBiomeGenerators");
|
|
self.caveBiomeGenerators = CaveBiomeMap.CaveBiomeGenerator.getAndInitGenerators(main.globalAllocator, generator);
|
|
|
|
generator = settings.getChild("caveGenerators");
|
|
self.caveGenerators = CaveMap.CaveGenerator.getAndInitGenerators(main.globalAllocator, generator);
|
|
|
|
generator = settings.getChild("structureMapGenerators");
|
|
self.structureMapGenerators = StructureMap.StructureMapGenerator.getAndInitGenerators(main.globalAllocator, generator);
|
|
|
|
generator = settings.getChild("generators");
|
|
self.generators = BlockGenerator.getAndInitGenerators(main.globalAllocator, generator);
|
|
|
|
const climateWavelengths = settings.getChild("climateWavelengths");
|
|
self.climateWavelengths[0] = climateWavelengths.get(f32, "hot_cold", 2400);
|
|
self.climateWavelengths[1] = climateWavelengths.get(f32, "land_ocean", 3200);
|
|
self.climateWavelengths[2] = climateWavelengths.get(f32, "wet_dry", 2400);
|
|
self.climateWavelengths[3] = climateWavelengths.get(f32, "vegetation", 2400);
|
|
self.climateWavelengths[4] = climateWavelengths.get(f32, "mountain", 500);
|
|
|
|
return self;
|
|
}
|
|
|
|
pub fn deinit(self: TerrainGenerationProfile) void {
|
|
self.mapFragmentGenerator.deinit();
|
|
self.climateGenerator.deinit();
|
|
for(self.caveBiomeGenerators) |generator| {
|
|
generator.deinit();
|
|
}
|
|
main.globalAllocator.free(self.caveBiomeGenerators);
|
|
for(self.caveGenerators) |generator| {
|
|
generator.deinit();
|
|
}
|
|
main.globalAllocator.free(self.caveGenerators);
|
|
for(self.structureMapGenerators) |generator| {
|
|
generator.deinit();
|
|
}
|
|
main.globalAllocator.free(self.structureMapGenerators);
|
|
for(self.generators) |generator| {
|
|
generator.deinit();
|
|
}
|
|
main.globalAllocator.free(self.generators);
|
|
}
|
|
};
|
|
|
|
pub fn initGenerators() void {
|
|
SurfaceMap.initGenerators();
|
|
ClimateMap.initGenerators();
|
|
CaveBiomeMap.initGenerators();
|
|
CaveMap.initGenerators();
|
|
StructureMap.initGenerators();
|
|
const list = @import("chunkgen/_list.zig");
|
|
inline for(@typeInfo(list).@"struct".decls) |decl| {
|
|
BlockGenerator.registerGenerator(@field(list, decl.name));
|
|
}
|
|
const t1 = std.time.milliTimestamp();
|
|
noise.BlueNoise.load();
|
|
std.log.info("Blue noise took {} ms to load", .{std.time.milliTimestamp() -% t1});
|
|
}
|
|
|
|
pub fn deinitGenerators() void {
|
|
SurfaceMap.deinitGenerators();
|
|
ClimateMap.deinitGenerators();
|
|
CaveBiomeMap.deinitGenerators();
|
|
CaveMap.deinitGenerators();
|
|
StructureMap.deinitGenerators();
|
|
BlockGenerator.generatorRegistry.clearAndFree(main.globalAllocator.allocator);
|
|
}
|
|
|
|
pub fn init(profile: TerrainGenerationProfile) void {
|
|
CaveBiomeMap.init(profile);
|
|
CaveMap.init(profile);
|
|
StructureMap.init(profile);
|
|
ClimateMap.init(profile);
|
|
SurfaceMap.init(profile);
|
|
}
|
|
|
|
pub fn deinit() void {
|
|
CaveBiomeMap.deinit();
|
|
CaveMap.deinit();
|
|
StructureMap.deinit();
|
|
ClimateMap.deinit();
|
|
SurfaceMap.deinit();
|
|
LightMap.deinit();
|
|
}
|