diff --git a/Application/Biome.cpp b/Application/Biome.cpp new file mode 100644 index 0000000..8934e28 --- /dev/null +++ b/Application/Biome.cpp @@ -0,0 +1,64 @@ + +#include +#include "Block.h" +#include "Chunk.h" +#include "Maths/Vec3.h" +#include + +Biome::Biome(std::uint32_t filler, std::uint32_t water_level, std::map>> blocks): filler(filler), water_level(water_level), c_blockmap(blocks) +{ + for (const auto& [height, BlockPlacement] : blocks) + { + const auto& [PlacementType, Blocks] = BlockPlacement; + if (PlacementType == BlockPlacementType::PseudoRandom && Blocks.size() < 2) + Scop::FatalError("A biome have a Multiple block placement but less than 2 blocks was given"); + } +} + +const std::array Biome::GetBiomeBlocks(const std::uint32_t height, Scop::Vec2i pos) +{ + std::array data; + + auto it = c_blockmap.lower_bound(height); + + if (it == c_blockmap.end()) + Scop::FatalError("Biome declaration does not have a value for a certain generated height"); + for(std::uint32_t y = 0; y < std::min(height, CHUNK_SIZE.y); y++) + { + if(y > std::min(height, CHUNK_SIZE.y) - 2) + { + data[y] = static_cast(BlockType::Dirt); + continue; + const auto& [placementType, blockTypes] = it->second; + switch (static_cast(placementType)) + { + case(static_cast(BlockPlacementType::Simple)): + { + data[y] = static_cast(blockTypes.front()); + break; + } + case(static_cast(BlockPlacementType::PseudoRandom)): + { + float weight = sin(2 * (pos.x * pos.y)) + sin(Scop::Pi() * (pos.x * pos.y)); + if (weight > 0.0f) + data[y] = static_cast(blockTypes.at(0)); + else + data[y] = static_cast(blockTypes.at(1)); + break; + } + default: + data[y] = static_cast(BlockType::Stone); + } + } + else + { + data[y] = filler; + } + } + for(std::uint32_t y = 0; y < water_level; y++) + { + if(data[y] == static_cast(BlockType::Air)) + data[y] = static_cast(BlockType::Water); + } + return data; +} diff --git a/Application/Biome.h b/Application/Biome.h new file mode 100644 index 0000000..95dcf3c --- /dev/null +++ b/Application/Biome.h @@ -0,0 +1,30 @@ +#ifndef BIOME_H +#define BIOME_H + +#include +#include "Chunk.h" +#include "Maths/Vec2.h" +#include +#include +#include + +enum class BlockPlacementType : std::uint8_t +{ + Simple = 0, + PseudoRandom, +}; + +class Biome +{ + + public: + Biome(std::uint32_t filler, std::uint32_t water_level, std::map>> blocks); + ~Biome() = default; + const std::array GetBiomeBlocks(const std::uint32_t height, Scop::Vec2i pos); + private: + const std::uint32_t filler; + const std::uint32_t water_level; + const std::map>> c_blockmap; +}; + +#endif diff --git a/Application/BiomeCollection.cpp b/Application/BiomeCollection.cpp new file mode 100644 index 0000000..b351f0c --- /dev/null +++ b/Application/BiomeCollection.cpp @@ -0,0 +1,6 @@ +#include + +const std::array BiomeCollection::GetBiomeBlocks(std::string biome, std::uint32_t height, Scop::Vec2i pos) const +{ + return m_collection.at(biome)->GetBiomeBlocks(height, pos); +} diff --git a/Application/BiomeCollection.h b/Application/BiomeCollection.h new file mode 100644 index 0000000..a5e4b3f --- /dev/null +++ b/Application/BiomeCollection.h @@ -0,0 +1,33 @@ + +#ifndef BIOMECOLLECTION_H +#define BIOMECOLLECTION_H + +#include +#include +#include +#include "Biome.h" +#include "Chunk.h" +#include "Maths/Vec2.h" + +class BiomeCollection +{ + public: + inline BiomeCollection() + { + m_collection.emplace("grassland", std::make_unique(Biome( + static_cast(BlockType::Stone), + 0, + { + {20, {BlockPlacementType::Simple, {BlockType::Sand}}}, + {255, {BlockPlacementType::Simple, {BlockType::Snow}}} + }) + )); + }; + const std::array GetBiomeBlocks(std::string biome, std::uint32_t height, Scop::Vec2i pos) const; + ~BiomeCollection() = default; + + private: + std::unordered_map> m_collection; +}; + +#endif