|
|
|
using System;
|
|
|
|
using gaemstone.ECS;
|
|
|
|
using gaemstone.Utility;
|
|
|
|
using static gaemstone.Bloxel.Components.CoreComponents;
|
|
|
|
using static gaemstone.Bloxel.Constants;
|
|
|
|
|
|
|
|
namespace gaemstone.Bloxel.Systems;
|
|
|
|
|
|
|
|
[Module]
|
|
|
|
[DependsOn<gaemstone.Bloxel.Components.CoreComponents>]
|
|
|
|
public class BasicWorldGenerator
|
|
|
|
{
|
|
|
|
private readonly FastNoiseLite _noise;
|
|
|
|
private readonly Random _rnd = new();
|
|
|
|
|
|
|
|
public BasicWorldGenerator()
|
|
|
|
{
|
|
|
|
_noise = new(new Random().Next());
|
|
|
|
_noise.SetNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
|
|
|
_noise.SetFractalType(FastNoiseLite.FractalType.Ridged);
|
|
|
|
_noise.SetFractalOctaves(4);
|
|
|
|
_noise.SetFractalGain(0.6f);
|
|
|
|
}
|
|
|
|
|
|
|
|
[Symbol, Tag]
|
|
|
|
public struct HasBasicWorldGeneration { }
|
|
|
|
|
|
|
|
[System]
|
|
|
|
public void Populate(World world, EntityRef entity,
|
|
|
|
in Chunk chunk, ChunkStoreBlocks blocks,
|
|
|
|
[Not] HasBasicWorldGeneration _)
|
|
|
|
{
|
|
|
|
var stone = world.LookupByPathOrThrow("Stone");
|
|
|
|
var dirt = world.LookupByPathOrThrow("Dirt");
|
|
|
|
var grass = world.LookupByPathOrThrow("Grass");
|
|
|
|
for (var localX = 0; localX < ChunkLength; localX++)
|
|
|
|
for (var localY = 0; localY < ChunkLength; localY++)
|
|
|
|
for (var localZ = 0; localZ < ChunkLength; localZ++) {
|
|
|
|
var globalX = chunk.Position.X << ChunkBitShift | localX;
|
|
|
|
var globalY = chunk.Position.Y << ChunkBitShift | localY;
|
|
|
|
var globalZ = chunk.Position.Z << ChunkBitShift | localZ;
|
|
|
|
var bias = Math.Clamp((globalY / 32.0f + 1.0f), 0.0f, 1.0f);
|
|
|
|
if (_noise.GetNoise(globalX, globalY, globalZ) > bias)
|
|
|
|
blocks[localX, localY, localZ] = _rnd.Pick(stone, dirt, grass);
|
|
|
|
}
|
|
|
|
entity.Add<HasBasicWorldGeneration>();
|
|
|
|
}
|
|
|
|
}
|