diff --git a/CMakeLists.txt b/CMakeLists.txt index cbfc917..6b95893 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,7 @@ add_executable(${PROJECT_NAME} src/gameplay/river_path.cpp src/block.cpp src/gameplay/vertex_data.cpp + src/gameplay/builders/ocean_builder.cpp ) if(CMAKE_BUILD_TYPE STREQUAL "Debug") diff --git a/include/Cubed/gameplay/biome.hpp b/include/Cubed/gameplay/biome.hpp index 72ac7f9..f4af4ed 100644 --- a/include/Cubed/gameplay/biome.hpp +++ b/include/Cubed/gameplay/biome.hpp @@ -15,6 +15,7 @@ enum class BiomeType { MOUNTAIN, RIVER, SNOWY_PLAIN, + OCEAN, NONE }; diff --git a/include/Cubed/gameplay/builders/biome_builder.hpp b/include/Cubed/gameplay/builders/biome_builder.hpp index a3270fe..5597fd9 100644 --- a/include/Cubed/gameplay/builders/biome_builder.hpp +++ b/include/Cubed/gameplay/builders/biome_builder.hpp @@ -13,5 +13,6 @@ public: protected: void build_bottom(); void place_grass(); + void ocean_water_build(); }; } // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/builders/ocean_builder.hpp b/include/Cubed/gameplay/builders/ocean_builder.hpp new file mode 100644 index 0000000..3404e6e --- /dev/null +++ b/include/Cubed/gameplay/builders/ocean_builder.hpp @@ -0,0 +1,23 @@ +#pragma once + +#pragma once + +#include "Cubed/gameplay/builders/biome_builder.hpp" +namespace Cubed { + +class ChunkGenerator; + +class OceanBuilder : public BiomeBuilder { +public: + OceanBuilder(ChunkGenerator& chunk_generator); + void build_biome() override; + ChunkGenerator& get_chunk_generator() override; + void build_vegetation() override; + +private: + ChunkGenerator& m_chunk_generator; + + void build_blocks(); +}; + +} // namespace Cubed diff --git a/src/gameplay/biome.cpp b/src/gameplay/biome.cpp index 39fdeb9..76acaaa 100644 --- a/src/gameplay/biome.cpp +++ b/src/gameplay/biome.cpp @@ -62,6 +62,10 @@ std::string get_biome_str(BiomeType biome) { break; case SNOWY_PLAIN: str = "Snowy Plain"; + break; + case OCEAN: + str = "Ocean"; + break; case NONE: str = "Unknown"; break; @@ -190,6 +194,9 @@ BiomeType determine_biome(const BiomeConditions& conditions) { if (conditions.mountainous > 0.75) { return MOUNTAIN; } + if (conditions.mountainous < 0.25) { + return OCEAN; + } auto temp = conditions.temp; auto humid = conditions.humid; if (temp < 0.5) { diff --git a/src/gameplay/builders/biome_builder.cpp b/src/gameplay/builders/biome_builder.cpp index f0f83d6..9c7b901 100644 --- a/src/gameplay/builders/biome_builder.cpp +++ b/src/gameplay/builders/biome_builder.cpp @@ -39,4 +39,23 @@ void BiomeBuilder::place_grass() { } } } + +void BiomeBuilder::ocean_water_build() { + ChunkGenerator& chunk_generator = get_chunk_generator(); + Chunk& chunk = chunk_generator.chunk(); + auto& blocks = chunk.blocks(); + const auto& heightmap = chunk.get_heightmap(); + + for (int x = 0; x < SIZE_X; ++x) { + for (int z = 0; z < SIZE_Z; ++z) { + int height = heightmap[x][z]; + if (height <= SEA_LEVEL) { + for (int y = height; y <= SEA_LEVEL; y++) { + blocks[Chunk::index(x, y, z)] = 7; + } + } + } + } +} + } // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/builders/desert_builder.cpp b/src/gameplay/builders/desert_builder.cpp index 2b60cfa..b05fde5 100644 --- a/src/gameplay/builders/desert_builder.cpp +++ b/src/gameplay/builders/desert_builder.cpp @@ -27,6 +27,7 @@ void DesertBuilder::build_blocks() { } } } + ocean_water_build(); } void DesertBuilder::build_vegetation() {} diff --git a/src/gameplay/builders/forest_builder.cpp b/src/gameplay/builders/forest_builder.cpp index 8607b02..92656c0 100644 --- a/src/gameplay/builders/forest_builder.cpp +++ b/src/gameplay/builders/forest_builder.cpp @@ -32,6 +32,7 @@ void ForestBuilder::build_blocks() { m_blocks[Chunk::index(x, height, z)] = 1; } } + ocean_water_build(); } void ForestBuilder::build_vegetation() { diff --git a/src/gameplay/builders/mountain_builder.cpp b/src/gameplay/builders/mountain_builder.cpp index 0c8c379..1cb873a 100644 --- a/src/gameplay/builders/mountain_builder.cpp +++ b/src/gameplay/builders/mountain_builder.cpp @@ -23,6 +23,7 @@ void MountainBuilder::build_blocks() { } } } + ocean_water_build(); } void MountainBuilder::build_vegetation() {} diff --git a/src/gameplay/builders/ocean_builder.cpp b/src/gameplay/builders/ocean_builder.cpp new file mode 100644 index 0000000..cf95d9d --- /dev/null +++ b/src/gameplay/builders/ocean_builder.cpp @@ -0,0 +1,35 @@ +#include "Cubed/gameplay/builders/ocean_builder.hpp" + +#include "Cubed/gameplay/chunk.hpp" +#include "Cubed/gameplay/chunk_generator.hpp" +namespace Cubed { +OceanBuilder::OceanBuilder(ChunkGenerator& chunk_generator) + : m_chunk_generator(chunk_generator) {} + +void OceanBuilder::build_biome() { + BiomeBuilder::build_bottom(); + build_blocks(); +}; + +void OceanBuilder::build_blocks() { + auto& m_chunk = m_chunk_generator.chunk(); + auto& m_blocks = m_chunk.blocks(); + auto& m_heightmap = m_chunk.heightmap(); + for (int x = 0; x < CHUNK_SIZE; x++) { + for (int z = 0; z < CHUNK_SIZE; z++) { + int height = static_cast(m_heightmap[x][z]); + for (int y = 5; y <= height; y++) { + m_blocks[Chunk::index(x, y, z)] = 3; + } + } + } + ocean_water_build(); +} + +void OceanBuilder::build_vegetation() {} + +ChunkGenerator& OceanBuilder::get_chunk_generator() { + return m_chunk_generator; +}; + +} // namespace Cubed \ No newline at end of file diff --git a/src/gameplay/builders/plain_builder.cpp b/src/gameplay/builders/plain_builder.cpp index a900905..65ec47b 100644 --- a/src/gameplay/builders/plain_builder.cpp +++ b/src/gameplay/builders/plain_builder.cpp @@ -27,6 +27,7 @@ void PlainBuilder::build_blocks() { m_blocks[Chunk::index(x, height, z)] = 1; } } + ocean_water_build(); } void PlainBuilder::build_vegetation() { place_grass(); } diff --git a/src/gameplay/builders/snowy_plain_builder.cpp b/src/gameplay/builders/snowy_plain_builder.cpp index 189ce46..0e765c3 100644 --- a/src/gameplay/builders/snowy_plain_builder.cpp +++ b/src/gameplay/builders/snowy_plain_builder.cpp @@ -27,6 +27,7 @@ void SnowyPlainBuilder::build_blocks() { m_blocks[Chunk::index(x, height, z)] = 8; } } + ocean_water_build(); } void SnowyPlainBuilder::build_vegetation() {} diff --git a/src/gameplay/chunk.cpp b/src/gameplay/chunk.cpp index 430fd85..341bd49 100644 --- a/src/gameplay/chunk.cpp +++ b/src/gameplay/chunk.cpp @@ -199,7 +199,7 @@ void Chunk::gen_phase_six( Logger::error("ChunkGenerator is Nullptr"); return; } - m_generator->blend_surface_blocks_borders(neighbor_block); + // m_generator->blend_surface_blocks_borders(neighbor_block); m_generator->generate_cave(); m_generator->generate_river(); } diff --git a/src/gameplay/chunk_generator.cpp b/src/gameplay/chunk_generator.cpp index ddb7547..0fb9b0b 100644 --- a/src/gameplay/chunk_generator.cpp +++ b/src/gameplay/chunk_generator.cpp @@ -3,6 +3,7 @@ #include "Cubed/gameplay/builders/desert_builder.hpp" #include "Cubed/gameplay/builders/forest_builder.hpp" #include "Cubed/gameplay/builders/mountain_builder.hpp" +#include "Cubed/gameplay/builders/ocean_builder.hpp" #include "Cubed/gameplay/builders/plain_builder.hpp" #include "Cubed/gameplay/builders/river_builder.hpp" #include "Cubed/gameplay/builders/snowy_plain_builder.hpp" @@ -166,18 +167,43 @@ void ChunkGenerator::generate_heightmap() { amplitude = std::lerp(10, 40, t); */ float t; - if (mountainous >= 0.7f) { - t = Math::smootherstep(0.7f, 0.75, mountainous); - base_y = std::lerp(70, 88, t); - amplitude = std::lerp(28, 48, t); - } else if (mountainous >= 0.65f) { - t = Math::smootherstep(0.65f, 0.7f, mountainous); - base_y = std::lerp(66, 70, t); + if (mountainous >= 0.95f) { + t = Math::smootherstep(0.95f, 1.0f, mountainous); + base_y = std::lerp(130, 140, t); + amplitude = std::lerp(38, 48, t); + } else if (mountainous >= 0.85f) { + t = Math::smootherstep(0.85f, 0.95f, mountainous); + base_y = std::lerp(100, 130, t); + amplitude = std::lerp(28, 38, t); + } else if (mountainous >= 0.8) { + t = Math::smootherstep(0.8f, 0.85f, mountainous); + base_y = std::lerp(85, 100, t); amplitude = std::lerp(18, 28, t); + } else if (mountainous >= 0.75f) { + t = Math::smootherstep(0.75f, 0.8f, mountainous); + base_y = std::lerp(70, 85, t); + amplitude = std::lerp(6, 18, t); + } else if (mountainous >= 0.7) { + t = Math::smootherstep(0.7f, 0.75f, mountainous); + base_y = std::lerp(66, 70, t); + amplitude = std::lerp(6, 6, t); + + } else if (mountainous >= 0.45f) { + t = Math::smootherstep(0.45f, 0.7f, mountainous); + base_y = std::lerp(64, 66, t); + amplitude = std::lerp(6, 6, t); + } else if (mountainous >= 0.3f) { + t = Math::smootherstep(0.3f, 0.45f, mountainous); + base_y = std::lerp(60, 64, t); + amplitude = std::lerp(6, 6, t); + } else if (mountainous >= 0.25f) { + t = Math::smootherstep(0.25f, 0.3f, mountainous); + base_y = std::lerp(44, 60, t); + amplitude = std::lerp(6, 6, t); } else { - t = Math::smootherstep(0.55, 0.65, mountainous); - base_y = std::lerp(58, 66, t); - amplitude = std::lerp(8, 18, t); + t = Math::smootherstep(0.0f, 0.25f, mountainous); + base_y = std::lerp(35, 44, t); + amplitude = std::lerp(3, 6, t); } heightmap[x][z] = base_y + fbm_height(world_x, world_z, octaves, lacunarity, gain, @@ -553,10 +579,10 @@ void ChunkGenerator::blend_surface_blocks_borders( // bottom block unsigned fill_type = 2; - if (final_type == 1) { + if (final_type == 1 || final_type == 8) { fill_type = 2; - } else if (final_type == 4) { - fill_type = 4; + } else { + fill_type = final_type; } for (int y = top_y - 5; y < top_y; y++) { if (fill_type == 7 && y > SEA_LEVEL) { @@ -600,6 +626,9 @@ void ChunkGenerator::make_biome_builder() { case SNOWY_PLAIN: m_biome_builder = std::make_unique(*this); break; + case OCEAN: + m_biome_builder = std::make_unique(*this); + break; case NONE: m_biome_builder = nullptr; break; @@ -617,9 +646,14 @@ void ChunkGenerator::generate_cave() { const int CHUNK_MAX_Z = CHUNK_MIN_Z + SIZE_Z - 1; const int CHUNK_MIN_Y = 0; const int CHUNK_MAX_Y = SIZE_Y - 1; + for (auto& [id, path] : paths) { for (const auto& point : path.points()) { - + if ((m_chunk.biome() == BiomeType::RIVER) || + (m_chunk.biome() == BiomeType::OCEAN)) { + path.clear_chunk(chunk_pos); + continue; + } const glm::vec3& center = point.pos; float rad_xz = point.rad_xz; float rad_y = point.rad_y; @@ -651,6 +685,9 @@ void ChunkGenerator::generate_cave() { if (y == 0) { continue; } + if (blocks[Chunk::index(x, y, z)] == 7) { + continue; + } blocks[Chunk::index(x, y, z)] = 0; } } @@ -678,7 +715,8 @@ void ChunkGenerator::generate_river() { for (auto& [id, path] : paths) { for (const auto& point : path.points()) { - if (m_chunk.biome() == BiomeType::DESERT) { + if ((m_chunk.biome() == BiomeType::DESERT) || + (m_chunk.biome() == BiomeType::OCEAN)) { path.clear_chunk(chunk_pos); continue; }